Combined
SDK reference

Python SDK

Configure the Python client, query data, paginate, close resources, and handle errors.

Install and configure

Install from the private registry configured for your organization:

python -m pip install combined-context

Use the client as a context manager so its HTTP connection pool is always closed:

import os
from combined_context import ContextOS

with ContextOS(
    token=os.environ["COMBINED_TOKEN"],
    base_url=os.environ["COMBINED_API_URL"],
    timeout=30.0,
) as context:
    accounts = context.accounts.list()

If you do not pass token or base_url, the client reads COMBINED_TOKEN and COMBINED_API_URL. Call context.close() when you cannot use a context manager. A custom httpx.BaseTransport is supported for testing or controlled networking.

Discover and query

with ContextOS() as context:
    catalogue = context.catalog.list(account_id)
    result = context.sql.query(
        account_id,
        """
        SELECT channel_name, COUNT(*) AS messages
        FROM slack_messages
        WHERE sent_at >= ?
        GROUP BY channel_name
        ORDER BY messages DESC
        LIMIT 20
        """,
        parameters=["2026-08-01T00:00:00Z"],
        max_rows=20,
    )
    print(result["columns"], result["rows"], result["truncated"])

Pagination

cursor = None
while True:
    page = context.sources.list(account_id, cursor=cursor, limit=100)
    for source in page.data:
        print(source["name"], source["state"])
    cursor = page.next_cursor
    if cursor is None:
        break

The Page dataclass exposes data, next_cursor, has_more, and correlation_id. Restart from the first page if filters change. Never construct or decode a cursor.

Request options

Pass RequestOptions to control idempotency keys. The SDK generates a secure key for mutations when one is omitted. Reuse a supplied idempotency_key only for an identical request.

from combined_context import RequestOptions

context.sources.run(
    account_id,
    source_id,
    trigger="manual",
    options=RequestOptions(idempotency_key="run-20260816-001"),
)

Error handling

from combined_context import ContextOSError

try:
    result = context.sql.query(account_id, sql, parameters=parameters)
except ContextOSError as error:
    print(error.status, error.code, error.correlation_id, error.details)
    raise

The client validates required envelope and model fields. An invalid upstream envelope is raised as a 502 invalid_response, rather than returning partially trusted data.

On this page