0
0
FastAPIframework~15 mins

Dependencies with parameters in FastAPI - Deep Dive

Choose your learning style9 modes available
Overview - Dependencies with parameters
What is it?
Dependencies with parameters in FastAPI allow you to create reusable pieces of code that can accept inputs. These inputs can change how the dependency behaves each time it is used. This helps you write cleaner and more flexible code by sharing logic that depends on some values. Instead of repeating code, you pass parameters to customize the dependency's work.
Why it matters
Without dependencies that accept parameters, you would have to write similar code many times with small differences. This leads to mistakes and harder maintenance. Parameterized dependencies let you centralize logic and adapt it easily, saving time and reducing bugs. They make your API more scalable and easier to understand for others.
Where it fits
Before learning this, you should understand basic FastAPI dependencies and Python functions. After mastering dependencies with parameters, you can explore advanced dependency injection, security schemes, and state management in FastAPI.
Mental Model
Core Idea
A dependency with parameters is like a function that takes inputs to customize its behavior before FastAPI uses it to handle requests.
Think of it like...
Imagine a coffee machine where you can choose the size and type of coffee each time you use it. The machine is the dependency, and the size and type are parameters that change the coffee it makes.
Dependency with parameters flow:

Client Request
     ↓
FastAPI Endpoint
     ↓
Dependency Function(parameter)
     ↓
Returns customized result
     ↓
