-
Notifications
You must be signed in to change notification settings - Fork 16.5k
fix(dashboard): Get dashboard by slug #13352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8ab7a38
9b44b92
4c9a2cf
cf76b2c
979fd48
3a7312d
0fdfd32
b9d92ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,7 @@ | |
| FilterRelatedRoles, | ||
| ) | ||
| from superset.dashboards.schemas import ( | ||
| DashboardGetResponseSchema, | ||
| DashboardPostSchema, | ||
| DashboardPutSchema, | ||
| get_delete_ids_schema, | ||
|
|
@@ -99,29 +100,6 @@ class DashboardRestApi(BaseSupersetModelRestApi): | |
| class_permission_name = "Dashboard" | ||
| method_permission_name = MODEL_API_RW_METHOD_PERMISSION_MAP | ||
|
|
||
| show_columns = [ | ||
| "id", | ||
| "charts", | ||
| "css", | ||
| "dashboard_title", | ||
| "json_metadata", | ||
| "owners.id", | ||
| "owners.username", | ||
| "owners.first_name", | ||
| "owners.last_name", | ||
| "roles.id", | ||
| "roles.name", | ||
| "changed_by_name", | ||
| "changed_by_url", | ||
| "changed_by.username", | ||
| "changed_on", | ||
| "position_json", | ||
| "published", | ||
| "url", | ||
| "slug", | ||
| "table_names", | ||
| "thumbnail_url", | ||
| ] | ||
| list_columns = [ | ||
| "id", | ||
| "published", | ||
|
|
@@ -190,6 +168,7 @@ class DashboardRestApi(BaseSupersetModelRestApi): | |
| add_model_schema = DashboardPostSchema() | ||
| edit_model_schema = DashboardPutSchema() | ||
| chart_entity_response_schema = ChartEntityResponseSchema() | ||
| dashboard_get_response_schema = DashboardGetResponseSchema() | ||
|
|
||
| base_filters = [["slice", DashboardFilter, lambda: []]] | ||
|
|
||
|
|
@@ -207,7 +186,11 @@ class DashboardRestApi(BaseSupersetModelRestApi): | |
|
|
||
| openapi_spec_tag = "Dashboards" | ||
| """ Override the name set for this collection of endpoints """ | ||
| openapi_spec_component_schemas = (ChartEntityResponseSchema, GetFavStarIdsSchema) | ||
| openapi_spec_component_schemas = ( | ||
| ChartEntityResponseSchema, | ||
| DashboardGetResponseSchema, | ||
| GetFavStarIdsSchema, | ||
| ) | ||
| apispec_parameter_schemas = { | ||
| "get_delete_ids_schema": get_delete_ids_schema, | ||
| "get_export_ids_schema": get_export_ids_schema, | ||
|
|
@@ -222,6 +205,53 @@ def __init__(self) -> None: | |
| self.include_route_methods = self.include_route_methods | {"thumbnail"} | ||
| super().__init__() | ||
|
|
||
| @expose("/<id_or_slug>", methods=["GET"]) | ||
| @protect() | ||
| @safe | ||
| @statsd_metrics | ||
| @event_logger.log_this_with_context( | ||
| action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.get", | ||
| log_to_statsd=False, | ||
| ) | ||
| def get(self, id_or_slug: str) -> Response: | ||
| """Gets a dashboard | ||
| --- | ||
| get: | ||
| description: >- | ||
| Get a dashboard | ||
| parameters: | ||
| - in: path | ||
| schema: | ||
| type: string | ||
| name: id_or_slug | ||
| description: Either the id of the dashboard, or its slug | ||
| responses: | ||
| 200: | ||
| description: Dashboard | ||
| content: | ||
| application/json: | ||
| schema: | ||
| type: object | ||
| properties: | ||
| result: | ||
| $ref: '#/components/schemas/DashboardGetResponseSchema' | ||
| 302: | ||
| description: Redirects to the current digest | ||
| 400: | ||
| $ref: '#/components/responses/400' | ||
| 401: | ||
| $ref: '#/components/responses/401' | ||
| 404: | ||
| $ref: '#/components/responses/404' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can return 500 also from the |
||
| """ | ||
| # pylint: disable=arguments-differ | ||
| try: | ||
| dash = DashboardDAO.get_by_id_or_slug(id_or_slug) | ||
| result = self.dashboard_get_response_schema.dump(dash) | ||
| return self.response(200, result=result) | ||
| except DashboardNotFoundError: | ||
| return self.response_404() | ||
|
|
||
| @expose("/<pk>/charts", methods=["GET"]) | ||
| @protect() | ||
| @safe | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,7 +27,7 @@ | |
| from superset.dashboards.filters import DashboardFilter | ||
| from superset.extensions import db | ||
| from superset.models.core import FavStar, FavStarClassName | ||
| from superset.models.dashboard import Dashboard | ||
| from superset.models.dashboard import Dashboard, id_or_slug_filter | ||
| from superset.models.slice import Slice | ||
| from superset.utils.dashboard_filter_scopes_converter import copy_filter_scopes | ||
|
|
||
|
|
@@ -38,6 +38,25 @@ class DashboardDAO(BaseDAO): | |
| model_cls = Dashboard | ||
| base_filter = DashboardFilter | ||
|
|
||
| @staticmethod | ||
| def get_by_id_or_slug(id_or_slug: str) -> Dashboard: | ||
| query = ( | ||
| db.session.query(Dashboard) | ||
| .filter(id_or_slug_filter(id_or_slug)) | ||
| .outerjoin(Slice, Dashboard.slices) | ||
| .outerjoin(Slice.table) | ||
| .outerjoin(Dashboard.owners) | ||
| .outerjoin(Dashboard.roles) | ||
| ) | ||
| # Apply dashboard base filters | ||
| query = DashboardFilter("id", SQLAInterface(Dashboard, db.session)).apply( | ||
| query, None | ||
| ) | ||
| dashboard = query.one_or_none() | ||
| if not dashboard: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this |
||
| raise DashboardNotFoundError() | ||
| return dashboard | ||
|
|
||
| @staticmethod | ||
| def get_charts_for_dashboard(dashboard_id: int) -> List[Slice]: | ||
| query = ( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,6 +42,7 @@ | |
| from sqlalchemy.orm.mapper import Mapper | ||
| from sqlalchemy.orm.session import object_session | ||
| from sqlalchemy.sql import join, select | ||
| from sqlalchemy.sql.elements import BinaryExpression | ||
|
|
||
| from superset import app, ConnectorRegistry, db, is_feature_enabled, security_manager | ||
| from superset.connectors.base.models import BaseDatasource | ||
|
|
@@ -57,6 +58,8 @@ | |
| from superset.utils.decorators import debounce | ||
| from superset.utils.urls import get_url_path | ||
|
|
||
| # pylint: disable=too-many-public-methods | ||
|
|
||
| metadata = Model.metadata # pylint: disable=no-member | ||
| config = app.config | ||
| logger = logging.getLogger(__name__) | ||
|
|
@@ -361,15 +364,16 @@ def export_dashboards( # pylint: disable=too-many-locals | |
| @classmethod | ||
| def get(cls, id_or_slug: str) -> Dashboard: | ||
| session = db.session() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated, but seems strange that this is creating a new session here
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does. I didn't feel entirely comfortable removing it though. Not sure why it was put there. |
||
| qry = session.query(Dashboard) | ||
| if id_or_slug.isdigit(): | ||
| qry = qry.filter_by(id=int(id_or_slug)) | ||
| else: | ||
| qry = qry.filter_by(slug=id_or_slug) | ||
|
|
||
| qry = session.query(Dashboard).filter(id_or_slug_filter(id_or_slug)) | ||
| return qry.one_or_none() | ||
|
|
||
|
|
||
| def id_or_slug_filter(id_or_slug: str) -> BinaryExpression: | ||
suddjian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if id_or_slug.isdigit(): | ||
| return Dashboard.id == int(id_or_slug) | ||
| return Dashboard.slug == id_or_slug | ||
|
|
||
|
|
||
| OnDashboardChange = Callable[[Mapper, Connection, Dashboard], Any] | ||
|
|
||
| # events for updating tags | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.