Classes as Dependencies
While functions are great for simple dependencies, sometimes you need more structure. FastAPI allows you to use classes as dependencies, giving you powerful ways to organize complex logic and maintain state.Why Use Classes?
Classes as dependencies are useful when you need:- State management: Store configuration or computed values
- Complex initialization: Set up connections or load data
- Reusability: Create instances with different configurations
- Organization: Group related parameters and methods together
Basic Class Dependency
Here’s a simple example from the FastAPI source code:How It Works
1
FastAPI inspects the class
When you pass a class to
Depends(), FastAPI looks at the __init__ method to determine what parameters are needed.2
Parameters are extracted from the request
FastAPI extracts values from the request (query params, headers, etc.) based on the
__init__ parameters.3
An instance is created
FastAPI calls the class constructor with the extracted values, creating an instance.
4
The instance is passed to your path operation
Your path operation function receives the instance, which you can use to access the parameters and any methods.
Shorthand Syntax
You can use a convenient shorthand when the parameter type matches the dependency:FastAPI will look at the type annotation to determine which class to use. This works because
Depends() is smart enough to use the type hint when no explicit dependency is provided.Callable Classes with __call__
You can create dependencies that are callable instances by implementing the __call__ method. This is perfect for creating configurable dependencies:
Understanding the Pattern
- Initialization:
FixedContentQueryChecker("bar")creates an instance withfixed_content="bar" - Usage: When used with
Depends(checker), FastAPI callschecker(q=...)(the__call__method) - Parameters: The
__call__method can have its own parameters that FastAPI will resolve from the request
The
__call__ method is what gets executed on each request, while __init__ is called once when you create the instance. This lets you configure the behavior at initialization time.Stateful Dependencies
Classes can maintain state between initialization and usage:Classes with Methods
You can add methods to your dependency classes for complex logic:Real-World Example: Authentication
Here’s a practical example combining class dependencies with authentication:How FastAPI Detects Callables
FastAPI’s detection logic (fromfastapi/dependencies/models.py:106) determines if a dependency is callable:
- Regular functions
- Async functions
- Classes (calls
__init__) - Callable instances (calls
__call__) - Generator functions (for context managers)
Best Practices
1
Use classes for complex dependencies
If your dependency has more than 3-4 parameters or needs helper methods, consider using a class.
2
Use callable instances for configuration
When you need multiple variations of the same dependency with different settings, create callable instances.
3
Keep state management in mind
Remember that callable instances persist across requests. Use appropriate scoping or request-specific dependencies when needed.
4
Add type hints for better editor support
Always type hint your class attributes and method returns for better IDE autocompletion.
Next Steps
Now that you know how to use classes as dependencies, learn about:- Creating sub-dependencies (dependencies that use other dependencies)
- Using dependencies at the path operation decorator level
- Setting up global application dependencies