Endpoint uses result to respond
Build-Up - 7 Steps
1
FoundationBasic FastAPI Dependency Concept
🤔
Concept: Learn what a dependency is in FastAPI and how it helps reuse code.
In FastAPI, a dependency is a function that you can 'inject' into your path operation functions. It runs before your endpoint code and provides some data or logic. For example, a dependency can check user authentication or provide a database session.
Result
You can reuse common logic across multiple endpoints without repeating code.
Understanding dependencies is key to writing clean, maintainable FastAPI applications.
2
FoundationPassing Parameters to Functions Normally
🤔
Concept: Understand how Python functions accept parameters to customize their behavior.
In Python, functions can take parameters to change what they do. For example, def greet(name): return f'Hello {name}' lets you greet different people by passing different names.
Result
You can write one function that behaves differently based on input parameters.
Knowing how parameters work in Python functions is essential before using them in dependencies.
3
IntermediateCreating Dependencies That Accept Parameters
🤔Before reading on: Do you think FastAPI dependencies can directly accept parameters like normal functions? Commit to yes or no.
Concept: Learn how to write dependencies that accept parameters using Python's function features and FastAPI's Depends.
FastAPI dependencies cannot receive parameters directly from the endpoint call. Instead, you create a function that returns another function (a closure) or use classes with __call__ to accept parameters. Then you use Depends on the returned function or instance. Example: from fastapi import Depends from fastapi import FastAPI app = FastAPI() def dependency_with_param(param: str): def dependency(): return f'Value is {param}' return dependency @app.get('/') async def read(param_dep=Depends(dependency_with_param('hello'))): return {'message': param_dep} This way, the inner dependency uses the parameter passed when setting up Depends.
Result
You can customize dependencies by passing parameters when declaring Depends, allowing flexible reuse.
Understanding closures or callable classes unlocks how to pass parameters to dependencies in FastAPI.
4
IntermediateUsing Classes as Parameterized Dependencies
🤔Before reading on: Is using a class with __call__ a valid way to create parameterized dependencies in FastAPI? Commit to yes or no.
Concept: Learn how to use classes with a __call__ method to create dependencies that accept parameters cleanly.
Instead of nested functions, you can define a class that takes parameters in its constructor and implements __call__ to act like a function. Example: from fastapi import FastAPI, Depends app = FastAPI() class DependencyWithParam: def __init__(self, param: str): self.param = param def __call__(self): return f'Value is {self.param}' @app.get('/') async def read(dep=Depends(DependencyWithParam('hello'))): return {'message': dep} This approach is often clearer and easier to maintain for complex dependencies.
Result
You get a clean, reusable dependency that can be customized with parameters.
Using callable classes leverages Python's object-oriented features for clearer parameterized dependencies.
5
IntermediateCombining Parameterized Dependencies with Request Data
🤔Before reading on: Can parameterized dependencies also receive data from the request like query parameters? Commit to yes or no.
Concept: Learn how to mix parameters passed when creating the dependency with request data FastAPI provides automatically.
Parameterized dependencies can also accept parameters from the request by declaring them in the inner function or __call__ method. Example: from fastapi import FastAPI, Depends app = FastAPI() def dependency_with_param(param: str): def dependency(q: str): return f'{param} and query {q}' return dependency @app.get('/') async def read(dep=Depends(dependency_with_param('fixed'))): return {'message': dep} Here, 'param' is fixed when setting up Depends, but 'q' comes from the request query parameters.
Result
Dependencies can combine fixed parameters and dynamic request data for flexible behavior.
Knowing how FastAPI injects request data into dependencies helps build powerful, adaptable APIs.
6
AdvancedParameterizing Dependencies for Security and Context
🤔Before reading on: Do you think parameterized dependencies can help implement role-based access control? Commit to yes or no.
Concept: Explore how parameterized dependencies can enforce security rules or provide context-specific data based on parameters.
You can create dependencies that check user roles or permissions by passing required roles as parameters. Example: from fastapi import FastAPI, Depends, HTTPException, status app = FastAPI() class RoleChecker: def __init__(self, allowed_role: str): self.allowed_role = allowed_role def __call__(self, user_role: str): if user_role != self.allowed_role: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='Forbidden') return True @app.get('/admin') async def admin_access(check=Depends(RoleChecker('admin'))): return {'message': 'Welcome admin'} This pattern centralizes security logic and makes it reusable with different roles.
Result
You get secure endpoints that reuse the same logic but differ by required roles or permissions.
Parameterized dependencies enable clean, scalable security implementations in FastAPI.
7
ExpertAdvanced Internals: Dependency Caching and Parameter Effects
🤔Before reading on: Does FastAPI cache dependencies with parameters separately for each parameter value? Commit to yes or no.
Concept: Understand how FastAPI caches dependencies and how parameters affect caching and performance.
FastAPI caches dependencies per request to avoid running the same dependency multiple times. When you use parameterized dependencies, FastAPI treats each unique parameter value as a different dependency instance. This means if you pass different parameters, FastAPI runs the dependency separately for each. This behavior affects performance and resource usage. If parameters change often, caching benefits reduce. You can control caching with the 'use_cache' argument in Depends. Example: from fastapi import FastAPI, Depends app = FastAPI() def dependency_with_param(param: str): def dependency(): return f'Value is {param}' return dependency @app.get('/') async def read(dep1=Depends(dependency_with_param('a')), dep2=Depends(dependency_with_param('b'))): return {'dep1': dep1, 'dep2': dep2} Here, FastAPI runs the dependency twice because parameters differ.
Result
You understand how parameter values influence dependency execution and caching.
Knowing FastAPI's caching behavior prevents unexpected performance issues with parameterized dependencies.
Under the Hood
FastAPI uses Python's function signature inspection to detect dependencies. When you declare Depends with a callable, FastAPI calls it to get the dependency function or instance. For parameterized dependencies, you pass parameters when creating the callable, so FastAPI receives a customized function or callable object. During request handling, FastAPI calls these dependency functions, injecting request data as needed. It caches results per request to avoid repeated calls. The dependency graph is built dynamically, resolving parameters and nested dependencies.
Why designed this way?
FastAPI was designed to leverage Python's type hints and function signatures for automatic dependency injection. Parameterized dependencies use closures or callable classes to work around the limitation that Depends cannot accept dynamic parameters at runtime. This design balances flexibility and simplicity, avoiding complex frameworks while enabling powerful patterns. Alternatives like global state or manual calls were rejected for being less clean and harder to test.
Request → Endpoint
  ↓
Depends called with parameter → Returns customized dependency function
  ↓
FastAPI calls dependency function with request data
  ↓
Dependency returns value
  ↓
