API reference

The public surface of gringotts. Import everything from the top-level package:

from gringotts import init_app, charge, GringottsConfig, CreditPack, grant

Setup

gringotts.init_app(app, config=None)[source]

Register the 402 handler and mount the gringotts routes.

Routes (balance, usage, account, purchase page, checkout, webhook, admin) land under config.mount_path.

Parameters:
  • app (FastAPI) – The FastAPI application to wire gringotts into.

  • config (GringottsConfig | None) – Settings; a default GringottsConfig (no packs, Stripe off) is used when omitted.

Return type:

None

Example

>>> from fastapi import FastAPI
>>> import gringotts
>>> from gringotts import GringottsConfig, CreditPack
>>> app = FastAPI()
>>> gringotts.init_app(
...     app,
...     GringottsConfig(
...         packs=[CreditPack(credits=100, price_cents=500, name="Starter")]
...     ),
... )
class gringotts.GringottsConfig(packs=<factory>, stripe_secret_key=None, stripe_webhook_secret=None, success_url=None, cancel_url=None, mount_path='/gringotts', idempotency_enabled=True, idempotency_header='Idempotency-Key', idempotency_max_key_length=255, idempotency_max_body_bytes=1000000, idempotency_max_response_bytes=1000000, idempotency_retention_seconds=86400.0, idempotency_replay_validator=None)[source]

Settings for the mounted routes and Stripe integration.

Stripe keys fall back to the STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET environment variables when not set explicitly.

Parameters:
  • packs (list[CreditPack])

  • stripe_secret_key (str | None)

  • stripe_webhook_secret (str | None)

  • success_url (str | None)

  • cancel_url (str | None)

  • mount_path (str)

  • idempotency_enabled (bool)

  • idempotency_header (str)

  • idempotency_max_key_length (int)

  • idempotency_max_body_bytes (int)

  • idempotency_max_response_bytes (int)

  • idempotency_retention_seconds (float)

  • idempotency_replay_validator (Callable[[dict], bool] | None)

packs

Credit packs offered for sale. Empty disables purchasing; all packs must share one currency.

Type:

list[gringotts.config.CreditPack]

stripe_secret_key

Stripe secret key (or STRIPE_SECRET_KEY env). Required, with packs, to enable Checkout.

Type:

str | None

stripe_webhook_secret

Stripe webhook signing secret (or STRIPE_WEBHOOK_SECRET env). Required to accept webhooks.

Type:

str | None

success_url

Where Checkout returns on success; defaults to the buy page with ?status=success.

Type:

str | None

cancel_url

Where Checkout returns on cancel; defaults to the buy page with ?status=cancelled.

Type:

str | None

mount_path

URL prefix the routes mount under (default /gringotts).

Type:

str

idempotency_enabled

Whether to install the response-caching idempotency middleware so an Idempotency-Key header makes a request safe to retry (default True).

Type:

bool

idempotency_header

The header carrying the idempotency key (default "Idempotency-Key").

Type:

str

idempotency_max_key_length

Reject a key longer than this with 400 (default 255).

Type:

int

idempotency_max_body_bytes

A keyed request whose body exceeds this is rejected with 413 before the app runs (default 1_000_000).

Type:

int

idempotency_max_response_bytes

A response larger than this is streamed to the client but replays a marker rather than the body (default 1_000_000).

Type:

int

idempotency_retention_seconds

A stored record older than this is treated as expired — a reused key re-runs, bounding table growth and key lifetime (default 86_400).

Type:

float

idempotency_replay_validator

Synchronous callback receiving the ASGI scope before a host-application response is replayed. Return True only after revalidating any mutable host authorization. Without one, host retries stay safe but return 409 instead of cached response data.

Type:

collections.abc.Callable[[dict], bool] | None

property stripe_enabled: bool

Whether credit purchases are possible (packs plus a Stripe key).

class gringotts.CreditPack(credits, price_cents, name, currency='usd')[source]

A purchasable bundle of credits sold through Stripe Checkout.

Parameters:
credits

How many credits the buyer receives. Must be positive.

Type:

int

price_cents

The price in the currency’s smallest unit — cents for USD, whole yen for JPY and other zero-decimal currencies.

Type:

int

name

Human-readable pack name shown on the buy page and in Checkout.

Type:

str

currency

ISO currency code (default "usd"). All packs in one GringottsConfig must share a currency.

Type:

str

Charging

gringotts.charge(cost)[source]

Build the dependency that authenticates and charges for a request.

The dependency yields the charged user; if the endpoint raises, the charge is refunded with a compensating ledger entry.

Parameters:

cost (int | Callable[[Request], int]) – Credits to charge — an int, or a callable computing it from the request (e.g. per-unit pricing).

Returns:

A FastAPI dependency usable as Depends(charge(5)).

Return type:

Callable[[…], Iterator[User]]

Example

>>> from fastapi import Depends
>>> from gringotts import CreditedUser, charge
>>> @app.post("/predict")
... def predict(user: CreditedUser = Depends(charge(1))):
...     return {"credits_left": user.credits}
gringotts.grant(db, user, amount, kind='grant', external_id=None, amount_cents=None, payment_intent_id=None, currency=None)

Atomically add credits with a ledger row.

Returns False when external_id was already processed, making event-driven crediting (Stripe webhooks) idempotent. A negative amount raises ValueError, since a grant must never deduct. HTTP-level safe-retry for the admin grant route is handled by IdempotencyMiddleware.

Parameters:
  • db (Session)

  • user (User)

  • amount (int)

  • kind (str)

  • external_id (str | None)

  • amount_cents (int | None)

  • payment_intent_id (str | None)

  • currency (str | None)

Return type:

bool

gringotts.CreditedUser

alias of User

Errors

class gringotts.PaymentRequiredError(cost, balance)[source]

Raised when a key has too few credits.

init_app registers a handler that renders the machine-readable 402 body; without it, FastAPI’s default HTTPException handler still returns a 402 with the plain-text detail.

Parameters:
class gringotts.InvalidAPIKeyError[source]

Raised when the X-API-Key header is missing or matches no user (401).

Wiring (advanced)

init_app handles wiring for you. These are exposed only for hosts that want to share gringotts’ database session:

gringotts.get_session()[source]

FastAPI dependency yielding a session that is always closed after use.

Return type:

Iterator[Session]

  • gringotts.SessionLocal — the SQLAlchemy sessionmaker bound to the configured database (DATABASE_URL).

  • gringotts.engine — the SQLAlchemy Engine for that database (WAL and a busy timeout are applied automatically for SQLite).

  • gringotts.Base — the declarative base gringotts’ models attach to.