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()/pre_aggregations_jobs_post()/pre_aggregations_jobs_get()/
readyz()/livez() (all four of the last are Python-only additions with no
@cubejs-client/core precedent: the first two wrap Cube's Pre-Aggregations Jobs
orchestration REST API, the last two wrap its unauthenticated health-check endpoints);
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.
Metadata
Release files for cubejs-client-python 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cubejs_client_python-1.0.1.tar.gz | 89.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cubejs_client_python-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 138.9 kB
Release files / cubejs_client_python-1.0.1.tar.gz
| Download URL | cubejs_client_python-1.0.1.tar.gz |
|---|---|
| Size | 89.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c08466426445a6abce3488861e3be6a780bc76def936ff87b1059d1c0f0cc24e
|
|
BLAKE2b-256 checksum How to use checksums |
5f7183f75baa53d9d414cb4a153b731c29ccdeff3c11c8a021f6ea28d10da081
|
| 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 Jul 29, 2026.
Transparency logRelease files / cubejs_client_python-1.0.1-py3-none-any.whl
| Download URL | cubejs_client_python-1.0.1-py3-none-any.whl |
|---|---|
| Size | 49.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1c637ab91dc0d43b648bcd7a3397785cfc8294b38b41fdb36d2ae2fa9c2c20c4
|
|
BLAKE2b-256 checksum How to use checksums |
691ca2a64993aaab2cc2928d2a00aadc343f067a6b47f7b2539905d8828b2117
|
| 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 Jul 29, 2026.
Transparency log