Endpoint uses value to respond
Myth Busters - 4 Common Misconceptions
Quick: Can you pass parameters directly to a dependency function from the endpoint call? Commit to yes or no.
Common Belief:You can pass parameters directly to a dependency function like a normal function call inside the endpoint.
Tap to reveal reality
Reality:FastAPI dependencies cannot receive parameters directly from the endpoint call. Parameters must be fixed when declaring Depends or passed via request data.
Why it matters:Trying to pass parameters directly causes errors or unexpected behavior, confusing beginners and breaking code.
Quick: Does FastAPI cache parameterized dependencies the same way regardless of parameter values? Commit to yes or no.
Common Belief:FastAPI caches all dependencies once per request, ignoring parameter differences.
Tap to reveal reality
Reality:FastAPI caches dependencies separately for each unique parameter value, running them multiple times if parameters differ.
Why it matters:Ignoring this leads to performance surprises and inefficient code when using many parameterized dependencies.
Quick: Can you use classes without __call__ as dependencies with parameters? Commit to yes or no.
Common Belief:Any class instance can be used as a dependency with parameters, even without __call__.
Tap to reveal reality
Reality:FastAPI requires dependencies to be callable. Classes must implement __call__ to be used as parameterized dependencies.
Why it matters:Not implementing __call__ causes runtime errors and confusion about how dependencies work.
Quick: Are parameterized dependencies only useful for security or authentication? Commit to yes or no.
Common Belief:Parameterized dependencies are mainly for security checks like roles or tokens.
Tap to reveal reality
Reality:They are useful for any reusable logic that needs customization, such as database sessions, configuration, or context-specific data.
Why it matters:Limiting their use reduces code reuse and flexibility, missing out on cleaner designs.
Expert Zone
1
Parameterized dependencies can be combined with FastAPI's dependency overrides for testing, allowing dynamic behavior changes in tests.
2
Using classes with __call__ allows maintaining internal state or caching within the dependency instance, which is not possible with simple functions.
3
FastAPI resolves dependencies in a graph, so parameterized dependencies can themselves depend on other dependencies, enabling complex layered logic.
When NOT to use
Avoid parameterized dependencies when parameters need to come from the request dynamically at runtime; instead, declare them as normal dependency parameters to receive request data. Also, for very simple cases, inline code or direct calls may be clearer. For global shared state, use application state or context managers instead.
Production Patterns
In production, parameterized dependencies are used for role-based access control, multi-tenant database sessions, feature flags, and configuration injection. Teams often create reusable classes for common patterns and combine them with FastAPI's security utilities. They also use dependency overrides in testing to mock external services.
Connections
Dependency Injection (general software design)
FastAPI dependencies with parameters are a specific implementation of dependency injection where dependencies can be customized.
Understanding FastAPI's parameterized dependencies deepens knowledge of how dependency injection can be flexible and context-aware in software design.
Closures in Programming
Parameterized dependencies often use closures to capture parameters and return customized functions.
Knowing closures helps understand how FastAPI creates dependencies that remember parameters without global variables.
Role-Based Access Control (RBAC) in Security
Parameterized dependencies can implement RBAC by accepting roles as parameters and enforcing access.
This connection shows how software design patterns and security concepts combine in practical API development.
Common Pitfalls
#1Trying to pass parameters to a dependency function directly from the endpoint call.
Wrong approach:async def endpoint(dep=Depends(my_dependency(param))): ... # where param is a variable from the endpoint parameters
Correct approach:def my_dependency(param: str): def dependency(): return param return dependency async def endpoint(dep=Depends(my_dependency('fixed_value'))): ...
Root cause:Misunderstanding that Depends expects a callable without runtime parameters, so parameters must be fixed when declaring Depends.
#2Using a class without __call__ as a dependency expecting it to work.
Wrong approach:class MyDep: def __init__(self, param): self.param = param async def endpoint(dep=Depends(MyDep('value'))): ...
Correct approach:class MyDep: def __init__(self, param): self.param = param def __call__(self): return self.param async def endpoint(dep=Depends(MyDep('value'))): ...
Root cause:FastAPI requires dependencies to be callable; missing __call__ causes errors.
#3Assuming FastAPI caches parameterized dependencies once per request regardless of parameters.
Wrong approach:Using many Depends(dependency_with_param(x)) with different x expecting only one call per request.
Correct approach:Understanding that each unique parameter value creates a separate dependency instance and FastAPI calls each separately.
Root cause:Not realizing caching keys include parameter values, leading to unexpected multiple executions.
Key Takeaways
Dependencies with parameters in FastAPI let you write reusable, customizable logic for your endpoints.
You cannot pass parameters dynamically at runtime to dependencies; parameters must be fixed when declaring Depends using closures or callable classes.
FastAPI caches dependencies per request and treats different parameter values as separate dependencies, affecting performance.
Using classes with __call__ is a clean and powerful way to create parameterized dependencies.
Parameterized dependencies are essential for scalable security, configuration, and context-aware API design.