Addresses @EnxDev's review on #41133:
- Soft timeouts now abort the export instead of being caught per chart: the
per-chart SoftTimeLimitExceeded handler (and screenshot.py's broad except)
re-raise, so the outer handler emails a failure and runs cleanup rather than
running to the hard limit (leaking temp files, holding the lock). Removes the
now-dead ERROR_TIMEOUT reason.
- Concurrency guard uses a shared, atomic DistributedLock (Redis when
configured, metadata DB otherwise) instead of cache_manager.cache, which is a
no-op under the default NullCache and process-local under SimpleCache. The
lock is released if apply_async fails so a broker outage can't block exports
until the TTL expires.
- boto3 is declared via a new `excel-export` optional extra; superset.utils.s3
raises an actionable install hint when it is missing.
- "Export Images to Excel" is gated on the webdriver screenshot feature flags
(it renders via the headless webdriver); documents EXCEL_EXPORT_TABLE_VIZ_TYPES
and the image mode in the config docs and UPDATING.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolves betodealmeida's review comments on PR #41133:
- i18n: wrap all user-facing email strings in gettext with named
placeholders (build_subject / errored section / success + failure bodies).
- Human-readable link expiry via a pluralized, translatable helper, fixing
the sub-hour "0 hours" underreporting.
- Group charts that could not be exported by reason
(no-query-context / timeout / general-exception) instead of a flat
"skipped" list; render one labelled section per reason in the email.
- Replace deprecated datetime.utcnow() with datetime.now(tz=timezone.utc).
- Throttle concurrent exports per user+dashboard via a cache lock: return
202 "already in progress" if one is in flight, clear the lock in the
task's finally block (TTL is the backstop).
- Tests: switch the export API tests to the @with_config decorator; add
unit coverage for grouped errors and the throttle-lock cleanup.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add the async task that exports a dashboard's chart data to a multi-sheet xlsx.
Running as the requesting user, it walks charts in layout order, re-runs each
saved query context with the live filter state applied, streams results into a
constant-memory workbook, uploads to S3, and emails a pre-signed link. Charts
with no/invalid query context or a failing query are skipped and listed in the
email; all-skipped dashboards get a summary sheet. On failure (incl. soft
timeout) it emails the user and always cleans up the temp file. Registers the
task in CeleryConfig.imports. Adds unit tests for happy path, skips, summary,
upload failure, and timeout.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>