Skip to main content

superset-cli

CLI for self-hosted Apache Superset.

MIT licensed. Copyright (c) 2026 Robin Rittsteiger.

Scope

Current scope (read by default, write opt-in):

  • Python project managed with uv
  • devenv shell configured for Python + uv
  • local instance config management (add, list, remove)
  • browser-cookie import login with immediate live validation + saved auth-state inspection
  • read access to dashboards, charts, datasets, databases, annotation layers, CSS templates, themes, tags, reports, saved queries, queries, logs, permalinks, OpenAPI, embedded configs, related objects, chart data
  • write access to chart, dashboard, dataset, database, saved-query, SQL Lab, tag, theme, security (roles, users, RLS), and asset-import surfaces; every write command requires --allow-write on every invocation (see ADR 0009 and ADR 0010)
  • shared list-query controls on all list commands via --page (0-based), --page-size, --search, --order-column, and --order-direction
  • user-friendly error messages for auth expiry, missing resources, and network failures (exit code 1, no raw tracebacks)

Decision log

Long-lived technical reasoning lives in docs/decisions/.

Use it to understand why key choices were made, not just what the code does. Start with docs/decisions/README.md.

Documentation map

A top-level map of repository docs lives in docs/index.md. A glossary of repository-specific terms lives in docs/glossary.md.

Architecture

A structural overview of modules, command-to-code mappings, and test entry points lives in docs/architecture/README.md.

Installation for users

After the first PyPI release, install the CLI without cloning this repository:

uv tool install superset-cli
superset-cli --help

Upgrade with uv tool upgrade superset-cli. Python 3.12 or newer is required; uv can provision Python when needed. pipx install superset-cli is an alternative. The release workflow exists, but a published package is not yet confirmed.

Publishing releases (maintainers)

The canonical upstream is RobinOnHisOwn/superset_cli, owned by the RobinOnHisOwn organization. The company repository is a mirror, not an independent publishing source.

Before the first release:

  1. Confirm ownership and permission to publish from the canonical repository, and review source and Git history for sensitive material. MIT licensing is configured in LICENSE and the distribution metadata.
  2. Keep this repository excluded from shared self-hosted runner groups. CI and publishing use GitHub-hosted ubuntu-latest runners.
  3. Create a GitHub environment named pypi with required reviewer approval and restrict deployment to tags matching v* (no branches). A sole maintainer can select themselves as reviewer with prevent-self-review disabled. On Free/Pro/Team, required reviewers are available only for public repositories; configure this gate after making the reviewed repository public, before publishing. Protect release tags and main against unauthorized changes.
  4. Configure a pending PyPI Trusted Publisher with project superset-cli, owner RobinOnHisOwn, repository superset_cli, workflow filename publish.yml, and environment pypi. Do not create an API-token secret. Configure only the canonical repository, not mirrors.

For each release, update project.version in pyproject.toml and regenerate uv.lock with uv lock; have the change reviewed and CI pass. Run Build and publish manually for a build-only rehearsal. Publish a GitHub release from the reviewed commit with a matching tag (for example v0.1.0 for version 0.1.0), then approve the pypi environment deployment. Manual runs never publish; published releases build and test before publishing the same artifacts. PyPI versions cannot be overwritten: use a new version for changed distributions. Prereleases also publish, so use a corresponding version such as 0.2.0rc1 and tag v0.2.0rc1.

See ADR 0011 for the security rationale.

Quick start for contributors

If you use direnv, allow the repo once and devenv will auto-activate whenever you enter this directory.

direnv allow
uv sync --group dev
uv run superset-cli --help
uv run pytest -v

Without direnv, enter the shell manually:

devenv shell

Custom authenticated API calls

uv run superset-cli api prod /api/v1/_openapi --json
uv run superset-cli api prod /api/v1/dashboard/ --param 'q={"page":0,"page_size":10}' --json
uv run superset-cli api prod /api/v1/chart/42 --method PUT --file /tmp/chart.json --allow-write --json

Replace the instance and IDs with discovered values; the write example is not permission to execute it. GET is the default. POST, PUT, PATCH, and DELETE require --allow-write, including read-like POST calls. Use repeated --param KEY=VALUE options and JSON object bodies through --body, --body - (stdin), or --file. Responses preserve the full API envelope: --json emits compact JSON, otherwise pretty JSON.

The command validates the saved session before sending the request. Missing or rejected authentication triggers one browser-cookie import attempt with live validation; select a browser with --browser zen if needed. You must already be signed in in that browser. Recovery progress goes to stderr; no browser is launched and sent mutations are never retried. Network errors and permission failures do not trigger recovery. Only instance-relative /api/v1/ paths are accepted and redirects are not followed. Custom requests handle CSRF automatically. Existing commands retain their explicit login behavior.

Current commands

