cayu.storage.PostgresBudgetLedger
Part of cayu.storage.postgres. Read the Python API overview and install the required extra.
from cayu.storage import PostgresBudgetLedgerPostgres-backed atomic budget reservation ledger for multi-worker apps.
reserve serializes per budget (scope/key/window/currency) under a
transaction-scoped advisory lock, so concurrent workers on separate
connections cannot jointly overshoot max_estimated_cost; reconcile
and release row-lock the reservation with SELECT ... FOR UPDATE.
The cayu_budget_reservations table is owned by the shared migration
machinery (ADR 0001 revision 8).
Bases: _PostgresStoreBase, BudgetLedger.
init (method)
Section titled “init (method)”PostgresBudgetLedger.__init__(conninfo: str | None=None, *, pool: AsyncConnectionPool | None=None, min_size: int=1, max_size: int=8, schema_mode: schema.SchemaMode=schema.SchemaMode.VALIDATE, clock: Callable[[], datetime] | None=None, reservation_ttl_seconds: int | None=DEFAULT_RESERVATION_TTL_SECONDS) -> Noneensure_schema (method)
Section titled “ensure_schema (method)”async PostgresBudgetLedger.ensure_schema() -> NoneOpen the pool and reconcile the schema now (per schema_mode).
Normally reconciliation happens lazily on first use; the cayu storage
CLI calls this to run a migrate (or validate) as an explicit step.
close (method)
Section titled “close (method)”async PostgresBudgetLedger.close() -> Nonereserve_batch (method)
Section titled “reserve_batch (method)”async PostgresBudgetLedger.reserve_batch(*, members, binding_id=None, binding_authority_digest=None, binding_allowance=None, binding_consumption_id=None) -> BudgetBatchResultReserve all ceilings in one PostgreSQL transaction.
register_budget_binding (method)
Section titled “register_budget_binding (method)”async PostgresBudgetLedger.register_budget_binding(*, binding_id: str, authority_digest: str, allowance: int) -> Nonedurable_state_paths (method)
Section titled “durable_state_paths (method)”PostgresBudgetLedger.durable_state_paths() -> tuple[Path, ...]Return local files that hold this ledger’s durable state.
claim_reservation_identity (method)
Section titled “claim_reservation_identity (method)”async PostgresBudgetLedger.claim_reservation_identity(*, reservation_id: str, publication_session_id: str, publication_id: str) -> Nonereservation_ttl_seconds (property)
Section titled “reservation_ttl_seconds (property)”PostgresBudgetLedger.reservation_ttl_seconds() -> int | Noneheartbeat (method)
Section titled “heartbeat (method)”async PostgresBudgetLedger.heartbeat(*, reservation_id: str) -> boolmark_dispatched (method)
Section titled “mark_dispatched (method)”async PostgresBudgetLedger.mark_dispatched(*, reservation_ids: tuple[str, ...], dispatch_id: str, dispatched_at: datetime | None=None) -> tuple[BudgetReservationRecord, ...]release_pre_provider_dispatch (method)
Section titled “release_pre_provider_dispatch (method)”async PostgresBudgetLedger.release_pre_provider_dispatch(*, reservation_ids: tuple[str, ...], dispatch_id: str, reason: str, occurred_at: datetime | None=None) -> tuple[BudgetReconciliation, ...]reserve (method)
Section titled “reserve (method)”async PostgresBudgetLedger.reserve(*, reservation_id: str | None=None, limit: BudgetLimit, session_id: str, agent_name: str, provider_name: str, model: str, model_attempt_identity: ModelAttemptIdentity, environment_name: str | None=None, settlement_event_payload: dict[str, Any] | None=None, settlement_fallback: BudgetSettlementFallback | None=None, requested_amount: Decimal | None=None, billing_identity: BillingIdentity | None=None, effective_at: datetime | None=None) -> BudgetReservationResultreconcile (method)
Section titled “reconcile (method)”async PostgresBudgetLedger.reconcile(*, reservation_id: str, actual_amount: Decimal, settlement_kind: Literal['completed', 'conservative']='completed', reason: str | None=None, occurred_at: datetime | None=None, billing_identity: BillingIdentity | None=None, pricing: BudgetReconciliationPricing | None=None) -> BudgetReconciliationrelease (method)
Section titled “release (method)”async PostgresBudgetLedger.release(*, reservation_id: str, reason: str, occurred_at: datetime | None=None) -> BudgetReconciliationload_reservation (method)
Section titled “load_reservation (method)”async PostgresBudgetLedger.load_reservation(reservation_id: str) -> BudgetReservationRecord | Noneload_settlement (method)
Section titled “load_settlement (method)”async PostgresBudgetLedger.load_settlement(settlement_id: str) -> BudgetSettlementRecord | Nonelist_pending_settlements (method)
Section titled “list_pending_settlements (method)”async PostgresBudgetLedger.list_pending_settlements(*, session_id: str | None=None, after: BudgetSettlementCursor | None=None, limit: int=100) -> list[BudgetSettlementRecord]mark_settlement_event_published (method)
Section titled “mark_settlement_event_published (method)”async PostgresBudgetLedger.mark_settlement_event_published(*, settlement_id: str, event_id: str) -> BudgetSettlementRecord