You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2025/09/04 19:51:18 UTC
(superset) 01/03: WIP
This is an automated email from the ASF dual-hosted git repository.
beto pushed a commit to branch sidecar
in repository https://gitbox.apache.org/repos/asf/superset.git
commit df62bffaddcd886d0223f8c7b4b00e8e1dfa050f
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Wed Sep 3 15:53:09 2025 -0400
WIP
---
superset/commands/report/execute.py | 79 +++++++++++++++++++++++++++++++++----
1 file changed, 71 insertions(+), 8 deletions(-)
diff --git a/superset/commands/report/execute.py b/superset/commands/report/execute.py
index 1b19738bab..e79475898d 100644
--- a/superset/commands/report/execute.py
+++ b/superset/commands/report/execute.py
@@ -77,6 +77,7 @@ from superset.utils.core import HeaderDataType, override_user, recipients_string
from superset.utils.csv import get_chart_csv_data, get_chart_dataframe
from superset.utils.decorators import logs_context, transaction
from superset.utils.pdf import build_pdf_from_screenshots
+from superset.utils.query_sidecar import get_query_sidecar_client, QuerySidecarException
from superset.utils.screenshots import ChartScreenshot, DashboardScreenshot
from superset.utils.slack import get_channels_with_search, SlackChannelTypes
from superset.utils.urls import get_url_path
@@ -388,9 +389,7 @@ class BaseReportState:
user = security_manager.find_user(username)
auth_cookies = machine_auth_provider_factory.instance.get_auth_cookies(user)
- if self._report_schedule.chart.query_context is None:
- logger.warning("No query context found, taking a screenshot to generate it")
- self._update_query_context()
+ self._ensure_query_context_available()
try:
logger.info("Getting chart from %s as user %s", url, user.username)
@@ -418,9 +417,7 @@ class BaseReportState:
user = security_manager.find_user(username)
auth_cookies = machine_auth_provider_factory.instance.get_auth_cookies(user)
- if self._report_schedule.chart.query_context is None:
- logger.warning("No query context found, taking a screenshot to generate it")
- self._update_query_context()
+ self._ensure_query_context_available()
try:
logger.info("Getting chart from %s as user %s", url, user.username)
@@ -435,9 +432,75 @@ class BaseReportState:
raise ReportScheduleCsvFailedError()
return dataframe
- def _update_query_context(self) -> None:
+ def _ensure_query_context_available(self) -> None:
+ """
+ Ensure query context is available for the chart.
+
+ First attempts to generate query context using the sidecar service
+ from the chart's form_data. If that fails, falls back to the
+ screenshot method for backward compatibility.
+ """
+ # Try sidecar service first if available
+ if app.config.get("QUERY_SIDECAR_ENABLED", True):
+ try:
+ self._generate_query_context_via_sidecar()
+ return
+ except QuerySidecarException as ex:
+ logger.warning(
+ "Failed to generate query context via sidecar service: %s. "
+ "Falling back to screenshot method.",
+ str(ex)
+ )
+
+ # Fallback to legacy screenshot method
+ if self._report_schedule.chart.query_context is None:
+ logger.warning("No query context found, taking a screenshot to generate it")
+ self._update_query_context_legacy()
+
+ def _generate_query_context_via_sidecar(self) -> None:
+ """
+ Generate and save query context using the sidecar service.
+
+ This method uses the chart's form_data to generate a fresh
+ QueryObject via the sidecar service, eliminating staleness issues.
+ """
+ if not self._report_schedule.chart:
+ raise QuerySidecarException("No chart associated with report schedule")
+
+ try:
+ # Get the chart's form_data
+ form_data = self._report_schedule.chart.form_data
+
+ # Use sidecar service to generate QueryObject
+ sidecar_client = get_query_sidecar_client()
+ query_object_data = sidecar_client.build_query_object(form_data)
+
+ # Convert to JSON and save as query_context
+ query_context = json.dumps({
+ "queries": [query_object_data],
+ "form_data": form_data,
+ "result_format": "json",
+ "result_type": "full",
+ })
+
+ # Update the chart's query_context in the database
+ self._report_schedule.chart.query_context = query_context
+ from superset import db
+ db.session.commit()
+
+ logger.info(
+ "Successfully generated query context via sidecar for chart %s",
+ self._report_schedule.chart.id
+ )
+
+ except Exception as ex:
+ raise QuerySidecarException(
+ f"Failed to generate query context via sidecar: {ex}"
+ ) from ex
+
+ def _update_query_context_legacy(self) -> None:
"""
- Update chart query context.
+ Update chart query context using the legacy screenshot method.
To load CSV data from the endpoint the chart must have been saved
with its query context. For charts without saved query context we