Skip to main content

Pythonic client for Cube (cube.dev) semantic layer, with pandas integration (sync and async clients)

Project description

cubejs-client-python

A Pythonic client for Cube, the semantic layer for building data applications. This is a from-scratch Python port of @cubejs-client/core (tracking cube-js/cube#1744), not a mechanical transliteration: pandas DataFrame is the primary result type, and queries can be built with a fluent/operator DSL, while a faithful low-level core (ResultSet, pivoting, time-series generation) stays behaviorally verified against the JS SDK's own test fixtures.

Status: Phases 0-6 — sync (CubeClient) and async (AsyncCubeClient) clients, both sharing one core, with load()/meta()/sql()/dry_run()/subscribe()/ cube_sql()/cube_sql_stream(); ResultSet covers regularQuery, compareDateRangeQuery, and blendingQuery (table_pivot, chart_pivot, pivot, table_columns, series/series_names, decompose, drill_down, etc.), including custom (PostgreSQL-interval-style) time granularities; .to_pandas()/.df; the fluent/operator query builder (Query, dim()/measure()); a PivotConfig builder for to_pandas(pivot_config=...); Meta.members_grouped_by_cube(); and a compact/columnar opt-in via load(response_format=...). The client-side format module and WebSocket transport are out of scope. subscribe() degrades to HTTP polling (no push transport) and uses native cancellation rather than the JS mutexObj/mutexKey supersession API.

📖 Full API Reference — every class, method, and type, with verified example output and a list of differences from the JS SDK.

Install

pip install cubejs-client-python

The distribution is cubejs-client-python; the import is cubejs_client:

from cubejs_client import cube

For local development, see Development.

Usage

from cubejs_client import cube, Query, dim

client = cube(api_token="CUBE-API-TOKEN", api_url="http://localhost:4000/cubejs-api/v1")

# Plain dict query (same shape the JS SDK / REST API expects)
result_set = client.load({
    "measures": ["Orders.count"],
    "dimensions": ["Orders.status"],
})

# Or the fluent builder + operator-overloaded filter DSL
query = (
    Query()
    .measures("Orders.count")
    .dimensions("Orders.status")
    .filter(dim("Orders.status") != "cancelled")
    .order("Orders.count", "desc")
)
result_set = client.load(query)

df = result_set.to_pandas()          # pandas DataFrame, typed via table_columns()
rows = result_set.table_pivot()      # list[dict], byte-for-byte faithful to the JS SDK

Async client

AsyncCubeClient mirrors CubeClient method-for-method (load/meta/sql/dry_run, same params and query-builder support), backed by httpx.AsyncClient:

from cubejs_client import AsyncCubeClient

client = AsyncCubeClient(api_token="CUBE-API-TOKEN", api_url="http://localhost:4000/cubejs-api/v1")
result_set = await client.load({"measures": ["Orders.count"]})
df = result_set.to_pandas()

PivotConfig builder

from cubejs_client import PivotConfig

pivot_config = PivotConfig().x("Orders.createdAt.day").y("Orders.status", "measures")
df = result_set.to_pandas(pivot_config=pivot_config)

PivotConfig is a Pythonic convenience accepted by to_pandas(); ResultSet's own methods (pivot, chart_pivot, table_pivot, ...) stay faithful to the JS core and take plain dicts only — call .build() first if calling those directly.

Direct SQL (cube_sql / cube_sql_stream)

# One-shot: returns {"schema": [...], "data": [...], "lastRefreshTime"?: str}
result = client.cube_sql("SELECT status, measure(count) FROM orders GROUP BY 1")
for row in result["data"]:
    print(row)

# Streaming: typed chunks ({"type": "schema"|"data"|"error", ...})
for chunk in client.cube_sql_stream("SELECT * FROM orders"):
    if chunk["type"] == "data":
        print(chunk["data"])

# Async streaming
async for chunk in async_client.cube_sql_stream("SELECT * FROM orders"):
    ...

Live updates (subscribe)

def on_update(error, result_set):
    if error is None:
        print(result_set.table_pivot())

subscription = client.subscribe({"measures": ["Logs.count"]}, on_update)
# ... later ...
subscription.unsubscribe()

# Async: schedule an asyncio.Task, cancel with `await`
subscription = async_client.subscribe({"measures": ["Logs.count"]}, on_update)
await subscription.unsubscribe()

subscribe() re-polls every poll_interval seconds and calls callback(error, result_set) for each update; request errors are delivered to the callback without stopping the loop.

Requesting compact / columnar response formats

# The wire format is decoded transparently; opt in to the smaller payload with:
result_set = client.load({"measures": ["Orders.count"]}, response_format="compact")

Development

python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

pytest tests            # golden tests (ported from the JS SDK's own test suite) + unit tests
ruff check src tests
mypy src/cubejs_client

Golden tests

tests/golden/ contains fixtures and expected outputs transcribed verbatim from the JS SDK's test/helpers.ts and test/ResultSet.test.ts, so the Python ResultSet/time-series core can be checked against the same ground truth the JS client is tested against. When porting new JS behavior, port the matching JS test case's exact input/output first.

Project details


Download files

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

Source Distribution

cubejs_client_python-0.1.0.tar.gz (81.4 kB view details)

Uploaded Source

Built Distribution

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

cubejs_client_python-0.1.0-py3-none-any.whl (46.6 kB view details)

Uploaded Python 3

File details

Details for the file cubejs_client_python-0.1.0.tar.gz.

File metadata

  • Download URL: cubejs_client_python-0.1.0.tar.gz
  • Upload date:
  • Size: 81.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for cubejs_client_python-0.1.0.tar.gz
Algorithm Hash digest
SHA256 01ccb4eaa9c4e68009e9aca3881d4099c90e1407ff405b28179ce8d49130ad7f
MD5 e0eaaa0c478ae004bf7d750b5f31fa02
BLAKE2b-256 2b756ba7444c9554a789df1a50583c9ff8bfe23a538c4e7b594cf9972b5de3b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for cubejs_client_python-0.1.0.tar.gz:

Publisher: release.yml on spark-strategy/cubejs-client-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cubejs_client_python-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cubejs_client_python-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0da1edd80416b073f6c22ef6f5f5e12a2e127ad501143f30a2c2b1ea54eefa07
MD5 9eb471d9133c889c545d5f3592c8e5a7
BLAKE2b-256 a24f585696b1381bafad4d6e5b9fcde2f1b2077a7c889a9742e0e9f8c0418523

See more details on using hashes here.

Provenance

The following attestation bundles were made for cubejs_client_python-0.1.0-py3-none-any.whl:

Publisher: release.yml on spark-strategy/cubejs-client-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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