uv run superset-cli instances add prod https://superset.example.com
uv run superset-cli instances list --json
uv run superset-cli instances remove prod --json
uv run superset-cli auth login prod                          # auto-detect: chrome -> edge -> brave -> firefox -> zen -> safari
uv run superset-cli auth login prod --browser firefox        # read cookies from Firefox
uv run superset-cli auth login prod --browser zen --json     # read cookies from Zen Browser
uv run superset-cli auth logout prod --json
uv run superset-cli auth status prod --json
uv run superset-cli auth validate prod --json
uv run superset-cli openapi fetch prod --json
uv run superset-cli me show prod --json
uv run superset-cli me roles prod --json
uv run superset-cli dashboards list prod --json
uv run superset-cli dashboards list prod --page 0 --page-size 25 --json
uv run superset-cli dashboards list prod --search Revenue --order-column dashboard_title --order-direction asc --json
uv run superset-cli dashboards get prod 7 --json
uv run superset-cli dashboards diff prod 7 8 --json           # field-by-field record comparison
uv run superset-cli dashboards charts prod 7 --json
uv run superset-cli dashboards datasets prod 7 --json
uv run superset-cli charts list prod --json
uv run superset-cli charts list prod --page 1 --page-size 10 --json
uv run superset-cli charts list prod --search Revenue --order-column slice_name --order-direction desc --json
uv run superset-cli charts get prod 42 --json
uv run superset-cli datasets list prod --json
uv run superset-cli datasets list prod --page 0 --page-size 50 --json
uv run superset-cli datasets list prod --search orders --order-column table_name --order-direction asc --json
uv run superset-cli datasets get prod 5 --json
uv run superset-cli databases list prod --json
uv run superset-cli databases list prod --page 0 --page-size 10 --json
uv run superset-cli databases list prod --search analytics --order-column database_name --order-direction desc --json
uv run superset-cli databases get prod 1 --json
uv run superset-cli databases schemas prod 1 --json
uv run superset-cli databases tables prod 1 --schema analytics --json
uv run superset-cli dashboards embedded prod 7 --json
uv run superset-cli datasets related prod 21 --json
uv run superset-cli charts data prod 10 --json
uv run superset-cli annotation-layers list prod --json
uv run superset-cli annotation-layers get prod 50 --json
uv run superset-cli css-templates list prod --json
uv run superset-cli css-templates get prod 1 --json
uv run superset-cli themes list prod --json
uv run superset-cli themes get prod 1 --json
uv run superset-cli tags list prod --json
uv run superset-cli tags get prod 1 --json
uv run superset-cli reports list prod --json
uv run superset-cli reports get prod 1 --json
uv run superset-cli saved-queries list prod --json
uv run superset-cli saved-queries get prod 1 --json
uv run superset-cli queries list prod --json
uv run superset-cli queries get prod 1 --json
uv run superset-cli logs list prod --json
uv run superset-cli logs get prod 1 --json
uv run superset-cli logs recent-activity prod --json
uv run superset-cli permalinks resolve prod dashboard abc123 --json
uv run superset-cli datasources column-values prod table 21 country --json

Write commands

Every command in the table below requires --allow-write on every invocation. Without it the command prints what it would do and exits non-zero (dry-run by default).

# Charts
uv run superset-cli charts create     prod --body '{"slice_name":"Revenue","viz_type":"line"}' --allow-write
uv run superset-cli charts update     prod 42 --body '{"slice_name":"Revenue v2"}' --allow-write
uv run superset-cli charts update     prod 42 --clear-query-context --allow-write   # drop stale saved query_context after a params edit
uv run superset-cli charts delete     prod 42 --allow-write
uv run superset-cli charts favorite   prod 42 --allow-write
uv run superset-cli charts unfavorite prod 42 --allow-write

# Dashboards
uv run superset-cli dashboards create     prod --file dashboard.json --allow-write
uv run superset-cli dashboards update     prod 7  --body '{"published":true}' --allow-write
uv run superset-cli dashboards delete     prod 7  --allow-write
uv run superset-cli dashboards favorite   prod 7  --allow-write
uv run superset-cli dashboards unfavorite prod 7  --allow-write
uv run superset-cli dashboards copy       prod 7  --body '{"dashboard_title":"Revenue (copy)"}' --allow-write

# Datasets
uv run superset-cli datasets create  prod --file dataset.json --allow-write
uv run superset-cli datasets update  prod 21 --body '{"description":"updated"}' --allow-write
uv run superset-cli datasets delete  prod 21 --allow-write
uv run superset-cli datasets refresh prod 21 --allow-write

# Databases
uv run superset-cli databases create          prod --file database.json --allow-write
uv run superset-cli databases update          prod 1 --body '{"expose_in_sqllab":true}' --allow-write
uv run superset-cli databases delete          prod 1 --allow-write
uv run superset-cli databases test-connection prod --file connection.json --allow-write

# Saved queries
uv run superset-cli saved-queries create prod --body '{"label":"q1","sql":"select 1"}' --allow-write
uv run superset-cli saved-queries update prod 9 --body '{"label":"q1-v2"}' --allow-write
uv run superset-cli saved-queries delete prod 9 --allow-write

