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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flexibilling-0.1.0.tar.gz (39.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flexibilling-0.1.0-py3-none-any.whl (40.0 kB view details)

Uploaded Python 3

File details

Details for the file flexibilling-0.1.0.tar.gz.

File metadata

  • Download URL: flexibilling-0.1.0.tar.gz
  • Upload date:
  • Size: 39.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flexibilling-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8ebd9da1069a6353d308250090b1a6219d3faacde8a237a54dcb8a3c6ca8e311
MD5 2d10a8a6f6ab8909f81887267f4c1ff2
BLAKE2b-256 e1a0d106920fffb05a27e1da5574b51e67b692e4ec3fb3bc2306e539f2738b20

See more details on using hashes here.

Provenance

The following attestation bundles were made for flexibilling-0.1.0.tar.gz:

Publisher: release_pypi.yaml on arterialist/flexibilling-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flexibilling-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: flexibilling-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 40.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for flexibilling-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f2ca72533d353816d3996e48ac868bf16a509bd9de0d8c25fb0a54439f2a2a50
MD5 43544092be8ea524c271a99bda6c7144
BLAKE2b-256 439329ffac5f7a6c4a7b540ec88c70aee7a05d79d7997d043e111fcf57f2748f

See more details on using hashes here.

Provenance

The following attestation bundles were made for flexibilling-0.1.0-py3-none-any.whl:

Publisher: release_pypi.yaml on arterialist/flexibilling-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 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