Outcome: a Django view that returns 401 unless Authdog authenticates the caller. About five minutes.

**Unreleased:** not on PyPI. Install from the public source tree.

0. Prerequisites: Python 3.10+, Django 4.2+, and an Authdog environment.

## 1. Create an environment and copy the public key

In the [console](https://console.authdog.com), create a tenant → project → environment and copy **Public key** from **Dashboard**. Details: [Environments](/docs/console/environments).

## 2. Install from source

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

Pin [`packages/python`](https://github.com/authdog/web-sdk/tree/main/packages/python).

## 3. Set the env var

```bash
export PK_AUTHDOG="pk_..."
```

## 4. Create the client and register middleware

```python
# auth.py
import os
from authdog.django import Authdog

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

```python
# settings.py
MIDDLEWARE = [
    # ...
    "myapp.auth.authdog.middleware",
]
```

## 5. Protect one view

```python
from django.http import JsonResponse

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

## 6. Verify

`GET` the view without a session → 401. With a valid cookie or bearer token from hosted sign-in → user JSON.

If it fails: middleware path wrong; `PK_AUTHDOG` from another environment; decorated without middleware (session still resolves, but register middleware so the context is shared).

## Next

The [Django guide](/docs/backend/django) covers logout and `request.authdog_context`. Other Python frameworks: [FastAPI](/docs/quickstarts?sdk=fastapi), [Flask](/docs/quickstarts?sdk=flask), [Starlette](/docs/quickstarts?sdk=starlette), [aiohttp](/docs/quickstarts?sdk=aiohttp).
