Skip to main content

FlexiBilling

CI PyPI Python Docs License

Billing and usage metering for Python backends. FlexiBilling tracks named balances, rates usage, applies priority rules, and records ledger entries.

The core package does not depend on a database, web framework, cache, or payment provider. Implement the async protocols in flexibilling.ports against an existing backend, or use the optional adapters.

Install

uv add flexibilling

Optional integrations:

uv add "flexibilling[redis]"
uv add "flexibilling[sqlalchemy]"
uv add "flexibilling[fastapi]"
uv add "flexibilling[all]"

Read the full documentation for backend adapters, framework integrations, operations, and releases.

Quickstart

This example charges one unit for each metered unit. When the first balance is empty, the second rule uses prepaid units.

from decimal import Decimal
from uuid import uuid4

from flexibilling import (
    AssetType,
    BillingRule,
    BillingService,
    InMemoryBillingCache,
    MetricType,
    UsageRecord,
    UsageService,
)
from flexibilling.adapters.memory import InMemoryBillingRepository

customer_id = uuid4()
repo = InMemoryBillingRepository(
    rules=[
        BillingRule(
            service=UsageService.api_request,
            target_asset=AssetType.units,
            metric_type=MetricType.units,
            conversion_rate=Decimal("1"),
        ),
        BillingRule(
            service=UsageService.api_request,
            target_asset=AssetType.prepaid_units,
            metric_type=MetricType.units,
            conversion_rate=Decimal("1"),
            priority=200,
        ),
    ]
)
cache = InMemoryBillingCache()
service = BillingService(repo, cache)

await repo.upsert_balance(
    customer_id, AssetType.units, Decimal("100"), session=object()
)
record = UsageRecord(
    id=1,
    customer_id=customer_id,
    service=UsageService.api_request,
    reference_id="request-123",
    units=12,
)
repo.records.append(record)
await service.process_record(record, session=object())

Asset and service names are open strings. AssetType and UsageService only provide a few neutral conveniences for examples; applications can define their own values without subclassing or configuring the package.

Main components

The package includes these parts:

  • flexibilling.engine rates usage, applies priority rules, and checks cached balances.
  • flexibilling.service.BillingService funds accounts, processes usage, writes ledger entries, handles charges and refunds, and updates the cache.
  • flexibilling.decorators provides requires, consumes, and billing.session(...) helpers.
  • flexibilling.ports defines the repository, usage, cache, and transaction protocols.
  • flexibilling.worker.BillingWorker processes pending usage records.
  • flexibilling.adapters.redis stores balances, period totals, and activity events in Redis.
  • flexibilling.adapters.sqlalchemy provides an async SQLAlchemy 2 repository and schema that a host can adapt.
  • flexibilling.integrations.fastapi provides optional middleware and HTTP 402 helpers.

Payment identifiers are opaque strings. BillingService.fund_customer maps them to asset grants and ignores a payment reference that it has already processed. Monthly-quota products replace a balance. Top-ups add to it.

For an existing database, implement BillingRepository and UsageRepository against the current models. The SQLAlchemy adapter shows one possible schema; it is not required.

Documentation

Usage sessions

from flexibilling import BillingDecorators, UsageService

billing = BillingDecorators(service=service, usage_repository=usage_repo)

async with billing.session(
    customer_id=customer_id,
    service=UsageService.api_request,
    variant="standard",
    reference_id="request-123",
) as usage:
    usage.report(units=12)

The session writes one pending usage record when it reports usage. It stores reported duration in event_metadata["duration_seconds"], so a rule can bill elapsed time without depending on the host framework. Set write_on_exception=False when failed operations should not create a record.

Development

uv sync --group testing --group lint --group dev
uv run pre-commit install
uv run pytest
uv run ruff check src tests examples
uv run ruff format src tests examples --check
uv run pyright --project pyproject.toml src/flexibilling
uv build
uv run mkdocs build --strict

CI runs lint and type checks, tests Python 3.11 through 3.14, and builds the distribution. A GitHub release publishes to PyPI through trusted publishing.

License

Apache-2.0. See LICENSE.

Metadata

Release files for flexibilling 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 flexibilling 0.1.0
File Size Uploaded
flexibilling-0.1.0.tar.gz 39.5 kB Details

Built distribution (wheel)

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

Total release size: 79.5 kB

Release files / flexibilling-0.1.0.tar.gz

Download URL flexibilling-0.1.0.tar.gz
Size 39.5 kB
Tags Source
SHA-256 checksum
How to use checksums
8ebd9da1069a6353d308250090b1a6219d3faacde8a237a54dcb8a3c6ca8e311
BLAKE2b-256 checksum
How to use checksums
e1a0d106920fffb05a27e1da5574b51e67b692e4ec3fb3bc2306e539f2738b20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 25, 2026.

Transparency log

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

Download URL flexibilling-0.1.0-py3-none-any.whl
Size 40.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f2ca72533d353816d3996e48ac868bf16a509bd9de0d8c25fb0a54439f2a2a50
BLAKE2b-256 checksum
How to use checksums
439329ffac5f7a6c4a7b540ec88c70aee7a05d79d7997d043e111fcf57f2748f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Aug 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

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