Skip to content
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

feat: deprecate old API and create new API for dashes created by me #19434

Merged
merged 17 commits into from
Apr 8, 2022
Merged
Next Next commit
feat: deprecate old API and create new API for dashes created by me
  • Loading branch information
dpgaspar committed Mar 30, 2022
commit 468463ccacc0e2042c151cd3ddd69696d3b5e863
48 changes: 39 additions & 9 deletions superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from zipfile import is_zipfile, ZipFile

from flask import g, make_response, redirect, request, Response, send_file, url_for
from flask_appbuilder.api import expose, protect, rison, safe
from flask_appbuilder.api import expose, permission_name, protect, rison, safe
from flask_appbuilder.hooks import before_request
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_babel import ngettext
Expand Down Expand Up @@ -61,6 +61,7 @@
FilterRelatedRoles,
)
from superset.dashboards.schemas import (
DashboardCreatedByMeResponseSchema,
DashboardDatasetSchema,
DashboardGetResponseSchema,
DashboardPostSchema,
Expand Down Expand Up @@ -212,6 +213,7 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]:
""" Override the name set for this collection of endpoints """
openapi_spec_component_schemas = (
ChartEntityResponseSchema,
DashboardCreatedByMeResponseSchema,
DashboardGetResponseSchema,
DashboardDatasetSchema,
GetFavStarIdsSchema,
Expand Down Expand Up @@ -272,8 +274,6 @@ def get(self, id_or_slug: str) -> Response:
properties:
result:
$ref: '#/components/schemas/DashboardGetResponseSchema'
302:
description: Redirects to the current digest
400:
$ref: '#/components/responses/400'
401:
Expand Down Expand Up @@ -336,8 +336,6 @@ def get_datasets(self, id_or_slug: str) -> Response:
type: array
items:
$ref: '#/components/schemas/DashboardDatasetSchema'
302:
description: Redirects to the current digest
400:
$ref: '#/components/responses/400'
401:
Expand Down Expand Up @@ -399,8 +397,6 @@ def get_charts(self, id_or_slug: str) -> Response:
type: array
items:
$ref: '#/components/schemas/ChartEntityResponseSchema'
302:
description: Redirects to the current digest
400:
$ref: '#/components/responses/400'
401:
Expand All @@ -427,6 +423,42 @@ def get_charts(self, id_or_slug: str) -> Response:
except DashboardNotFoundError:
return self.response_404()

@expose("/created_by_me/", 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, # pylint: disable=arguments-renamed
)
@permission_name("can_read")
def created_by_me(self, id_or_slug: str) -> Response:
"""Gets all dashboards created by the current user
---
get:
description: >-
Gets all dashboards created by the current user
responses:
200:
description: Dashboard
content:
application/json:
schema:
type: object
properties:
result:
$ref: '#/components/schemas/DashboardCreatedByMeResponseSchema'
401:
$ref: '#/components/responses/401'
403:
$ref: '#/components/responses/403'
404:
$ref: '#/components/responses/404'
"""
dashboards = DashboardDAO.get_dashboards_created_changed_by_user(g.user.id)
result = self.dashboard_get_response_schema.dump(dashboards)
return self.response(200, result=result)

@expose("/", methods=["POST"])
@protect()
@safe
Expand Down Expand Up @@ -461,8 +493,6 @@ def post(self) -> Response:
type: number
result:
$ref: '#/components/schemas/{{self.__class__.__name__}}.post'
302:
description: Redirects to the current digest
400:
$ref: '#/components/responses/400'
401:
Expand Down
20 changes: 20 additions & 0 deletions superset/dashboards/dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from datetime import datetime
from typing import Any, Dict, List, Optional, Union

from sqlalchemy import or_
from sqlalchemy.exc import SQLAlchemyError

from superset import security_manager
Expand Down Expand Up @@ -100,6 +101,25 @@ def get_dashboard_and_slices_changed_on( # pylint: disable=invalid-name
# drop microseconds in datetime to match with last_modified header
return max(dashboard_changed_on, slices_changed_on).replace(microsecond=0)

@staticmethod
def get_dashboards_created_changed_by_user(user_id: int) -> List[Dashboard]:
"""
Gets a list of dashboards that were created or changed by a certain user
:param user_id: The user id
:return: List of dashboards
"""
qry = (
db.session.query(Dashboard)
.filter( # pylint: disable=comparison-with-callable
or_(
Dashboard.created_by_fk == user_id,
Dashboard.changed_by_fk == user_id,
)
)
.order_by(Dashboard.changed_on.desc())
)
return qry.all()

@staticmethod
def get_dashboard_and_datasets_changed_on( # pylint: disable=invalid-name
id_or_slug_or_dashboard: Union[str, Dashboard]
Expand Down
8 changes: 8 additions & 0 deletions superset/dashboards/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,14 @@ def post_load(self, data: Dict[str, Any], **kwargs: Any) -> Dict[str, Any]:
return data


class DashboardCreatedByMeResponseSchema(Schema):
id = fields.Int()
dashboard = fields.Str()
title = fields.Str()
url = fields.Str()
dttm = fields.DateTime()


class DashboardPostSchema(BaseDashboardSchema):
dashboard_title = fields.String(
description=dashboard_title_description,
Expand Down
16 changes: 12 additions & 4 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1586,16 +1586,24 @@ def fave_dashboards(self, user_id: int) -> FlaskResponse:
@event_logger.log_this
@expose("/created_dashboards/<int:user_id>/", methods=["GET"])
def created_dashboards(self, user_id: int) -> FlaskResponse:
logging.warning(
"%s.select_star "
"This API endpoint is deprecated and will be removed in version 3.0.0",
self.__class__.__name__,
)

error_obj = self.get_user_activity_access_error(user_id)
if error_obj:
return error_obj
Dash = Dashboard
qry = (
db.session.query(Dash)
db.session.query(Dashboard)
.filter( # pylint: disable=comparison-with-callable
or_(Dash.created_by_fk == user_id, Dash.changed_by_fk == user_id)
or_(
Dashboard.created_by_fk == user_id,
Dashboard.changed_by_fk == user_id,
)
)
.order_by(Dash.changed_on.desc())
.order_by(Dashboard.changed_on.desc())
)
payload = [
{
Expand Down