Just want one protected view? Start with the Django quickstart.
authdog.django is middleware plus a require_auth view decorator. Other Python frameworks: FastAPI, Flask, Starlette, aiohttp. Hub: Python.
Availability and install
Unreleased on PyPI. Source-only in `packages/python`. Python 3.10+, Django 4.2+, httpx 0.27+.
python -m pip install "./packages/python[django]"import authdog.django is lazy: Django does not need to be configured until a binding is called.
Configure
# auth.py
import os
from authdog.django import Authdog
authdog = Authdog(public_key=os.environ["PK_AUTHDOG"])# settings.py
MIDDLEWARE = [
# ...
"myapp.auth.authdog.middleware",
]The public key is publishable. Construction rejects malformed keys and identity hosts outside the trusted HTTPS allowlist.
Session and gate
Middleware puts a resolved context on request.authdog_context. It never raises. session(request) reads that context from any view. @require_auth is the 401 boundary (JsonResponse({"error": "Unauthorized"}, status=401)).
Django drives userinfo with asyncio.run on the sync view path.
from django.http import JsonResponse
@authdog.require_auth
def me(request):
return JsonResponse(authdog.session(request).user)
def logout(request):
return authdog.logout(request)Middleware, decorator, and session() share one resolved context per request.
Shared rules
The resolver prefers authdog-session, then Authorization: Bearer <token>. fetch_user=False leaves is_authenticated false, so the decorator rejects. Apply authorization after the gate.
Self-hosted identity hosts need AUTHDOG_ALLOWED_IDENTITY_HOSTS.