This is an automated email from the ASF dual-hosted git repository. suddjian pushed a commit to branch get-dashboard-by-slug in repository https://gitbox.apache.org/repos/asf/superset.git
commit 9b44b9262aace719eae18b32ffe228fe94eba5c0 Author: David Aaron Suddjian <[email protected]> AuthorDate: Thu Feb 25 15:58:57 2021 -0800 fix(dashboard): accept slug in place of id in url --- superset/dashboards/api.py | 53 +++++++++++++++++++++++++++++++++++++++++- superset/dashboards/dao.py | 18 ++++++++++++-- superset/dashboards/schemas.py | 43 +++++++++++++++++++++++++++++++++- 3 files changed, 110 insertions(+), 4 deletions(-) diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index 7678711..f0e1f8b 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -60,6 +60,7 @@ from superset.dashboards.filters import ( from superset.dashboards.schemas import ( DashboardPostSchema, DashboardPutSchema, + DashboardResponseSchema, get_delete_ids_schema, get_export_ids_schema, get_fav_star_ids_schema, @@ -190,6 +191,7 @@ class DashboardRestApi(BaseSupersetModelRestApi): add_model_schema = DashboardPostSchema() edit_model_schema = DashboardPutSchema() chart_entity_response_schema = ChartEntityResponseSchema() + dashboard_response_schema = DashboardResponseSchema() base_filters = [["slice", DashboardFilter, lambda: []]] @@ -207,7 +209,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, + DashboardResponseSchema, + GetFavStarIdsSchema, + ) apispec_parameter_schemas = { "get_delete_ids_schema": get_delete_ids_schema, "get_export_ids_schema": get_export_ids_schema, @@ -222,6 +228,51 @@ class DashboardRestApi(BaseSupersetModelRestApi): 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 + responses: + 200: + description: Dashboard + content: + application/json: + schema: + type: object + properties: + result: + $ref: '#/components/schemas/DashboardResponseSchema' + 302: + description: Redirects to the current digest + 400: + $ref: '#/components/responses/400' + 401: + $ref: '#/components/responses/401' + 404: + $ref: '#/components/responses/404' + """ + try: + dash = Dashboard.get(id_or_slug) + result = self.dashboard_response_schema.dump(dash) + return self.response(200, result=result) + except DashboardNotFoundError: + return self.response_404() + @expose("/<pk>/charts", methods=["GET"]) @protect() @safe diff --git a/superset/dashboards/dao.py b/superset/dashboards/dao.py index 142331e..3e5b35b 100644 --- a/superset/dashboards/dao.py +++ b/superset/dashboards/dao.py @@ -25,9 +25,9 @@ from sqlalchemy.orm import contains_eager from superset.dao.base import BaseDAO from superset.dashboards.commands.exceptions import DashboardNotFoundError from superset.dashboards.filters import DashboardFilter -from superset.extensions import db +from superset.extensions import db, security_manager from superset.models.core import FavStar, FavStarClassName -from superset.models.dashboard import Dashboard +from superset.models.dashboard import Dashboard, dashboard_user from superset.models.slice import Slice from superset.utils.dashboard_filter_scopes_converter import copy_filter_scopes @@ -39,6 +39,20 @@ class DashboardDAO(BaseDAO): base_filter = DashboardFilter @staticmethod + def get_dashboard(id_or_slug: str) -> Dashboard: + query = db.session.query(Dashboard).filter( + Dashboard.id_or_slug_filter(id_or_slug) + ) + # Apply dashboard base filters + query = DashboardFilter("id", SQLAInterface(Dashboard, db.session)).apply( + query, None + ) + dashboard = query.one_or_none() + if not dashboard: + raise DashboardNotFoundError() + return dashboard + + @staticmethod def get_charts_for_dashboard(dashboard_id: int) -> List[Slice]: query = ( db.session.query(Dashboard) diff --git a/superset/dashboards/schemas.py b/superset/dashboards/schemas.py index 360f94f..46ce37b 100644 --- a/superset/dashboards/schemas.py +++ b/superset/dashboards/schemas.py @@ -61,7 +61,9 @@ published_description = ( "Determines whether or not this dashboard is visible in " "the list of all dashboards." ) - +charts_description = ( + "The names of the dashboard's charts. Names are used for legacy reasons." +) openapi_spec_methods_override = { "get": {"get": {"description": "Get a dashboard detail information."}}, @@ -121,6 +123,45 @@ class DashboardJSONMetadataSchema(Schema): label_colors = fields.Dict() +class UserSchema(Schema): + id = fields.Int() + username = fields.String() + first_name = fields.String() + last_name = fields.String() + + +class RolesSchema(Schema): + id = fields.Int() + name = fields.String() + + +class DatasourceSchema(Schema): + id = fields.Int() + name = fields.String() + description = fields.String() + + +class DashboardResponseSchema(Schema): + id = fields.Int() + slug = fields.String() + url = fields.String() + dashboard_title = fields.String(description=dashboard_title_description) + thumbnail_url = fields.String() + published = fields.Boolean() + css = fields.String(description=css_description) + json_metadata = fields.String(description=json_metadata_description) + position_json = fields.String(description=position_json_description) + changed_by_name = fields.String() + changed_by_url = fields.String() + changed_by = fields.Nested(UserSchema) + changed_on = fields.DateTime() + charts = fields.List(fields.String(description=charts_description)) + owners = fields.List(fields.Nested(UserSchema)) + roles = fields.List(fields.Nested(RolesSchema)) + datasources = fields.List(fields.Nested(DatasourceSchema)) + table_names = fields.String() # legacy nonsense + + class BaseDashboardSchema(Schema): # pylint: disable=no-self-use,unused-argument @post_load
