# Dependency Injection With Depends — Django / FastAPI

Source: https://www.skillbyai.com/en/django-fastapi/f-depends

> Reusable request logic.

## Auth, pagination, database sessions

`Depends()` declares that an endpoint needs the result of another function: the current user from a token, a database session, pagination parameters, settings. Dependencies can have their own dependencies and parameters (headers, queries), raise `HTTPException` to stop a request (401, 403), and use `yield` to clean up resources such as database sessions after the response. The `Annotated[type, Depends(fn)]` style keeps signatures clear and reusable.

## Authentication and capped pagination as dependencies, run

I ran this with Python 3.12, FastAPI 0.142.2, Pydantic 2.13 and Starlette 1.7, calling the app through FastAPI's TestClient (no server needed). Without a header the dependency returns 401; with a wrong token, 403; with a valid token the user is resolved and the requested limit of 500 is capped to 50.

```python
from typing import Annotated
from fastapi import Depends, FastAPI, Header, HTTPException
from fastapi.testclient import TestClient

TOKENS = {"secret-asha": "asha"}

def current_user(authorization: Annotated[str | None, Header()] = None) -> str:
    if not authorization or not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Missing bearer token")
    user = TOKENS.get(authorization.removeprefix("Bearer "))
    if user is None:
        raise HTTPException(status_code=403, detail="Invalid token")
    return user

def pagination(limit: int = 10, offset: int = 0) -> dict:
    return {"limit": min(limit, 50), "offset": offset}       # reusable, capped

app = FastAPI()

@app.get("/orders")
def orders(user: Annotated[str, Depends(current_user)],
           page: Annotated[dict, Depends(pagination)]):
    return {"user": user, **page}

client = TestClient(app)
print(client.get("/orders").status_code, client.get("/orders").json())
print(client.get("/orders", headers={"Authorization": "Bearer nope"}).json())
print(client.get("/orders?limit=500", headers={"Authorization": "Bearer secret-asha"}).json())
```

Output:

```
401 {'detail': 'Missing bearer token'}
{'detail': 'Invalid token'}
{'user': 'asha', 'limit': 50, 'offset': 0}
```

## Use yield dependencies for sessions

A dependency that yields a database session and closes it afterwards guarantees cleanup even when the endpoint raises.

**Quiz:** How does a dependency reject an unauthenticated request?

- [ ] By returning None silently
- [x] By raising HTTPException with status 401
- [ ] By printing a warning
- [ ] By crashing the server

*Answer:* By raising HTTPException with status 401. Dependencies can short-circuit requests.