# SQL Lab
uv run superset-cli sqllab execute    prod --body '{"database_id":1,"sql":"select 1"}' --allow-write
uv run superset-cli sqllab format-sql prod --body '{"sql":"select 1"}' --allow-write
uv run superset-cli sqllab estimate   prod --body '{"database_id":1,"sql":"select 1"}' --allow-write
uv run superset-cli sqllab stop-query prod --body '{"client_id":"abc"}' --allow-write

# Tags, themes
uv run superset-cli tags create   prod --body '{"name":"finance"}' --allow-write
uv run superset-cli tags update   prod 1 --body '{"name":"finance-v2"}' --allow-write
uv run superset-cli tags delete   prod 1 --allow-write
uv run superset-cli themes create prod --body '{"theme_name":"Dark"}' --allow-write
uv run superset-cli themes update prod 1 --body '{"theme_name":"Dark v2"}' --allow-write
uv run superset-cli themes delete prod 1 --allow-write

# Security: roles, users, RLS rules
uv run superset-cli security role-create prod --body '{"name":"Analyst"}' --allow-write
uv run superset-cli security role-update prod 5 --body '{"name":"Analyst v2"}' --allow-write
uv run superset-cli security role-delete prod 5 --allow-write
uv run superset-cli security user-create prod --file user.json --allow-write
uv run superset-cli security user-update prod 2 --body '{"active":false}' --allow-write
uv run superset-cli security user-delete prod 2 --allow-write
uv run superset-cli security rls create  prod --file rls.json --allow-write
uv run superset-cli security rls update  prod 3 --body '{"name":"updated"}' --allow-write
uv run superset-cli security rls delete  prod 3 --allow-write

# Asset import (server-side multipart upload)
uv run superset-cli import upload prod dashboard --file bundle.zip --allow-write
uv run superset-cli import upload prod chart     --file bundle.zip --overwrite --passwords '{"db.zip":"hunter2"}' --allow-write

Both --body '<json>' and --file <path-to-json> accept the request payload. Pass --body - to read JSON from stdin. The two flags are mutually exclusive.

Local Superset for testing

devenv includes a process that boots a sqlite-backed Apache Superset on http://localhost:8088 for ad-hoc CLI testing. No Redis, no Celery, no Docker. First boot installs Superset into .devenv/state/superset/venv/ and seeds an admin user (~1–2 min). Subsequent boots are seconds.

devenv up superset                # start it (or: bash scripts/dev-superset.sh)
superset-open                     # open http://localhost:8088/login/ in your default browser
# log in as user: admin   password: admin

superset-cli instances add local http://localhost:8088
superset-cli auth login local     # reads cookies from your installed browser
superset-cli me show local --json
superset-cli tags create local --body '{"name":"smoke"}' --allow-write --json

The dev instance disables CSRF and Talisman so cookie auth works without extra setup. It is not safe to expose. State lives under .devenv/state/superset/; delete that directory to reset.

Snowflake connections from ~/.snowflake/connections.toml

On every Superset start, scripts/dev-superset-import-snowflake.sh reconciles the local instance's database list against ~/.snowflake/connections.toml. Connections missing in Superset are created as snowflake-<name>; existing ones are skipped. Auth methods supported:

  • password — baked into the SQLAlchemy URI.
  • key-pair (private_key_path / private_key_file) — mapped to authenticator=snowflake_jwt, key path stored in the database's extra.
  • PROGRAMMATIC_ACCESS_TOKEN — the file at token_file_path is read and submitted as the password. No authenticator parameter is sent (the connector rejects PROGRAMMATIC_ACCESS_TOKEN as an authenticator value even though the Snowflake CLI uses that label in TOML).
  • externalbrowser / oauth — skipped (no browser on the server).

If a TOML entry has no database field, the importer defaults to SNOWFLAKE_SAMPLE_DATA so Superset's connection-test query has a current database. Failures in the importer never bring down the Superset server. Secrets written into Superset's sqlite metadata DB are protected only by a static dev SECRET_KEY — do not point this at a production credential.

Metadata

Release files for superset-cli 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for superset-cli 0.1.0
File Size Uploaded
superset_cli-0.1.0.tar.gz 166.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for superset-cli 0.1.0
File Interpreter ABI Platform
superset_cli-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 191.5 kB

Release files / superset_cli-0.1.0.tar.gz

Download URL superset_cli-0.1.0.tar.gz
Size 166.4 kB
Tags Source
SHA-256 checksum
How to use checksums
9d102cf505938ec669b65de09cc177828d039d716f5e34931ba27bb84649bb39
BLAKE2b-256 checksum
How to use checksums
fac99c6f1177e57f7fc538682632aa95c3b211e7680ee295d94ac867b551ad4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release files / superset_cli-0.1.0-py3-none-any.whl

Download URL superset_cli-0.1.0-py3-none-any.whl
Size 25.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b21b143246b735a3f7990bef0c6735a9c8dbce0ab61a0615aca67ac1a49cd45
BLAKE2b-256 checksum
How to use checksums
7cd12f06d9d97a0645c1fe4d5a17f23ec92ae9dc37b74ac6b9c9f517c95df207
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page