Just want one protected view? Start with the [Flask quickstart](/docs/quickstarts?sdk=flask).

`authdog.flask` caches session context on `flask.g` and exposes a `require_auth` decorator. Other Python frameworks: [FastAPI](/docs/backend/fastapi), [Django](/docs/backend/django), [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+, Flask 3.0+, `httpx` 0.27+.

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

## Configure

```python
import os
from flask import Flask
from authdog.flask import Authdog

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

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

## Session and gate

`session()` returns a typed context from any view and caches it on `flask.g`. Repeat calls in one request do not hit `userinfo` again. `@require_auth` is the 401 boundary.

Flask drives `userinfo` with `asyncio.run` on the sync view path.

```python
@app.get("/")
def index():
    return {"authenticated": authdog.session().is_authenticated}

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

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

`logout()` (no request argument) returns a redirect `Response` that expires the cookie.

Works with blueprints as ordinary view decorators.

## Shared rules

The resolver prefers `authdog-session`, then `Authorization: Bearer <token>`. `fetch_user=False` leaves `is_authenticated` false, so the decorator rejects. Apply [authorization](/docs/concepts/authorization) after the gate.

Self-hosted identity hosts need `AUTHDOG_ALLOWED_IDENTITY_HOSTS`.
