Sub-Dependencies
One of the most powerful features of FastAPI’s dependency injection system is the ability to create sub-dependencies - dependencies that themselves have dependencies. This allows you to build complex, modular systems with clean separation of concerns.What are Sub-Dependencies?
A sub-dependency is simply a dependency that usesDepends() in its own parameters. FastAPI automatically resolves the entire dependency tree, executing everything in the correct order.
FastAPI builds a complete dependency graph internally using the
Dependant model, which tracks all sub-dependencies through its dependencies field (see fastapi/dependencies/models.py:38).Basic Sub-Dependency Example
Here’s a simple example from the FastAPI source:How It Works
1
Request arrives
A request comes in to
/items/?q=test2
FastAPI resolves dependencies
FastAPI sees that
read_query depends on query_or_cookie_extractor3
Sub-dependency is resolved first
Before calling
query_or_cookie_extractor, FastAPI sees it depends on query_extractor and calls that first4
Values flow up the chain
The result from
query_extractor is passed to query_or_cookie_extractor, and its result is passed to read_queryMultiple Levels of Dependencies
You can nest dependencies as deep as needed:Dependency Graph
For the above example, FastAPI creates this dependency graph:get_database → get_session → get_current_user → get_user_permissions → protected_route
Sub-Dependencies with Multiple Parameters
A dependency can have multiple sub-dependencies:Dependency Caching
By default, FastAPI caches dependency results within a single request:The
call_count will only increment once per request, even though expensive_operation is used in two different dependencies. This is controlled by the use_cache=True parameter in the Depends class.Disabling Cache
If you need to disable caching for a specific dependency:Dependencies with Yield (Context Managers)
Sub-dependencies can useyield to provide cleanup logic. This is especially useful for database sessions:
Execution Flow with Yield
1
Setup phase (before yield)
All dependencies execute their setup code (before
yield) in dependency order:get_dbcreates database sessionget_current_usergets user from database- Path operation executes
2
Cleanup phase (after yield)
After the response is sent, cleanup code (after
yield) executes in reverse order:get_current_usercleanup (if any)get_dbcloses database connection
Complex Example: Chained Dependencies
Here’s a real-world example with multiple dependency levels:docs_src/dependencies/tutorial008_py310.py. The cleanup order is:
Handling Exceptions in Sub-Dependencies
You can catch exceptions from sub-dependencies:docs_src/dependencies/tutorial008b_py310.py) allows dependencies to handle exceptions raised during the request processing.
Best Practices
1
Keep dependencies focused
Each dependency should have a single, clear responsibility. This makes them easier to test and reuse.
2
Use meaningful names
Name your dependencies based on what they provide or verify (e.g.,
get_current_user, verify_permissions).3
Consider the dependency tree
Think about which dependencies are truly independent and which should be sub-dependencies. This affects caching and execution order.
4
Use yield for resource management
Always use
yield with try/finally for dependencies that manage resources like database connections.5
Be mindful of caching
Remember that dependencies are cached by default. Disable caching with
use_cache=False when you need fresh values.The Dependant Model Structure
Internally, FastAPI tracks sub-dependencies using theDependant dataclass:
Dependant can have its own list of Dependant objects, creating a tree structure that FastAPI traverses to resolve all dependencies.
Next Steps
Now that you understand sub-dependencies, explore:- Using dependencies at the path operation decorator level for side effects
- Setting up global dependencies that apply to your entire application
- Advanced patterns like dependency override for testing