Python Client¶
The Python SDK supports both remote mode (connects to a running server) and local mode (no server needed).
Installation¶
Usage¶
Remote Mode¶
from slayer.client.slayer_client import SlayerClient
client = SlayerClient(url="http://localhost:5143")
query = {
"source_model": "orders",
"measures": ["*:count", "revenue:sum"],
"dimensions": ["status"],
"limit": 10,
}
# Get raw data
data = client.query(query)
# [{"orders.status": "completed", "orders._count": 42, ...}, ...]
# Get pandas DataFrame
df = client.query_df(query)
print(df)
Local Mode¶
No server needed — queries execute directly against the storage backend:
from slayer.client.slayer_client import SlayerClient
from slayer.storage.yaml_storage import YAMLStorage
client = SlayerClient(storage=YAMLStorage(base_dir="./slayer_data"))
# Same query API as remote mode
data = client.query(query)
df = client.query_df(query)
Accepted Input Shapes¶
client.query / query_sync / sql / sql_sync / explain / explain_sync / query_df all accept the same input union (mirroring engine.execute):
- A dict — a single query.
- A
SlayerQueryinstance. - A list of dicts or
SlayerQuery— a multi-stage DAG. Earlier stages are named sub-queries; the last entry is the root. Order doesn't matter (the engine auto-sorts). See Query Lists. - A string — runs the backing query of a query-backed model by name.
# Multi-stage DAG
client.query_sync([
{"name": "by_customer", "source_model": "orders", "measures": [{"formula": "amount:sum"}], "dimensions": [{"name": "customer_id"}]},
{"source_model": "by_customer", "measures": [{"formula": "amount_sum:avg"}]},
])
# Run-by-name (query-backed model)
client.query_sync("rev_by_region")
Other Methods¶
# List models
models = client.list_models()
# Get model definition
model = client.get_model("orders")
# Create a model
client.create_model({"name": "orders", "sql_table": "public.orders", ...})
# List datasources
datasources = client.list_datasources()
# Create a datasource
client.create_datasource({"name": "mydb", "type": "postgres", ...})
Direct Engine Access¶
For maximum control, use the query engine directly:
from slayer.engine.query_engine import SlayerQueryEngine
from slayer.storage.yaml_storage import YAMLStorage
storage = YAMLStorage(base_dir="./slayer_data")
engine = SlayerQueryEngine(storage=storage)
result = engine.execute(query=query)
# result.data — list of row dicts
# result.columns — list of column names
# result.attributes — ResponseAttributes with .dimensions and .measures dicts (column → FieldMetadata)
#
# client.query() returns SlayerResponse with all fields above
# client.sql(query) returns just the generated SQL string
# client.explain(query) returns SlayerResponse with EXPLAIN ANALYZE output
# result.row_count — number of rows
# result.sql — generated SQL string