The Authdog Python SDK validates sessions for **FastAPI, Django, Flask, Starlette, and aiohttp**. Every binding exposes the same `Authdog` client — a session resolver, a `require_auth` gate, and a `logout` handler — with idiomatic wiring per framework. For the model behind it, see [Backend requests](/docs/backend).

## Install

```bash
pip install authdog-fastapi
```

The pip package is `authdog-fastapi`; the importable module is `authdog`, with framework bindings as submodules (`authdog.fastapi`, `authdog.flask`, `authdog.django`, `authdog.starlette`, `authdog.aiohttp`). Install the extra for your framework, e.g. `pip install authdog-fastapi[flask]`.

## Configure

Construct the client once with your environment's **public key** (`pk_...`). It's validated at construction, so a bad key fails at startup:

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

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

Pass `fetch_user=False` to skip the `userinfo` round-trip when you only need to detect a token. For self-hosted identity, allowlist hosts with the `AUTHDOG_ALLOWED_IDENTITY_HOSTS` environment variable (comma-separated).

## FastAPI

`require_auth` is a dependency that rejects unauthenticated requests with `HTTPException(401, "Unauthorized")`:

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

app = FastAPI()

@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)
```

Read the session without enforcing with `Depends(authdog.session)`, which returns an `AuthdogContext`.

## Django

```python
from authdog.django import Authdog

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

@authdog.require_auth
def me(request):
    return JsonResponse(authdog.session(request).user)
```

`authdog.logout(request)` returns an `HttpResponseRedirect`, and `authdog.middleware(get_response)` resolves the session for every request.

## Flask

```python
from authdog.flask import Authdog

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

@app.get("/me")
@authdog.require_auth
def me():
    return authdog.session().user
```

`authdog.session()` caches the resolved context on `flask.g`; `authdog.logout()` returns a `Response`.

## The session context

Every binding resolves an `AuthdogContext`, which never raises:

```python
{
  "token": str | None,
  "user": Any | None,
  "is_authenticated": bool,
  "user_info": dict | None,
}
```

Resolving a session tells you *who* the caller is — pair it with your environment's [authorization](/docs/concepts/authorization) model to decide *what* they can do. For a full RBAC layer on FastAPI, see the [Python access-control guide](/guides/python/access-control).

## Service-to-service

Machine-to-machine callers send their token as `Authorization: Bearer <token>`; it resolves on the same path as a browser session. See [Backend requests](/docs/backend#service-to-service-m2m).

## Next steps

- [Backend requests](/docs/backend) — the verification model across every backend SDK.
- [Python guides](/guides/python/authentication) — end-to-end authentication and access control on FastAPI.
- [Calling the REST API](/docs/api) — read users and organizations once a request is authenticated.
