codejump

Share logic with FastAPI dependencies

Use Depends to reuse request parsing and resource setup, compose dependencies, and replace them in tests.

1 min readUpdated

3 exercises

Waiting at the end of this page.

Key takeaways

  • Pass a callable to Depends; FastAPI calls it while resolving each request and injects its result.
  • Dependencies can read request values and can depend on other dependencies.
  • A dependency with yield can release a resource after use, and tests can override the callable.

Extract shared request logic

When two routes need the same validated query values, define them once as a dependency:

python
from typing import Annotated
from fastapi import Depends, FastAPI, Query

app = FastAPI()

def pagination(limit: Annotated[int, Query(ge=1, le=50)] = 10):
    return limit

@app.get("/books")
def list_books(limit: Annotated[int, Depends(pagination)]):
    return {"limit": limit}

Pass pagination, not pagination(). FastAPI inspects the callable, reads its query parameter, validates it, calls the dependency, then passes the result to the route. A dependency can itself declare Depends(...); FastAPI resolves the graph. Shared subdependencies are cached for the duration of one request by default.

Run a check without using its return value

If the route only needs a prerequisite to run, place it on the decorator: @app.get("/private", dependencies=[Depends(check_key)]). FastAPI still executes check_key and stops the route if it raises HTTPException, but does not add a parameter to your handler.

Manage a request resource

A dependency with yield can acquire a resource and close it after the request uses it:

python
from collections.abc import Iterator
from sqlite3 import Connection, connect

def get_db() -> Iterator[Connection]:
    db = connect("books.db")
    try:
        yield db
    finally:
        db.close()

The cleanup runs even when the route raises. The default request scope closes a yielded dependency after the response is sent. If the resource only needs to live through the route function, FastAPI also supports Depends(get_db, scope="function") in versions that provide dependency scopes.

Replace dependencies in tests

The callable is also a test seam: app.dependency_overrides[get_db] = fake_db makes routes that depend on get_db receive a test resource. Clear overrides after the test, preferably in a fixture teardown, so one test cannot affect another.

Now practice it

3 exercises

Reading this page is the cheap half. These are the exercises that make you use it.