Just want one protected route? Start with the [FastAPI quickstart](/docs/quickstarts?sdk=fastapi).

`authdog.fastapi` exposes session context and a 401 gate as FastAPI dependencies. Other Python frameworks have their own guides: [Django](/docs/backend/django), [Flask](/docs/backend/flask), [Starlette](/docs/backend/starlette), [aiohttp](/docs/backend/aiohttp). Hub: [Python](/docs/backend/python).

## Availability and install

**Unreleased on PyPI.** Source-only in [`packages/python`](https://github.com/authdog/web-sdk/tree/main/packages/python). Python 3.10+, FastAPI 0.110+, `httpx` 0.27+.

```bash
python -m pip install "./packages/python[fastapi]"
```

Pin a commit. Published compatibility is not yet guaranteed.

## Configure

```python
import os
from authdog.fastapi import Authdog

authdog = Authdog(public_key=os.environ["PK_AUTHDOG"])
```

The key is publishable. Construction rejects malformed keys and identity hosts outside the trusted HTTPS allowlist.

## Session and gate

`session` is optional context. `require_auth` is the 401 dependency. Context is cached on `request.state`, so composing both costs one `userinfo` call.

```python
from fastapi import Depends, FastAPI, Request

app = FastAPI()

@app.get("/")
async def index(ctx=Depends(authdog.session)):
    return {"authenticated": ctx.is_authenticated}

@app.get("/me")
async def me(user=Depends(authdog.require_auth)):
    return user

@app.get("/logout")
async def logout(request: Request):
    return authdog.logout(request)
```

`logout(request)` expires the cookie and redirects to a sanitized `redirect_uri`.

## Shared rules

The resolver prefers `authdog-session`, then `Authorization: Bearer <token>`. Failed `userinfo` is anonymous. `fetch_user=False` leaves `is_authenticated` false, so `require_auth` rejects. Authentication is not authorization — apply [authorization](/docs/concepts/authorization) after the gate.

Self-hosted identity hosts need `AUTHDOG_ALLOWED_IDENTITY_HOSTS`.
