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

[![Registry](https://img.shields.io/badge/registry-Codeberg-blue)](https://codeberg.org/magogi-admin/mgf-fastapi)
[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://codeberg.org/magogi-admin/mgf-fastapi)

> **Shape:** Federation sibling of `mgf-common`. The current
> `mgf-common` pin window is shown in this package's
> [Codeberg registry](https://codeberg.org/magogi-admin/mgf-fastapi) —
> sourced from `pyproject.toml` at release time, so this README
> can't go stale. (Per v2.6 DOC-01 / project-shape taxonomy.
> PAPER-38.)
>
> **Sibling of [`mgf-common`](https://codeberg.org/magogi-admin/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/main/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-standard/docs/standards/`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/).
This sibling inherits them by reference; the standards source-of-truth
lives in mgf-common.

> **Conformance: targets L2** per [`mgf-standard/docs/standards/`](https://codeberg.org/magogi-admin/mgf-standard/src/branch/main/docs/standards/) — below L2 today, with open **MUST** gaps tracked in the per-rule audit ledger: [`docs/inprogress/MGF_STANDARDS_CONFORMANCE.md`](docs/inprogress/MGF_STANDARDS_CONFORMANCE.md). L2 means every federation **MUST** rule applies; reaching it requires closing the gaps the ledger still lists.

## 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/main/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/main/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/main/docs/release/federation_roadmap.md).
