Skip to main content

MicroAuth SDK for FastAPI

API key authentication, per-customer rate limiting and metered billing for your FastAPI API — powered by your MicroAuth tenant, in one dependency.

from fastapi import FastAPI, Security
from microauth_fastapi import MicroAuth, Customer

app = FastAPI()
auth = MicroAuth(app)  # tenant secret from MICROAUTH_SECRET_KEY

@app.get("/forecast")
async def forecast(customer: Customer = Security(auth)):
    return {"hello": customer.id}

That's the whole integration. Your customers sign up on your MicroAuth developer portal, create API keys, pick a plan or top up credits — and every request to /forecast is now authenticated, rate-limited and billed.

What it does

  • API key auth via the X-API-Key header (configurable), including the security scheme in your OpenAPI docs — the Swagger "Authorize" button just works.
  • Suspension, balance and quota enforcement — suspended customers get 403, customers who ran out of prepaid credit get 402, customers over their monthly quota get 429.
  • Per-customer rate limiting at each customer's effective RPS (custom override → plan → pay-as-you-go default), 429 with Retry-After.
  • Metered billing — responses with a billable status code (you choose them in your tenant settings; default 200 only) are counted per API key and reported to MicroAuth in efficient batches.

Designed for the hot path

The SDK never calls MicroAuth while serving a request:

  • A snapshot of your customers, keys and limits is cached in memory and refreshed in the background (default every 30s).
  • Keys not in the snapshot yet (created seconds ago) are resolved once via a single-flight on-demand lookup; invalid keys are negatively cached so a flood of bad keys can't reach MicroAuth.
  • Usage is aggregated in memory (one counter per key per hour) and flushed in the background (default every 15s), surviving MicroAuth outages with buffering and retries.
  • Authentication itself is a SHA-256 and a couple of dict lookups.

If MicroAuth is briefly unreachable, your API keeps serving with the last known data (fail_open=True, the default). Set fail_open=False if you'd rather return 503 once the snapshot is older than max_snapshot_age.

Multiple workers? Add Redis

In-memory rate limiting is per-process: with 4 uvicorn workers a customer could reach ~4× their RPS. If that matters to you, point the SDK at Redis and limits are enforced exactly across every worker and machine:

auth = MicroAuth(app, redis_url="redis://localhost:6379/0")
pip install 'microauth-fastapi[redis]'

One Redis round trip per request (pipelined INCR+EXPIRE), and if Redis goes down the limiter fails open so your API stays up.

Billing does not need Redis: each worker reports its own counts and MicroAuth sums them idempotently per hour bucket.

Optional authentication

For endpoints that serve both anonymous and authenticated traffic:

@app.get("/status")
async def status(customer: Customer | None = Security(auth.optional)):
    return {"authenticated": customer is not None}

Settings

Everything has a sensible default; override only what you need.

Setting Default What it does
secret_key $MICROAUTH_SECRET_KEY Tenant secret key (mas_...)
base_url https://api.microauth.com MicroAuth API ($MICROAUTH_BASE_URL)
header_name X-API-Key Header customers send their key in
redis_url $MICROAUTH_REDIS_URL Enable exact cross-worker rate limiting
sync_interval 30 Seconds between snapshot refreshes
report_interval 15 Seconds between usage report flushes
max_snapshot_age 300 Staleness threshold for fail_open
fail_open True Keep serving with stale data vs. 503
enforce_balance True 402 when prepaid credit is exhausted
enforce_quota True 429 when the monthly quota is used up
enforce_rps True Per-customer RPS limiting
verify_negative_ttl 30 Seconds an invalid key is cached
timeout 5 HTTP timeout for MicroAuth calls

Error responses

Status When
401 Missing or invalid API key
402 Prepaid balance exhausted
403 Customer suspended
429 RPS limit (Retry-After header) or monthly quota exceeded
503 Only with fail_open=False and stale data

All of these subclass microauth_fastapi.AuthDenied (itself a FastAPI HTTPException), so you can add your own exception handler to reshape the response bodies.

Consistency notes (the honest fine print)

  • Balance and quota enforcement use the cached snapshot plus locally counted activity, corrected on every refresh. A customer racing their last credits across many workers can overshoot by at most ~one sync_interval of traffic — the industry-standard tradeoff that keeps your latency flat.
  • A crashed worker loses at most report_interval seconds of unreported usage. Graceful shutdowns flush everything.
  • Suspensions and key revocations propagate within one sync_interval (30s by default) to every worker.

Example app

See examples/weather_api.py:

MICROAUTH_SECRET_KEY=mas_... uvicorn examples.weather_api:app --reload

Metadata

Release files for microauth-fastapi 2.0.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 microauth-fastapi 2.0.0
File Size Uploaded
microauth_fastapi-2.0.0.tar.gz 15.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for microauth-fastapi 2.0.0
File Interpreter ABI Platform
microauth_fastapi-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.5 kB

Release files / microauth_fastapi-2.0.0.tar.gz

Download URL microauth_fastapi-2.0.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
3a43dc9d17e43c2b0f8559e7cf8a645e9cf1f1a456a17e0d2c3d34a7b187248c
BLAKE2b-256 checksum
How to use checksums
760bd71fe4fa2e935103a2274d0ca8c03627c36669dfaca7f696ab40915a4050
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 3, 2026.

Transparency log

Release files / microauth_fastapi-2.0.0-py3-none-any.whl

Download URL microauth_fastapi-2.0.0-py3-none-any.whl
Size 15.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fc1db60ed346c16b9e89dadff2224c7b9a073a9efee17c61d1743c80a4677805
BLAKE2b-256 checksum
How to use checksums
3d9f261ac3e6ad1bcdeb1ab604fca74c3eb152cffe79f725fef0035d129d115f
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 3, 2026.

Transparency log

Release history Release notifications | RSS feed

3.0.0

2 release files

2.8.1

2 release files

2.8.0

2 release files

2.7.0

2 release files

2.6.0

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.0

2 release files

This release

2.0.0 This release

2 release files

1.0.0

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