Skip to main content
Version: 2.x

Python API

Python 3.12 and 3.13 are supported. Install the Postgres backend with:

Terminal
pip install "bursar[postgres]"

Constructing the facade

Bursar wires a store, the optional billing/commerce capabilities, and an optional event emitter into one application-facing facade:

from bursar import Bursar, PostgresStore

store = PostgresStore(
database_url,
tenant_id=tenant_id,
provider_environment="test",
)
bursar = Bursar(credit_store=store)
  • credit_store is the only required argument. PostgresStore is the bundled implementation; CreditStore is the abstract base for custom backends.
  • tenant_id scopes every store operation to a single tenant.
  • billing_store plus commerce_options enable the billing and commerce capabilities (ingest_billing_event, checkouts, subscriptions, auto-recharge).
  • emitter receives credit lifecycle events (CreditEventEmitter).

Apply the database schema with bursar migrate before constructing a store — the package never runs migrations from the store itself.

Errors, deadlines, and retries

All Bursar-classified failures extend BursarError and expose stable code, category, and retryable fields. to_dict() returns the safe logging shape without exposing the underlying driver exception.

Use the Tenacity-backed retry helper only for reads or mutations protected by a stable idempotency key:

from bursar import BursarRetryOptions, is_bursar_error, retry_bursar_operation

try:
balance = retry_bursar_operation(
bursar.credits.get_balance,
user_id,
retry_options=BursarRetryOptions(max_attempts=3),
)
except Exception as error:
if is_bursar_error(error):
logger.error("Bursar request failed", extra={"bursar": error.to_dict()})
raise

StoreError.indeterminate means a transport failure occurred after a mutation may have reached PostgreSQL. Retry only with the same idempotency key. Custom stores should use StoreUnavailableError or StoreTimeoutError for classified transient failures rather than matching error-message text.

Package layout

The bursar top level exposes the application-facing facade, stores, pricing engine, common inputs, errors, and retry helpers. Domain-specific result and provider types remain grouped under focused modules such as bursar.credits.types and bursar.providers.

ExportPurpose
BursarThe facade: credits, catalog, accounts, plus optional billing/commerce
PostgresStoreProduction, tenant-scoped credit store (requires the [postgres] extra)
PostgresBillingStoreBilling store for payment-provider lifecycle (requires the [postgres] extra)
PricingEngineDatabase-free operation-pricing core
CreditStoreAbstract base class for custom credit backends
BillingStoreAbstract base class for custom billing backends
UsageMetricsOne billable operation (measures + dimensions)
load_config_from_dictValidate and canonicalize a config document
errorsBursarError, CreditError, ConfigError, StoreError, CapabilityNotSupportedError, …
retry helpersBursarRetryOptions, retry_bursar_operation, and its async counterpart

PostgresStore and PostgresBillingStore are lazy-imported: they are only available when the optional psycopg2 extra is installed.

Where to go next