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
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:
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:
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 exercisesReading this page is the cheap half. These are the exercises that make you use it.
- Dependencies & Dependency Injection · Dependency BasicsIdentify what Depends calls and which value the route receives.QuizTake · EasyQuizTake · Easy
- Dependencies & Dependency Injection · Dependency Graphs & ReuseTrace composed dependencies and request-level behavior.QuizTake · MediumQuizTake · Medium
- Dependencies & Dependency Injection · Scopes, Cleanup & TestingReason about cleanup, caching, and test overrides.QuizTake · HardQuizTake · Hard
Read next
Your first FastAPI route
Build a small FastAPI endpoint and see how routes, path values, request bodies, and validation work together.
2 min
Use a database in FastAPI
Create a request-scoped database dependency, use parameterized queries, and keep transactions explicit in FastAPI routes.
2 min
Test FastAPI through HTTP
Exercise real request parsing and responses with TestClient, replace dependencies, and handle lifespan in async tests.
1 min