Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
fisjac committed Jan 8, 2025
1 parent bd9a103 commit f05f59a
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 14 deletions.
6 changes: 2 additions & 4 deletions superset/charts/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ def screenshot(self, pk: int, digest: str) -> WerkzeugResponse:
name: digest
responses:
200:
description: Chart thumbnail image
description: Chart screenshot image
content:
image/*:
schema:
Expand All @@ -677,19 +677,16 @@ def screenshot(self, pk: int, digest: str) -> WerkzeugResponse:
"""
chart = self.datamodel.get(pk, self._base_filters)

# Making sure the chart still exists
if not chart:
return self.response_404()

# fetch the chart screenshot using the current user and cache if set
if cache_payload := ChartScreenshot.get_from_cache_key(digest):
if cache_payload.status == StatusValues.UPDATED:
return Response(
FileWrapper(cache_payload.get_image()),
mimetype="image/png",
direct_passthrough=True,
)
# TODO: return an empty image
return self.response_404()

@expose("/<pk>/thumbnail/<digest>/", methods=("GET",))
Expand Down Expand Up @@ -766,6 +763,7 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse:
updated_at=cache_payload.get_timestamp(),
update_status=cache_payload.get_status(),
)
# TODO remove digest from params... currently does nothing
if chart.digest != digest:
self.incr_stats("redirect", self.thumbnail.__name__)
return redirect(
Expand Down
15 changes: 15 additions & 0 deletions superset/charts/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,21 @@ class ChartCacheScreenshotResponseSchema(Schema):
image_url = fields.String(
metadata={"description": "The url to fetch the screenshot"}
)
update_status = fields.String(
metadata={"description": "The status of the async screenshot"}
)
updated_at = fields.String(
metadata={"description": "The timestamp of the last change in status"}
)


class ChartGetCachedScreenshotResponseSchema(Schema):
update_status = fields.String(
metadata={"description": "The status of the async screenshot"}
)
updated_at = fields.String(
metadata={"description": "The timestamp of the last change in status"}
)


class ChartDataColumnSchema(Schema):
Expand Down
20 changes: 12 additions & 8 deletions superset/dashboards/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,14 +942,11 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse:
screenshot_obj = DashboardScreenshot(dashboard_url, digest)
cache_key = screenshot_obj.get_cache_key()
cache_payload = screenshot_obj.get_from_cache_key(cache_key)
if not cache_payload:
if not cache_payload or kwargs["rison"].get("force", False):
cache_payload = ScreenshotCachePayload()
screenshot_obj.cache.set(cache_key, cache_payload)

if (
kwargs["rison"].get("force", False)
or cache_payload.status != StatusValues.UPDATED
):
if cache_payload.status != StatusValues.UPDATED:
cache_dashboard_thumbnail.delay(
current_user=current_user,
dashboard_id=dashboard.id,
Expand Down Expand Up @@ -986,7 +983,9 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse:
f".cache_dashboard_screenshot",
log_to_statsd=False,
)
def cache_dashboard_screenshot(self, pk: int, **kwargs: Any) -> WerkzeugResponse:
def cache_dashboard_screenshot(
self, pk: int, force: bool, **kwargs: Any
) -> WerkzeugResponse:
"""Compute and cache a screenshot.
---
post:
Expand Down Expand Up @@ -1021,7 +1020,6 @@ def cache_dashboard_screenshot(self, pk: int, **kwargs: Any) -> WerkzeugResponse
payload = CacheScreenshotSchema().load(request.json)
except ValidationError as error:
return self.response_400(message=error.messages)

dashboard = cast(Dashboard, self.datamodel.get(pk, self._base_filters))
if not dashboard:
return self.response_404()
Expand Down Expand Up @@ -1052,6 +1050,11 @@ def cache_dashboard_screenshot(self, pk: int, **kwargs: Any) -> WerkzeugResponse
image_url = get_url_path(
"DashboardRestApi.screenshot", pk=dashboard.id, digest=cache_key
)
force = kwargs["rison"].get("force", False)
cache_payload = screenshot_obj.get_from_cache_key(cache_key)
if force or cache_payload is None:
cache_payload = ScreenshotCachePayload()
screenshot_obj.cache.set(cache_key, cache_payload)

def trigger_celery() -> WerkzeugResponse:
logger.info("Triggering screenshot ASYNC")
Expand All @@ -1064,7 +1067,6 @@ def trigger_celery() -> WerkzeugResponse:
),
dashboard_id=dashboard.id,
dashboard_url=dashboard_url,
force=False,
thumb_size=thumb_size,
window_size=window_size,
cache_key=cache_key,
Expand All @@ -1074,6 +1076,8 @@ def trigger_celery() -> WerkzeugResponse:
cache_key=cache_key,
dashboard_url=dashboard_url,
image_url=image_url,
updated_at=cache_payload.get_timestamp(),
update_status=cache_payload.get_status(),
)

return trigger_celery()
Expand Down
6 changes: 6 additions & 0 deletions superset/dashboards/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ class DashboardCacheScreenshotResponseSchema(Schema):
image_url = fields.String(
metadata={"description": "The url to fetch the screenshot"}
)
update_status = fields.String(
metadata={"description": "The status of the async screenshot"}
)
updated_at = fields.String(
metadata={"description": "The timestamp of the last change in status"}
)


class CacheScreenshotSchema(Schema):
Expand Down
1 change: 0 additions & 1 deletion superset/models/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,6 @@ def update_thumbnail(self) -> None:
cache_dashboard_thumbnail.delay(
current_user=get_current_user(),
dashboard_id=self.id,
force=True,
)

@classmethod
Expand Down
1 change: 0 additions & 1 deletion tests/integration_tests/cli_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,5 @@ def test_compute_thumbnails(thumbnail_mock, app_context, fs):
thumbnail_mock.assert_called_with(
None,
dashboard.id,
force=False,
)
assert response.exit_code == 0

0 comments on commit f05f59a

Please sign in to comment.