New: `ffroute.FFAPIRouter` — the dynamic FFRouter × APIRouter mixin that `speedup()` synthesized at runtime is now a real importable top-level class.
```python
from fastapi import FastAPI
from ffroute import FFAPIRouter
app = FastAPI()
... register routes ...
new_router = FFAPIRouter()
new_router.routes.extend(app.router.routes)
app.router = new_router
app.router._rebuild_index()
```
Why this matters
`FFAPIRouter` is the static type that backs an upcoming proposal to add a `router_class=` kwarg to `Starlette.init` and `FastAPI.init`. Once that lands upstream, the snippet above collapses to:
```python
app = FastAPI(router_class=FFAPIRouter)
```
Shipping the class now (in advance of the upstream PR) lets the proposal cite a real consumer.
Install
```bash
pip install 'ffroute[fastapi]'
```
(Or `uv add 'ffroute[fastapi]'`.) FastAPI is pulled in as a lazy optional dependency — `from ffroute import Router` / `FFRouter` still works without FastAPI installed.
Tests
3 new verification tests (importability + drop-in via assignment + works-without-speedup-call). `speedup()` itself is unchanged — the dynamic-mixin path stays as a fallback for arbitrary user-supplied router subclasses.
Migration
No breaking changes. Existing `speedup(app)` callers keep working unchanged.