Outcome: a Starlette route that returns 401 unless `require_auth` succeeds. About five minutes.

This is **pure Starlette**. FastAPI has a [separate quickstart](/docs/quickstarts?sdk=fastapi).

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

0. Prerequisites: Python 3.10+, Starlette 0.37+, 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[starlette]"
```

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

## 3. Set the env var

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

## 4. Construct the client

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

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

## 5. Protect one route

```python
from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route

async def me(request):
    user = await authdog.require_auth(request)
    return JSONResponse(user)

app = Starlette(
    routes=[Route("/me", me)],
    middleware=[authdog.middleware],
)
```

## 6. Verify

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

If it fails: forgot `authdog.middleware`; used FastAPI `Depends` instead of `await require_auth`; wrong environment key.

## Next

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