Metadata-Version: 2.4
Name: mgf-fastapi
Version: 0.1.0
Summary: FastAPI integration adapters for mgf-common — request-id + exception translation + lifespan + webhooks (Svix HMAC) + IpAllowlist + run_test_app. Sibling of mgf-common under the mgf.* namespace.
Project-URL: Homepage, https://codeberg.org/magogi-admin/mgf-fastapi
Project-URL: Issues, https://codeberg.org/magogi-admin/mgf-fastapi/issues
Project-URL: Changelog, https://codeberg.org/magogi-admin/mgf-fastapi/src/branch/master/CHANGELOG.md
Author: Bassam Alsanie, mgf-fastapi contributors
License: MIT
License-File: LICENSE
Keywords: fastapi,ip-allowlist,middleware,request-id,svix,webhooks
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.110
Requires-Dist: mgf-common<0.29,>=0.28
Provides-Extra: dev
Requires-Dist: httpx>=0.27; extra == 'dev'
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: import-linter>=2.0; extra == 'dev'
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: uvicorn>=0.30; extra == 'dev'
Provides-Extra: testing
Requires-Dist: httpx>=0.27; extra == 'testing'
Requires-Dist: uvicorn>=0.30; extra == 'testing'
Description-Content-Type: text/markdown

# `mgf-fastapi` — FastAPI integration adapters for mgf-common

[![PyPI](https://img.shields.io/pypi/v/mgf-fastapi)](https://pypi.org/project/mgf-fastapi/)
[![Python](https://img.shields.io/pypi/pyversions/mgf-fastapi)](https://pypi.org/project/mgf-fastapi/)

> **Sibling of [`mgf-common`](https://pypi.org/project/mgf-common/)
> under the `mgf.*` namespace.** Houses every FastAPI-specific
> adapter that previously lived under `mgf.common.fastapi.*` —
> extracted at mgf-common v0.28 / mgf-fastapi v0.1 per the
> [federation split plan](https://codeberg.org/magogi-admin/mgf_common/src/branch/master/docs/release/federation_roadmap.md).

## What this provides

| Submodule | What |
|---|---|
| `mgf.fastapi` | `bootstrap` ↔ FastAPI lifespan; `RequestIdMiddleware`; `ExceptionTranslationMiddleware`; `Depends()` helpers (`get_app_context`, `get_settings`, `get_request_id`); `setup_lifespan`. |
| `mgf.fastapi.webhooks` | Svix-shape HMAC webhook verification (`HmacWebhookVerifier`, `WebhookHeaderSchema`, `SVIX_SCHEMA`, `verify_request`). |
| `mgf.fastapi.security` | `IpAllowlist` FastAPI dependency with proxy-trust opt-in. |
| `mgf.fastapi.testing` | `run_test_app` async context manager — start uvicorn for a FastAPI app on a free port; yield base URL; clean shutdown. |
| `mgf.fastapi.exceptions` | `HmacVerificationError(HttpUnauthorized)` and other framework-domain concrete leaves. (HTTP-01 hierarchy roots stay in `mgf.common.exceptions`.) |

## Install

```bash
pip install mgf-fastapi
# Or with the test-helper extra (uvicorn + httpx for run_test_app):
pip install 'mgf-fastapi[testing]'
```

Pulls in `mgf-common` and `fastapi` automatically.

## Quick start

```python
from fastapi import FastAPI, Request
from mgf.fastapi import (
    ExceptionTranslationMiddleware,
    RequestIdMiddleware,
    setup_lifespan,
)
from mgf.fastapi.webhooks import HmacWebhookVerifier, verify_request

app = FastAPI(lifespan=setup_lifespan(app_name="my-service", app_version="0.1.0"))
app.add_middleware(ExceptionTranslationMiddleware)
app.add_middleware(RequestIdMiddleware)

webhook = HmacWebhookVerifier(secret=settings.webhook_secret)

@app.post("/webhooks/clerk")
async def clerk_webhook(request: Request) -> dict:
    event_id, ts = await verify_request(request, webhook)
    payload = await request.json()
    # ... process the (now-trusted) payload ...
    return {"ok": True}
```

## Documentation

- [`docs/recipes/fastapi.md`](docs/recipes/fastapi.md) — full FastAPI service walkthrough.
- [`docs/recipes/webhooks.md`](docs/recipes/webhooks.md) — HMAC webhook verification.
- [`docs/cutover/v0.1.0.md`](docs/cutover/v0.1.0.md) — maiden voyage migration story (the v0.28 split).
- [`PUBLIC_API.md`](PUBLIC_API.md) — full public surface contract.
- [`CHANGELOG.md`](CHANGELOG.md) — release history.

For the federation-wide engineering standards (DESIGN_PRINCIPLES,
ERROR_HANDLING, SECURITY, etc.) see
[`mgf-common/docs/standards/`](https://codeberg.org/magogi-admin/mgf_common/src/branch/master/docs/standards/).
This sibling inherits them by reference; the standards source-of-truth
lives in mgf-common.

## Status

🚧 **Experimental** — every public name is `experimental` per AP-09.
Promotion to `stable` happens release-by-release as consumer feedback
in [`FEEDBACK.md`](FEEDBACK.md) converges. The 0.x window applies.
Pin tightly: `mgf-fastapi = ">=0.X.0,<0.Y"`.

## Cross-references

- **Filing process for sharp edges**: open an entry on
  [`mgf-common/FEEDBACK.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/master/FEEDBACK.md)
  with `[mgf-fastapi]` prefix, OR file directly on this repo's
  Issues → maintainer mirrors into the canonical FEEDBACK.md.
- **Federation pattern**:
  [`mgf-common/docs/design/federation.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/master/docs/design/federation.md).
- **The split that created this sibling**:
  [`mgf-common/docs/release/federation_roadmap.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/master/docs/release/federation_roadmap.md).
