bursar.PostgresStore
class bursar.PostgresStore(database_url=None, *, tenant_id, max_pool_size=20, pool=None, usage_backend='postgres', provider_environment, connection_timeout_seconds=10.0, statement_timeout_ms=30000, idle_transaction_timeout_ms=30000, application_name='bursar-python', on_pool_error=None, postgres_options=None)
Bases: CreditStore
Credit store backed by a raw Postgres connection with pooling.
- Parameters:
- database_url (str | None) – Postgres connection string
(e.g.
postgresql://user:pass@host:5432/db). - tenant_id (str | UUID)
- max_pool_size (int)
- pool (PostgresPool | None)
- usage_backend (Literal [ 'postgres' , 'clickhouse' ])
- provider_environment (ProviderEnvironment)
- connection_timeout_seconds (float)
- statement_timeout_ms (int)
- idle_transaction_timeout_ms (int)
- application_name (str)
- on_pool_error (Callable [ [BursarError ] , None ] | None)
- postgres_options (PostgresConnectionOptions | None)
- database_url (str | None) – Postgres connection string
(e.g.
property provider_environment : Literal['live', 'test', 'sandbox']
Provider namespace used by catalog and credit transactions.
property database_url : str
Postgres connection string for this store (read-only).
property tenant_id : str
Tenant UUID bound to every store transaction.
close()
Close all connections in the pool.
- Return type: None
get_balance(user_id)
Get the current balance for a user.
- Parameters: user_id (str) – The user ID.
- Returns: BalanceResult with user_id, balance, and lifetime_purchased. Returns zero balance when the user has no balance record.
- Return type: BalanceResult
add_credits(user_id, amount, type='adjustment', metadata=None, expires_at=None, bucket=None, *, idempotency_key)
Add credits to a user’s balance.
- Parameters:
- user_id (str) – The user ID.
- amount (Decimal) – The credit amount.
- type (str) – The transaction type (default “adjustment”).
- metadata (CreditMetadata | None) – Optional structured metadata.
- expires_at (datetime | None) – Optional expiry datetime for the credits.
- bucket (str | None) – Target bucket key, or None for default.
- idempotency_key (str) – Idempotency key for replay protection.
- Returns: AddCreditsResult with ledger entry details.
- Raises: StoreError – If the RPC returns no result or an error.
- Return type: AddCreditsResult
deduct_with_allowance(user_id, amount, *, idempotency_key, operation='usage', feature=None, model=None, region=None, measures=None, dimensions=None, metadata=None)
Call the plan-aware atomic usage-charge RPC.
- Parameters:
- user_id (str)
- amount (Decimal)
- idempotency_key (str)
- operation (str)
- feature (str | None)
- model (str | None)
- region (str | None)
- measures (dict *[*str , Decimal | int | float ] | None)
- dimensions (dict *[*str , Any ] | None)
- metadata (CreditMetadata | None)
- Return type: DeductionResult
record_usage(user_id, operation, requested, *, idempotency_key, feature=None, model=None, region=None, measures=None, dimensions=None, metadata=None)
Append priced usage telemetry without creating another debit.
- Parameters:
- user_id (str)
- operation (str)
- requested (Decimal)
- idempotency_key (str)
- feature (str | None)
- model (str | None)
- region (str | None)
- measures (dict *[*str , Decimal | int | float ] | None)
- dimensions (dict *[*str , Any ] | None)
- metadata (CreditMetadata | None)
- Return type: UsageRecordResult
create_lease(user_id, amount, operation_type, options)
Create a credit lease (reservation) for admission control.
- Parameters:
- user_id (str) – The user ID.
- amount (Decimal) – The worst-case amount to reserve.
- operation_type (str) – The operation type key.
- billing_mode – Billing mode policy (“strict”, “overdraft”).
- floor – Minimum balance floor during lease.
- max_concurrent – Max concurrent leases for this user, or None.
- ttl_seconds – Time-to-live for the lease in seconds.
- model – The AI model identifier, or None.
- overdraft_floor – Overdraft floor, or None.
- metadata – Optional structured metadata.
- period_start – Calendar period start date, or None.
- feature – Entitlement feature key, or None.
- options (CreateLeaseOptions)
- Returns: LeaseResult with lease_id and reservation details.
- Raises: StoreError – If the RPC returns no result (admission denied).
- Return type: LeaseResult
settle_lease(user_id, lease_id, amount, options=None)
Settle a lease by deducting the actual amount used.
- Parameters:
- user_id (str) – The user ID.
- lease_id (str) – The lease ID to settle.
- amount (Decimal) – The actual amount to charge.
- idempotency_key – Idempotency key for replay protection.
- floor – Minimum balance floor after deduction.
- model – The AI model identifier, or None.
- metadata – Optional structured metadata.
- skip_allowance – If True, skip plan allowance checks.
- period_start – Calendar period start date, or None.
- feature – Entitlement feature key, or None.
- options (SettleLeaseOptions | None)
- Returns: DeductionResult with ledger entry details.
- Return type: DeductionResult
get_lease_pricing_context(user_id, lease_id)
Read the immutable pricing context captured by a subject-owned lease.
- Parameters:
- user_id (str)
- lease_id (str)
- Return type: LeasePricingContext | None
release_lease(user_id, lease_id)
Release a lease without deducting credits (cancels the reservation).
- Parameters:
- user_id (str) – The user ID.
- lease_id (str) – The lease ID to release.
- Returns: ReleaseResult indicating whether the release was successful.
- Return type: ReleaseResult
renew_lease(user_id, lease_id, ttl_seconds)
Extend an active lease’s expiry without changing its policy snapshot.
- Parameters:
- user_id (str)
- lease_id (str)
- ttl_seconds (int)
- Return type: LeaseResult
expire_leases(limit=100)
Expire a bounded batch of abandoned leases and release reservations.
- Parameters: limit (int)
- Return type: int
get_available(user_id)
Get the available (unreserved) credit balance for a user.
- Parameters: user_id (str) – The user ID.
- Returns: AvailableResult with balance, reserved, and available amounts.
- Return type: AvailableResult
get_active_catalog()
Fetch the active catalog revision from the store.
- Return type: CatalogRevision | None
publish_and_activate_catalog(config, label=None, rollout=None)
Publish and activate a catalog revision.
- Parameters:
- config (dict *[*str , Any ]) – The Bursar configuration document.
- label (str | None) – Optional human-readable label.
- rollout (Any | None)
- Returns: The ID of the newly activated catalog revision.
- Raises:
- StoreError – If the RPC returns no result.
- ConfigError – If the config fails validation.
- Return type: str
get_catalog_history()
Get all catalog revisions.
- Returns: List of CatalogRevisionSummary (may be empty).
- Return type: list[CatalogRevisionSummary]
get_catalog_revision(version)
Get a catalog revision by version number.
- Parameters: version (int) – The version number to retrieve.
- Returns: CatalogRevision if found, None otherwise.
- Return type: CatalogRevision | None
activate_catalog_revision(version, rollout=None)
Activate a catalog revision.
- Parameters:
- version (int) – The version number to activate.
- rollout (Any | None)
- Returns: The ID of the activated config.
- Raises: StoreError – If the version is not found.
- Return type: str
publish_catalog_draft(config, label=None)
Publish an inactive catalog draft.
- Parameters:
- config (dict *[*str , Any ])
- label (str | None)
- Return type: str
get_user_plan(user_id)
Get the current plan for a user.
- Parameters: user_id (str) – The user ID.
- Returns: GetUserPlanResult with plan details or defaults if no plan assigned.
- Return type: GetUserPlanResult
check_feature(user_id, feature)
Check whether a user’s plan has a specific feature entitlement.
Convenience method. Default implementation calls get_user_plan()
and inspects the features dict. Override in custom stores for
optimized queries.
Feature presence is distinguished from truthiness:
the feature is considered present when the key exists and its value is
not None/False. Numeric 0 and empty string "" are
therefore present (has_feature=True).
- absent /
None/False→has_feature=False True/ numeric (incl.0) / string (incl."") →has_feature=True
Note: identity checks (is None/is False) are used rather than the
contract’s literal not in (None, False), because 0 == False /
0.0 == False in Python would otherwise mis-classify numeric 0 as
absent even though numeric 0 and "" are present values.
- Parameters:
- user_id (str)
- feature (str)
- Return type: CheckFeatureResult
set_user_plan(user_id, plan_key, plan_assigned_at=None)
Assign a plan to a user.
- Parameters:
- user_id (str) – The user ID.
- plan_key (str) – The public plan key.
- plan_assigned_at (datetime | None) – The assignment datetime, or None for now.
- Returns: SetUserPlanResult with assignment details.
- Raises: StoreError – If the RPC returns no result.
- Return type: SetUserPlanResult
unset_user_plan(user_id)
Remove the plan assignment from a user.
- Parameters: user_id (str) – The user ID.
- Returns: Dict with the user_id.
- Return type: UnsetUserPlanResult
set_plan_revision_pin(user_id, pinned)
Pin or unpin the user’s current catalog-plan revision.
- Parameters:
- user_id (str)
- pinned (bool)
- Return type: bool
apply_due_plan_changes(limit=100)
Apply one bounded batch of renewal-effective plan changes.
- Parameters: limit (int)
- Return type: int
start_plan_migration(from_plan_id, to_plan_id)
Create a resumable migration from one catalog plan to another.
- Parameters:
- from_plan_id (str | None)
- to_plan_id (str)
- Return type: PlanMigrationStartResult
migrate_plan_batch(migration_id, batch_size=100)
Advance a plan migration by one bounded batch.
- Parameters:
- migration_id (str)
- batch_size (int)
- Return type: PlanMigrationBatchResult
get_quota_state(user_id, quota_key=None)
Return current quota windows for a user.
- Parameters:
- user_id (str)
- quota_key (str | None)
- Return type: list[QuotaState]
check_allowance(user_id)
Check the remaining plan allowance for a user.
- Parameters: user_id (str) – The user ID.
- Returns:
AllowanceResult with the current window, or
Nonewhen the subject has no active allowance policy. - Return type: AllowanceResult | None
list_quota_events(user_id, options=None)
List persisted quota threshold and blocking events.
- Parameters:
- user_id (str)
- options (ListQuotaEventsOptions | None)
- Return type: list[QuotaEvent]
refund_credits(entry_id, *, idempotency_key, amount=None, reason=None, metadata=None)
Refund a previous ledger entry.
- Parameters:
- entry_id (str) – The original ledger entry ID to refund.
- amount (Decimal | None) – The amount to refund, or None for full refund.
- reason (str | None) – The refund reason, or None.
- metadata (CreditMetadata | None) – Optional structured metadata.
- idempotency_key (str)
- Returns: RefundResult with refund ledger entry details.
- Return type: RefundResult
revoke_credits_by_entry_type(user_id, entry_type)
Revoke credits for all transactions of a given type for a user.
- Parameters:
- user_id (str) – The user ID.
- entry_type (str) – The transaction type to revoke.
- Returns: Typed result with the revoked amount and committed balance.
- Return type: RevokeCreditsResult
spend_by_user(start, end)
Get total spend grouped by user within a date range.
- Parameters:
- start (datetime) – The range start datetime.
- end (datetime) – The range end datetime.
- Returns: List of SpendByUserRow (may be empty).
- Return type: list[SpendByUserRow]
spend_by_model(start, end)
Get total spend grouped by model within a date range.
- Parameters:
- start (datetime) – The range start datetime.
- end (datetime) – The range end datetime.
- Returns: List of SpendByModelRow (may be empty).
- Return type: list[SpendByModelRow]
top_users(limit, start, end)
Get the top users by spend within a date range.
- Parameters:
- limit (int) – Maximum number of users to return.
- start (datetime) – The range start datetime.
- end (datetime) – The range end datetime.
- Returns: List of TopUserRow (may be empty).
- Return type: list[TopUserRow]
daily_spend(start, end)
Get total spend broken down by day within a date range.
- Parameters:
- start (datetime) – The range start datetime.
- end (datetime) – The range end datetime.
- Returns: List of DailySpendRow (may be empty).
- Return type: list[DailySpendRow]
aggregate_stats(start, end)
Get aggregate usage statistics for a date range.
- Parameters:
- start (datetime) – The range start datetime.
- end (datetime) – The range end datetime.
- Returns: AggregateStats with summary statistics.
- Return type: AggregateStats
list_ledger_entries(user_id, entry_types=None, from_date=None, to_date=None, limit=50, cursor=None)
List account ledger history with a stable timestamp-plus-entry cursor.
- Parameters:
- user_id (str)
- entry_types (list *[*str ] | None)
- from_date (datetime | None)
- to_date (datetime | None)
- limit (int)
- cursor (LedgerCursor | None)
- Return type: LedgerPage
list_usage_entries(user_id, from_date=None, to_date=None, limit=50, cursor=None)
List usage ledger entries with the same cursor contract.
- Parameters:
- user_id (str)
- from_date (datetime | None)
- to_date (datetime | None)
- limit (int)
- cursor (LedgerCursor | None)
- Return type: LedgerPage
list_usage_charges(user_id, from_date=None, to_date=None, limit=50, cursor=None, include_record_only=True)
List metered usage charges, including allowance-covered events.
- Parameters:
- user_id (str)
- from_date (datetime | None)
- to_date (datetime | None)
- limit (int)
- cursor (UsageChargeCursor | None)
- include_record_only (bool)
- Return type: UsageChargePage
get_ledger_entry(user_id, entry_id)
Return one ledger entry when it belongs to the user account.
- Parameters:
- user_id (str)
- entry_id (str)
- Return type: LedgerEntry | None
create_team(owner_subject_id, name, initial_balance=Decimal('0'), *, idempotency_key)
Create a new team with an initial credit balance.
- Parameters:
- owner_subject_id (str) – Subject that owns the team.
- name (str) – The team name.
- initial_balance (Decimal) – The initial credit balance (default 0).
- idempotency_key (str) – Caller-owned replay key for this creation request.
- Returns: CreateTeamResult with team_id and name.
- Raises: StoreError – If the RPC returns no result.
- Return type: CreateTeamResult
get_team_balance(team_id)
Get the credit balance and member count for a team.
- Parameters: team_id (str) – The team ID.
- Returns:
TeamBalanceResult with balance details, or
Noneif not found. - Return type: TeamBalanceResult | None
add_team_member(team_id, user_id, role='member', spend_cap=None)
Add a member to a team with an optional spend cap.
- Parameters:
- team_id (str) – The team ID.
- user_id (str) – The user ID to add.
- role (Literal [ 'owner' , 'admin' , 'member' ]) – The member role (default “member”).
- spend_cap (Decimal | None) – The spend cap, or None for unlimited.
- Returns: AddTeamMemberResult with team_id, user_id, and role.
- Raises: StoreError – If the RPC returns no result.
- Return type: AddTeamMemberResult
get_team_members(team_id)
Get all members of a team.
- Parameters: team_id (str) – The team ID.
- Returns: List of TeamMember (may be empty).
- Return type: list[TeamMember]
remove_team_member(team_id, user_id)
Remove a team member unless they are the final owner.
- Parameters:
- team_id (str)
- user_id (str)
- Return type: bool
deduct_team(team_id, user_id, amount, metadata=None, *, idempotency_key)
Deduct credits from a team’s balance on behalf of a member.
- Parameters:
- team_id (str) – The team ID.
- user_id (str) – The user ID making the deduction.
- amount (Decimal) – The amount to deduct.
- metadata (CreditMetadata | None) – Optional structured metadata.
- idempotency_key (str) – Idempotency key threaded through metadata.
- Returns: TeamDeductionResult with ledger entry details.
- Raises: StoreError – If the RPC returns no result.
- Return type: TeamDeductionResult
sweep_expired_credits(dry_run=False, user_id=None, limit=100)
Expire at most limit eligible credit lots.
- Parameters:
- dry_run (bool)
- user_id (str | None)
- limit (int)
- Return type: SweepResult
get_bucket_balances(user_id)
Get all credit bucket balances for a user.
- Parameters: user_id (str) – The user ID.
- Returns: BucketBalancesResult with list of bucket balances and total.
- Return type: BucketBalancesResult
execute_grant_program(request)
Execute an application-driven catalog grant program.
- Parameters: request (ExecuteGrantProgramRequest)
- Return type: list[GrantProgramAwardResult]