Skip to main content

vibedasher — Python SDK

Official Python SDK for the Vibedasher headless data engine. The method you'll use most is client.query(...) — it runs SQL across your managed datasets and returns typed rows, so you can render a dashboard natively from your own backend.

Install

pip install vibedasher

Headless / eject — start here

Vibedasher hosts the data engine (ETL, datasets, query); you own the frontend/app. You author a dashboard in Vibedasher, eject its code, and wire it to the engine with a single call:

from vibedasher import Vibedasher

# Server-side (API key held on your server, never shipped to a browser).
client = Vibedasher(api_key="sk_...", region="eu-central-1")

result = client.query(
    sql="SELECT region, AVG(lead_price_usd) AS avg_price FROM sales GROUP BY region",
    params={"region": "Caribe"},     # bound/escaped server-side, never interpolated
)

for col in result.columns:
    print(col.name, col.type)        # e.g. region string / avg_price number
for row in result.rows:
    print(row["region"], row["avg_price"])
  • dataset_ids is optional (plural). Omit it and the server infers the dataset set from the aliases your sql references. Pass it to pin an exact set explicitly: client.query(sql=..., dataset_ids=[12, 47], params=...) — each id resolves server-side to that dataset's alias under RLS, and a dataset not in the set is rejected (deny-don't-drop). A mistyped/unknown alias raises 400 query_dataset_unresolved.
  • sql is inline and alias-only — it references dataset aliases, never a physical table.
  • Results are typed columnarresult.columns are QueryColumn(name, type) with typestring | number | boolean | date | timestamp | json, and result.rows are dicts keyed by column name.
  • Transport is hidden — inline vs presigned object storage, MessagePack decoding, and transient retries all happen inside query(). One call in, typed rows out.

query() is the one hand-written method (_query.py); everything else is generated (see below).

Where the query runs: type="wasm"

By default the server executes your SQL and returns rows. Pass type="wasm" to get a plan instead — the injected SQL plus one presigned Parquet per dataset — and execute it yourself (in DuckDB-WASM in a browser, or plain DuckDB locally):

result = client.query(sql="SELECT region, COUNT(*) FROM sales GROUP BY region", type="wasm")

if result.mode == "wasm":
    for src in result.plan.sources:
        print(src.alias, src.url, src.bytes)   # register each under `alias`
    print(result.plan.sql)                     # then run this
else:
    print(result.rows, result.fallback_reason) # ran server-side, and why

Authorization does not move. The server still authorizes, validates alias-only SQL, and injects row filters — in that order, before the capability check. Asking for wasm skips no gate; you get a plan only for data you were already allowed to read.

Asking for wasm does not guarantee getting it. If any participating dataset isn't wasm-capable — no current extract, an extract over the size cap, or a mandatory row-level filter — the query runs server-side and the response says so via mode: "backend" and a fallback_reason. It is never a silent downgrade, so always branch on result.mode, never on what you requested.

VibedasherEmbedClient (scoped-token) has no wasm lane and raises ValueError rather than quietly serving rows.

Embed vs eject

  • Embed (iframe, zero-code): paste a snippet; we host and render. Nothing to build.
  • Eject (this SDK, own-your-code): pull the dashboard's code into your stack and feed it data via client.query(...). Your app owns the rendering; only the data crosses the wire. See a runnable host app in examples/nextjs-embed (TS), the same contract as here.

Client-side (no backend) auth

For a pure-frontend app, mint a short-TTL scoped token and use the same method via the token-pinned client:

from vibedasher import VibedasherEmbedClient

client = VibedasherEmbedClient(token=scoped_token, region="eu-central-1")
result = client.query(sql=sql, params=params)
# The token pins the viz + datasets — dataset_ids are accepted for symmetry but the
# server enforces the token's bound set.

Everything else: resource operations (generated)

Datasets, uploads, viz metadata, API keys, etc. are generated from the OpenAPI spec:

from vibedasher.factory import create_client
from vibedasher.api.datasets import read_datasets_v1_datasets_get

client = create_client(api_key="sk_...", region="eu-central-1")
# Each operation lives under vibedasher.api.<tag>.<operation_id> and exposes
# .sync(), .sync_detailed(), .asyncio(), .asyncio_detailed().
datasets = read_datasets_v1_datasets_get.sync(client=client)

Auth is an API key sent as X-Api-Key (mint one via POST /v1/api-keys).

Layout

  • vibedasher/_query.py — the hand-written query() (transport, decode, retry, typed rows).
  • vibedasher/api/<tag>/<operation>.py — one module per API operation.
  • vibedasher/models/ — request/response models (attrs classes).
  • vibedasher/factory.pycreate_client(api_key, region=..., base_url=...).

Generated code — do not edit vibedasher/ by hand. Regenerate with make py from packages/sdk/. Source of truth: ../openapi.json. query() is the deliberate exception — hand-written and re-copied after each generation.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vibedasher-2.2.0.tar.gz (223.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vibedasher-2.2.0-py3-none-any.whl (722.9 kB view details)

Uploaded Python 3

File details

Details for the file vibedasher-2.2.0.tar.gz.

File metadata

  • Download URL: vibedasher-2.2.0.tar.gz
  • Upload date:
  • Size: 223.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vibedasher-2.2.0.tar.gz
Algorithm Hash digest
SHA256 468e118cf02ded46931b099efa9376bd69bfb28cb3cf7e00be877e9cdb1f2df2
MD5 45554de626e72966cef11e0c84854eca
BLAKE2b-256 547f9240b9f80096696ed607ee6a3f6cfdbf4bb5201dd98a87ee7d2e2fa1c6ab

See more details on using hashes here.

File details

Details for the file vibedasher-2.2.0-py3-none-any.whl.

File metadata

  • Download URL: vibedasher-2.2.0-py3-none-any.whl
  • Upload date:
  • Size: 722.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vibedasher-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 739ec6f2453127205ce8a2309cf1141fd65404745f6911643e942ae8da4b6f23
MD5 531b62db107cc0a84f50c0d0af7b7c1d
BLAKE2b-256 85a90887c3a82f694d367d9f7adec891a35fa27432fc9fa94af1dd932e507fe2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page