Skip to main content

busabase — the Busabase Python SDK

The official Python client for the Busabase REST API: Bases and records, Docs, files, skills, search, and the Change Requests every write goes through. One client works against Busabase Cloud and any self-hosted Busabase server.

  • Typed models for every endpoint, generated from the Busabase OpenAPI document with openapi-python-client.
  • A small hand-written layer on top: configuration from the same environment variables as the Busabase CLI, bb.<group>.<operation>(...) calls, and a typed BusabaseError for every failed request instead of a silent None.
  • Sync and async. Python 3.11+.

Install

pip install busabase
# or
uv add busabase

Quick start

from busabase import Busabase

bb = Busabase(api_key="bb_...")  # or set BUSABASE_API_KEY
for base in bb.bases.list():
    print(base.slug, base.name)
record = bb.records.get(record_id="rec_...")
print(record.head_commit.payload.to_dict())  # the record's field values

Busabase Cloud or self-hosted

Busabase Cloud Self-hosted server
base_url / BUSABASE_BASE_URL https://busabase.com (the default) your server, e.g. http://localhost:15419
api_key / BUSABASE_API_KEY required — create one in the dashboard not needed for a local server
space / BUSABASE_SPACE_ID needed when your key belongs to more than one space usually not needed
bb = Busabase()  # everything from the environment
bb = Busabase(base_url="http://localhost:15419")  # a local `busabase server`
bb = Busabase(api_key="bb_...", space="spc_...")  # a specific Cloud space

base_url may include /api/v1 or not. These are the same variables the Busabase CLI and the TypeScript SDK (busabase-sdk) read.

Cloud-only endpoints. The SDK covers the full public API. A few groups exist only on Busabase Cloud and return 404 from a self-hosted server: system (health, meta), users.me, and agent_tasks.

Writing: Change Requests

Every write in Busabase is a Change Request. When your key has write access it merges in the same call and you get the materialized object back; otherwise it waits for a person to review it. Check which one you got:

from busabase.generated.models import MaterializedRecord, PendingChangeRequest

result = bb.bases.create_change_request(
    base_id="bas_...",
    body={"fields": {"company": "Acme", "score": 7}, "message": "Add Acme — inbound lead"},
)
if isinstance(result, MaterializedRecord):
    print("merged:", result.id)
elif isinstance(result, PendingChangeRequest):
    print("waiting for review:", result.id)

Don't pass autoMerge — let the server decide based on your permissions.

Calling operations

Operations are grouped the way the API is (bases, records, nodes, docs, file_trees, change_requests, search, grep, …), with snake_case names. dir(bb) and dir(bb.records) list them.

bb.bases.list()
bb.records.list(base_id="bas_...", limit=20)
bb.nodes.get("nod_...")  # path parameters can be positional
bb.docs.create(body={"slug": "notes", "name": "Notes", "body": "# Hi"})
bb.grep(body={"pattern": "acme", "sources": ["records", "nodes"]})
bb.nodes.share.list()  # nested groups
await bb.records.get.asyncio(record_id="rec_...")  # async

Each one calls the generated function of the same name in busabase.generated.api and returns its parsed model (from busabase.generated.models). A request body can be a plain dict or the generated model. For full static typing, call the generated module directly with bb.client:

from busabase.generated.api.records import records_list

page = records_list.sync(client=bb.client, base_id="bas_...")

Errors

Any HTTP status of 400 or above raises BusabaseError — from bb.… calls and from the generated functions alike — carrying the server's error envelope:

from busabase import BusabaseError

try:
    bb.records.get(record_id="rec_missing")
except BusabaseError as error:
    print(error.status, error.code, error.message)  # 404 NOT_FOUND Record not found: rec_missing

code is the server's semantic outcome (NOT_FOUND, FORBIDDEN, BAD_REQUEST, CONFLICT, …). For a validation failure message spells out each field (fields.0.slug: Invalid input: …) and data holds the raw issues.

Configuration

Busabase(
    api_key=None,  # BUSABASE_API_KEY
    base_url=None,  # BUSABASE_BASE_URL, then https://busabase.com
    space=None,  # BUSABASE_SPACE_ID
    timeout=30.0,  # seconds, or an httpx.Timeout
    headers=None,  # extra headers on every request
    httpx_args=None,  # passed to httpx.Client / httpx.AsyncClient (proxy, verify, transport…)
)

Use it as a context manager (with Busabase() as bb:) or call bb.close() to release connections.

Development

uv sync                                    # Python 3.11+, installs the pinned generator too
uv run pytest                              # unit tests + generated-code drift check
BUSABASE_TEST_BASE_URL=http://127.0.0.1:15419 uv run pytest -m integration   # against a local server

src/busabase/generated/ is generated — never edit it by hand. It is produced from openapi.json by scripts/generate.py, and tests/test_generated.py fails if the two disagree:

uv run python scripts/generate.py          # regenerate after openapi.json changes
uv run python scripts/generate.py --check  # what the test runs

License

MIT

Metadata

Release files for busabase 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for busabase 0.1.0
File Size Uploaded Provenance
busabase-0.1.0.tar.gz 259.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for busabase 0.1.0
File Interpreter ABI Platform
busabase-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 981.6 kB

Release files / busabase-0.1.0.tar.gz

Download URL busabase-0.1.0.tar.gz
Size 259.4 kB
Tags Source
SHA-256 checksum
How to use checksums
77a8dddc1a1ced989bae7f72e2c8b2407186e0b772ba2ccc8a78b305c40db9c6
BLAKE2b-256 checksum
How to use checksums
9bd201dc4a4e11c6651c541b18e28ade6088c140f3e75838f16975ebbbef0e62
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 21, 2026.

Transparency log

Release files / busabase-0.1.0-py3-none-any.whl

Download URL busabase-0.1.0-py3-none-any.whl
Size 722.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fbef31a1872d4242972a11e09ede9fedce0bb29eef9439f2c26cdbccc371594f
BLAKE2b-256 checksum
How to use checksums
b7a4cd565ec9ba67a78b2dedaa9215eaa840419ab34fc59cebf5b0f2dccfc754
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 21, 2026.

Transparency log

Security for busabase 0.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for busabase-0.1.0.tar.gz

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 Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page