Skip to content

[SIP-238] Extension APIs for exporting chart and dashboard data (Google Sheets export) #46015

Open

Description

@orion222

[SIP] Proposal for extension APIs to export chart and dashboard data

Note: This is an approved feature as a part of the UTSC 2026 Fall batch - Slack Work Item

Status: in progress. The core changes are open as #45991 (backend) and #46014 (frontend). The first extension built on them, chart export to Google Sheets, is in review at orion222/superset-google-sheets. Dashboard export is next.

Motivation

Business users often want the numbers behind a chart or dashboard in a spreadsheet, to annotate, model or share them. Today that takes an Export to .CSV or Excel download followed by a manual upload to Google Drive.

The sqllab-gsheets extension already sends SQL Lab results straight to a new Google Sheet. Bringing the same workflow to charts and dashboards is blocked by two gaps in the extension framework:

  1. Backend: superset_core can run raw SQL (Database.execute, feat: SQL execution API for Superset #36529), but it can't run a chart's query context or walk a dashboard's charts. That logic exists only inside Superset: ChartDataCommand behind /api/v1/chart/data, and the per-chart loop of the dashboard Excel export. Extensions must not import Superset internals.
  2. Frontend:
    • Extensions can contribute menu items only to SQL Lab panels, so they can't add an action to a chart's or dashboard's Download menu.
    • Even if they could, the click would carry no context, so the extension wouldn't know which query or filters to export.
    • Extensions also have no way to show Superset's toasts.

This SIP proposes small, general extension APIs that close both gaps. Nothing in Superset becomes Google-specific; Google Sheets is simply the first consumer.

Proposed Change

Backend: superset_core.exports (#45991)

A new package in superset-core. Its types and stubs are replaced with Superset's implementations at startup (core_api_injection.py), the same mechanism queries and tasks use, so Celery workers get them too.

Function Purpose
run_query_context(payload) Runs a chart query context the way /api/v1/chart/data does (validation, raise_for_access, client-side post-processing) and returns JSON rows. Same rows as Export to .CSV.
iter_dashboard_chart_results(dashboard_id, active_data_mask) Yields one result per chart in layout order, with the dashboard's filters applied. A failed chart is reported with a reason, not raised.
describe_dashboard_export(dashboard_id, active_data_mask) Title, a permalink for the exported filter state, the applied native filters and Explore links. Can be dropped if reviewers prefer.
build_tab_name(raw, used, max_len) Valid, unique tab names (the existing Excel sheet-name helper, with the length as a parameter).
can_export_data(), can_export_dashboard(dashboard_id) The same export-permission checks the chart data API and the dashboard Excel export apply.
as_user(user_id) Runs background work as the requesting user. Task workers don't set g.user, and extensions can't import override_user.

The dashboard Excel export is refactored onto the same per-chart helper, so both exports share one path for query resolution, filtering and access checks. Its output doesn't change.

Frontend: download-menu locations and a toasts API (#46014)

  • Eight menu locations, one per download menu that offers "Export to Excel":
    • Explore's Export All Data (plus a pivoted entry);
    • the standalone/embedded download control;
    • the dashboard chart Download menu (plus a pivoted entry);
    • Drill to Detail;
    • Drill By;
    • the dashboard header Download menu.
  • Context on click:
    • Chart locations pass { getPayload, chartName, canDownload }. getPayload() builds, at click time, the query context the CSV export would post.
    • The dashboard location passes { dashboardId, dashboardTitle, activeDataMask, canDownload }.
  • Unchanged without extensions: with no extension installed, every menu looks exactly as it does today.
  • Toasts: a toasts namespace in @apache-superset/core (addSuccessToast, addDangerToast, …, plus removeToast), backed by Superset's existing toast store, with an optional link button.

First consumer: Google Sheets export (orion222/superset-google-sheets)

An evolution of sqllab-gsheets:

  • "Export to Google Sheets" in every chart download menu, using the same rows as Export to .CSV, typed cells and one tab per query.
  • Files are created in a Shared Drive and shared with the user.
  • It also tightens the SQL Lab export's permission check: can_export_data() instead of read.
  • Dashboard export, one spreadsheet with a tab per chart run as a background task, is the next phase.

New or Changed Public Interfaces

  • Python (apache-superset-core):
    • new package superset_core.exports: the functions above, plus the frozen dataclasses ChartQueryResult, ChartResult, AppliedFilter, DashboardExportInfo, and the enums GenericDataType and SkipReason;
    • IDs are integers, matching the existing superset_core DAOs and the dashboard export endpoint.
  • TypeScript (@apache-superset/core):
    • new toasts namespace;
    • new menu location types ChartDownloadLocation and DashboardDownloadLocation, and the context types ChartDownloadContext and DashboardDownloadContext.
  • No REST endpoint, model or permission changes in Superset. No path returns data a user couldn't already get from /api/v1/chart/data.
  • Docs: extensions/exports.md, extension-points/download-menus.md and extensions/toasts.md.

New dependencies

None in Superset. The Google Sheets extension depends on google-api-python-client and google-auth (Apache-2.0, maintained by Google), installed only with the extension.

Migration Plan and Compatibility

  • No database migrations or URL changes.
  • The changes are additive. Existing menus, exports and extensions keep working unchanged.
  • The Excel dashboard export produces identical workbooks before and after the refactor.

Rejected Alternatives

  • Google Sheets support built into Superset: an integration with one vendor; the extension framework is the intended place for it.
  • An extension calling Superset internals directly: fragile across releases, and against the extension model.
  • An extension calling /api/v1/chart/data over HTTP from its backend: wouldn't run as the requesting user inside background tasks, and duplicates request handling.
  • A per-surface API instead of shared menu locations: seven menus would each need their own extension hook. One location scheme and one hook cover them all.
  • Push status updates over websocket for long exports: they need the optional superset-websocket sidecar. Polling the existing task status API is enough for now.

Activity

  1. orion222 commented on Nov 4, 2026

    @orion222
    Author

    I split this issue into a frontend and backend PR, if you guys would like it as one I'm happy to do that too.

  2. changed the title [-][SIP] Extension APIs for exporting chart and dashboard data (Google Sheets export)[/-] [+][SIP-238] Extension APIs for exporting chart and dashboard data (Google Sheets export)[/+] on Nov 4, 2026
  3. added
    review:checkpointLast PR reviewed during the daily review standup
    and removed
    review:checkpointLast PR reviewed during the daily review standup
    on Nov 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    utsc2026UTSC 2026 course contributions

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions