A Python wrapper for the Metabase API developed by the ⭐️ Spark Tech team
Project description
Spark Metabase API
A Python wrapper for the Metabase API, developed by the Spark Tech team ⭐️
Installation
pip install spark-metabase-api
# Optional YAML support for the Infrastructure-as-Code module:
pip install "spark-metabase-api[iac]"
Quick start
from spark_metabase_api import Metabase_API
mb = Metabase_API(
domain="https://metabase.example.com",
email="me@example.com",
password="hunter2",
)
mb.copy_dashboard(source_dashboard_id=42, destination_collection_name="Acme")
Infrastructure-as-Code
Define a Metabase collection tree in YAML, version it in git, and apply it idempotently with a Terraform-style diff.
# Pull the live state for an existing collection
spark-metabase --domain "$MB_URL" --email "$MB_USER" --password "$MB_PASS" \
export "Acme Customer" specs/acme.yaml
# Show what would change after editing the spec
spark-metabase plan specs/acme.yaml
# Apply (with confirmation prompt unless --yes)
spark-metabase apply specs/acme.yaml
Example spec:
name: "Acme Customer"
description: "Customer-facing dashboards"
authority_level: official
collections:
- name: "Questions"
cards:
- name: "Daily revenue"
definition:
dataset_query:
type: native
database: 2
native:
query: "SELECT day, sum(amount) FROM sales GROUP BY 1"
display: line
visualization_settings: {}
dashboards:
- name: "Acme Dashboard"
description: "Top-level KPIs"
parameters: []
dashcards: [] # populated automatically by `export`
The Python API is also exposed:
from spark_metabase_api import Metabase_API, iac
mb = Metabase_API(domain=..., session_id=...)
# Export to YAML
spec = iac.export(mb, "Acme Customer")
iac.dump(spec, "specs/acme.yaml")
# Edit the file in git, then in CI:
spec = iac.load("specs/acme.yaml")
print(iac.plan(mb, spec).render())
iac.apply(mb, spec)
Natural keys & renames
Items are identified by (parent_path, kind, name) within the spec. Renaming
an item is therefore a destructive change (delete + create). To bind a spec
entry to a specific live item across renames, set entity_id (Metabase's
stable nanoid, available since v0.46) on the entry.
Forward references in dashcards
A dashcard can reference a card created by the same spec via
card_name: "<name>" instead of card_id. The applier looks the name up in
the cards present (or just created) inside the same collection and rewrites
the dashcard with the real id.
Natural-language dashboard authoring
pip install "spark-metabase-api[chatbot]"
Describe what you want; Claude inspects the live Metabase via read-only tools
(list_databases, list_tables, describe_table, search_metabase,
find_cards_using_table) and emits a CollectionSpec:
from spark_metabase_api import Metabase_API, iac
from spark_metabase_api.chatbot import chat
mb = Metabase_API(domain=..., session_id=...)
spec = chat(mb, "Build an Acme dashboard with monthly revenue and top accounts")
print(iac.plan(mb, spec).render())
iac.apply(mb, spec)
For UIs (Streamlit, Slack, etc.) use the streaming generator:
from spark_metabase_api.chatbot import stream
for event_type, payload in stream(mb, "..."):
if event_type == "text": render_assistant_text(payload)
elif event_type == "tool_call": render_tool_call(payload) # {name, input}
elif event_type == "tool_result": render_tool_result(payload) # {name, input, result}
elif event_type == "proposed": save_spec(payload) # CollectionSpec dict
Powered by Claude Opus 4.7 with adaptive thinking; the model needs an
ANTHROPIC_API_KEY environment variable.
Streamlit frontend
A single-file Streamlit app that wires the chatbot to a chat UI with live tool-call rendering, plan diffing, and an Apply button.
pip install "spark-metabase-api[streamlit]"
streamlit run streamlit_app.py
The app:
- collects Metabase + Anthropic credentials in the sidebar,
- streams Claude's progress (text, tool calls, expandable tool results) as the agent works,
- renders the proposed spec as YAML,
- previews the diff via
iac.planand applies it on demand.
Integration tests
A standalone script exercises the package against a live Metabase instance, in four phases with a sandboxed write area that's archived on exit:
python tests/integration_test.py \
--domain "$MB_URL" --email "$MB_USER" --password "$MB_PASS" \
--collection "My Reports" \
--source-dashboard-id 42 \
--chatbot
Phase 1 is fully read-only. Phase 2 creates a uniquely-named throwaway
collection, applies a tiny spec, exercises add_card_to_dashboard and
copy_dashboard(deepcopy=True), then archives the sandbox in a finally
block (use --keep-sandbox to keep it around for manual inspection).
Phase 3 (opt-in via --chatbot) runs the Claude agent but does not
apply the spec it proposes.
Acknowledgements
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spark_metabase_api-0.3.0.tar.gz.
File metadata
- Download URL: spark_metabase_api-0.3.0.tar.gz
- Upload date:
- Size: 34.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c904d965ca19918b4a24f03928c7f05b71841b9008f1dd52130a05b84843c740
|
|
| MD5 |
3471697f7d2732ba8c4c03e405538cef
|
|
| BLAKE2b-256 |
55e7b76488b7f85f769a8833559687a26b610790f82e8491798f8eb05f8703bc
|
File details
Details for the file spark_metabase_api-0.3.0-py3-none-any.whl.
File metadata
- Download URL: spark_metabase_api-0.3.0-py3-none-any.whl
- Upload date:
- Size: 35.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d886d4183b6d6ff8736ee6974815a8e25d358eb0b7f7bc7b4d3dff40ba7f035
|
|
| MD5 |
b346e2474cb2b8109901eca59d904cbb
|
|
| BLAKE2b-256 |
5cbc478cb737e82cee69c5f00cf7af1a055c9d4b946a757ad0f478fda6e5f1a2
|