The booking API returns room reservations on `GET /bookings`. Routes without a session return 401.

Clone [starters/fastapi](https://github.com/authdog/samples/tree/main/starters/fastapi). SDK reference: [FastAPI](/docs/backend/fastapi).

`require_auth` is the identity gate. A signed-in session is not a permission grant. Apply [authorization](/docs/concepts/authorization) after the gate.

## What you need

| Requirement | Detail |
| --- | --- |
| Public key | `pk_...` from the [console](https://console.authdog.com) |
| Environment | Copy `.env.example` to `.env` and export `PK_AUTHDOG` |
| Secret key | Never put `sk_...` in the service |
| Package | FastAPI extra is source in [authdog/web-sdk](https://github.com/authdog/web-sdk) `packages/python`. It is not the `authdog` package on PyPI. That package is the management client. Python 3.10+. Pin the checkout this sample's `requirements.txt` uses |
| Request | Hosted sign-in stays in a browser. Call `/bookings` with the `authdog-session` cookie or `Authorization: Bearer` |

## Run

```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
export PK_AUTHDOG=pk_...
uvicorn main:app --reload --port 3000
```

```bash
curl -i http://localhost:3000/bookings
curl -i http://localhost:3000/bookings -H "Authorization: Bearer <token>"
```

With a valid session the body includes `bkg_30` (Cedar, Northwind) and `bkg_31` (Birch, Contoso).

## Bookings

```python
# main.py
import os

from fastapi import Depends, FastAPI
from authdog.fastapi import Authdog

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

@app.get("/bookings")
async def bookings(user=Depends(authdog.require_auth)):
    return {
        "caller": user,
        "bookings": [
            {"id": "bkg_30", "room": "Cedar", "slot": "09:00", "guest": "Northwind"},
            {"id": "bkg_31", "room": "Birch", "slot": "13:30", "guest": "Contoso"},
        ],
    }
```

`Depends(authdog.session)` on `/` reports whether a session exists. It does not reject the request. `fetch_user=False` leaves the caller anonymous, so `require_auth` rejects.
