Bird
Raised Fist0
FastAPIframework~15 mins

Depends function basics in FastAPI - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Depends function basics
What is it?
Depends is a special function in FastAPI that helps you share and reuse code for things like checking users or getting data. It lets you tell FastAPI to run some code before your main function and give you the result automatically. This makes your code cleaner and easier to manage. You use Depends to declare these reusable parts called dependencies.
Why it matters
Without Depends, you would have to repeat the same code in many places, making your app messy and hard to change. Depends solves this by letting you write code once and use it everywhere, saving time and reducing mistakes. It also helps FastAPI understand how your app works, so it can do things like check security or get data automatically.
Where it fits
Before learning Depends, you should know basic Python functions and how FastAPI handles requests and responses. After Depends, you can learn about advanced dependency injection, security with OAuth2, and how to manage database connections efficiently in FastAPI.
Mental Model
Core Idea
Depends lets you tell FastAPI to run helper code first and pass its result to your main function automatically.
Think of it like...
Depends is like asking a friend to prepare your coffee before you start working; you don't have to make it yourself every time, you just get it ready when you need it.
┌───────────────┐       ┌───────────────┐
│   Client      │──────▶│  FastAPI App  │
└───────────────┘       └───────────────┘
                             │
                             ▼
                   ┌─────────────────────┐
                   │ Depends Function Run │
                   └─────────────────────┘
                             │
                             ▼
                   ┌─────────────────────┐
                   │ Main Path Operation  │
                   └─────────────────────┘
                             │
                             ▼
                   ┌─────────────────────┐
                   │ Response to Client   │
                   └─────────────────────┘
Build-Up - 6 Steps
1
FoundationWhat is a Dependency in FastAPI
🤔
Concept: Introduce the idea of reusable code pieces called dependencies that FastAPI can run for you.
In FastAPI, a dependency is a function that does some work and returns a value. You can ask FastAPI to run this function automatically before your main function and give you its result. This helps avoid repeating code like checking if a user is logged in or getting a database connection.
Result
You understand that dependencies are helper functions that FastAPI runs for you to keep your code clean.
Understanding dependencies as reusable helpers is the first step to writing cleaner and more maintainable FastAPI apps.
2
FoundationUsing Depends to Declare Dependencies
🤔
Concept: Learn how to use the Depends function to tell FastAPI about dependencies.
You use Depends by adding it as a parameter default in your path operation function. For example, if you have a function get_current_user(), you write: def read_items(user: User = Depends(get_current_user)): FastAPI will run get_current_user() and pass its result as user.
Result
Your path operation function automatically receives the dependency's result without extra code.
Knowing how to declare dependencies with Depends lets you connect helper functions to your main code seamlessly.
3
IntermediateDependencies Can Have Their Own Dependencies
🤔Before reading on: do you think dependencies can call other dependencies automatically? Commit to yes or no.
Concept: Discover that dependencies can depend on other dependencies, creating a chain of reusable code.
A dependency function can itself use Depends to call another dependency. For example, get_current_active_user might depend on get_current_user. FastAPI will resolve all dependencies in the right order and pass the results down the chain.
Result
You can build complex dependency trees that FastAPI manages automatically.
Understanding nested dependencies unlocks powerful ways to organize your app's logic and reuse code efficiently.
4
IntermediateScope and Reuse of Dependency Results
🤔Before reading on: do you think FastAPI runs the same dependency function multiple times per request or just once? Commit to your answer.
Concept: Learn how FastAPI manages when and how often dependencies run during a request.
By default, FastAPI runs each dependency once per request and shares the result with all functions that need it. This avoids repeating expensive operations like database connections. You can also customize this behavior with special parameters.
Result
Your app runs efficiently by reusing dependency results during a request.
Knowing how FastAPI caches dependency results helps you write performant and resource-friendly applications.
5
AdvancedUsing Dependencies for Security and Validation
🤔Before reading on: do you think Depends can help with checking user permissions automatically? Commit to yes or no.
Concept: Explore how Depends is used to enforce security checks and validate inputs before running main code.
You can write dependencies that check if a user is authenticated or has the right permissions. If the check fails, the dependency can raise an error, stopping the request early. This keeps your main code focused on business logic.
Result
Your app automatically protects routes and validates users using dependencies.
Using Depends for security centralizes checks and reduces bugs from missing validations.
6
ExpertCustomizing Dependency Lifetimes and Cleanup
🤔Before reading on: do you think dependencies can run code after the request finishes, like closing a database? Commit to yes or no.
Concept: Learn how to use Python's yield in dependencies to run setup and cleanup code around requests.
Dependencies can be written as generators using yield. FastAPI runs the code before yield to set up, passes the value to your path function, then runs the code after yield to clean up. This is useful for opening and closing database sessions safely.
Result
Your app manages resources cleanly, avoiding leaks or stale connections.
Understanding dependency lifetimes and cleanup is key to building robust, production-ready FastAPI apps.
Under the Hood
FastAPI uses Python's function signature inspection to find parameters with Depends. When a request comes in, it builds a dependency graph by recursively resolving all Depends calls. It then calls each dependency function in order, caching results per request. For generator dependencies, it runs setup code before yield and cleanup code after the response is sent. This process happens asynchronously if needed, integrating with FastAPI's async support.
Why designed this way?
Depends was designed to make code reusable and declarative, reducing boilerplate and errors. Using Python's type hints and function signatures allows FastAPI to automatically understand dependencies without extra configuration. The generator pattern for cleanup was chosen to handle resource management cleanly, inspired by Python's context managers. This design balances simplicity, power, and performance.
┌─────────────────────────────┐
│ Incoming HTTP Request        │
└──────────────┬──────────────┘
               │
               ▼
    ┌───────────────────────┐
    │ Inspect Path Function  │
    │ for Depends parameters │
    └────────────┬──────────┘
                 │
                 ▼
    ┌─────────────────────────────┐
    │ Build Dependency Graph       │
    │ (resolve nested Depends)     │
    └────────────┬────────────────┘
                 │
                 ▼
    ┌─────────────────────────────┐
    │ Call Dependency Functions   │
    │ Cache results per request    │
    └────────────┬────────────────┘
                 │
                 ▼
    ┌─────────────────────────────┐
    │ Call Main Path Operation     │
    │ with dependency results      │
    └────────────┬────────────────┘
                 │
                 ▼
    ┌─────────────────────────────┐
    │ Send Response to Client      │
    └─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Depends run the dependency function every time it is called in your code? Commit to yes or no.
Common Belief:Depends runs the dependency function every time you use it, so it duplicates work.
Tap to reveal reality
Reality:FastAPI runs each dependency function only once per request and reuses the result wherever needed.
Why it matters:Thinking it runs multiple times can lead to unnecessary optimizations or incorrect assumptions about performance.
Quick: Can you use Depends only in path operation functions? Commit to yes or no.
Common Belief:Depends can only be used in the main route functions.
Tap to reveal reality
Reality:Depends can be used in any function FastAPI calls, including other dependencies, background tasks, and event handlers.
Why it matters:Limiting Depends to routes restricts code reuse and modular design.
Quick: Does Depends automatically handle asynchronous and synchronous functions the same way? Commit to yes or no.
Common Belief:Depends treats async and sync dependencies identically without any difference.
Tap to reveal reality
Reality:FastAPI detects if a dependency is async or sync and runs it accordingly, supporting both seamlessly.
Why it matters:Misunderstanding this can cause confusion about how to write dependencies and when to use async.
Quick: Can you use Depends to inject simple constant values like strings or numbers? Commit to yes or no.
Common Belief:Depends is only for complex functions, not for injecting simple values.
Tap to reveal reality
Reality:Depends can be used to inject any value, including constants, by wrapping them in a function.
Why it matters:Knowing this expands how you can organize configuration and constants in your app.
Expert Zone
1
FastAPI caches dependency results per request but not across requests, so expensive global caching needs separate handling.
2
Generator dependencies with yield can manage resource lifetimes but must be used carefully to avoid blocking the event loop in async apps.
3
Dependency injection order matters when dependencies depend on each other; circular dependencies cause errors that can be subtle to debug.
When NOT to use
Depends is not suitable for injecting global singletons or cross-request caches; use dedicated caching or state management instead. For very simple cases, direct function calls may be clearer. Also, avoid Depends for logic that does not need to run per request or that requires complex lifecycle management beyond setup and cleanup.
Production Patterns
In production, Depends is used to manage database sessions, authenticate users, validate permissions, and inject configuration. Complex apps build layered dependencies for modularity and testability. Using yield-based dependencies ensures proper cleanup of resources like database connections. Dependency overrides enable easy testing by replacing real dependencies with mocks.
Connections
Dependency Injection (general software design)
Depends is FastAPI's implementation of dependency injection.
Understanding Depends helps grasp the broader software pattern of dependency injection, which improves modularity and testability.
Python Context Managers
Generator dependencies with yield behave like context managers for setup and cleanup.
Knowing context managers clarifies how FastAPI manages resource lifetimes in dependencies.
Supply Chain Management
Dependency resolution in FastAPI is like managing supply chains where each step depends on previous deliveries.
Seeing dependency graphs as supply chains helps understand the order and caching of dependency calls.
Common Pitfalls
#1Writing a dependency function that does not return a value.
Wrong approach:def get_user(): user = fetch_user() # forgot to return user @app.get("/items") def read_items(user: User = Depends(get_user)): return user
Correct approach:def get_user(): user = fetch_user() return user @app.get("/items") def read_items(user: User = Depends(get_user)): return user
Root cause:Forgetting to return the value means FastAPI receives None, breaking the dependency injection.
#2Calling the dependency function directly instead of using Depends.
Wrong approach:@app.get("/items") def read_items(user: User = get_current_user()): return user
Correct approach:@app.get("/items") def read_items(user: User = Depends(get_current_user)): return user
Root cause:Calling the function runs it immediately at import time, not per request, breaking FastAPI's dependency system.
#3Using blocking code inside async dependencies without await.
Wrong approach:async def get_data(): time.sleep(1) # blocking call return data
Correct approach:async def get_data(): await asyncio.sleep(1) # non-blocking call return data
Root cause:Blocking calls in async functions freeze the event loop, hurting performance and responsiveness.
Key Takeaways
Depends is FastAPI's way to declare reusable helper functions that run before your main code and provide needed values.
Dependencies can depend on other dependencies, creating a tree that FastAPI resolves automatically and efficiently.
Using yield in dependencies allows setup and cleanup code to manage resources like database connections safely.
FastAPI runs each dependency once per request and shares the result, improving performance and consistency.
Proper use of Depends leads to cleaner, more modular, and more secure FastAPI applications.

Practice

(1/5)
1. What is the main purpose of the Depends function in FastAPI?
easy
A. To create HTML templates
B. To define database models
C. To inject dependencies automatically into path operation functions
D. To handle HTTP status codes

Solution

  1. Step 1: Understand what Depends does

    Depends is used to declare dependencies that FastAPI will automatically provide to your route functions.
  2. Step 2: Identify the main use case

    It helps inject reusable code like authentication, database sessions, or other shared logic into routes.
  3. Final Answer:

    To inject dependencies automatically into path operation functions -> Option C
  4. Quick Check:

    Depends injects dependencies = C [OK]
Hint: Depends injects reusable code into routes automatically [OK]
Common Mistakes:
  • Confusing Depends with database or template functions
  • Thinking Depends handles HTTP status codes
  • Assuming Depends creates models
2. Which of the following is the correct way to declare a dependency in a FastAPI route using Depends?
easy
A. def read_items(db=Depends(get_db)): pass
B. def read_items(db: Depends(get_db)): pass
C. def read_items(db: Depends = get_db): pass
D. def read_items(db=Depends): pass

Solution

  1. Step 1: Recall Depends syntax

    The correct syntax is to assign the parameter a default value of Depends with the dependency function inside.
  2. Step 2: Match the correct option

    def read_items(db=Depends(get_db)): pass uses db=Depends(get_db), which is the proper way to declare a dependency.
  3. Final Answer:

    def read_items(db=Depends(get_db)): pass -> Option A
  4. Quick Check:

    Depends usage = parameter=Depends(function) [OK]
Hint: Use parameter=Depends(function) to declare dependencies [OK]
Common Mistakes:
  • Using type annotation instead of default value for Depends
  • Passing Depends without parentheses
  • Assigning Depends without a function
3. Given the code below, what will be the output when accessing the /items/ endpoint?
from fastapi import FastAPI, Depends

app = FastAPI()

def get_number():
    return 42

@app.get('/items/')
def read_items(number: int = Depends(get_number)):
    return {"number": number}
medium
A. {"number": "get_number"}
B. {"number": 42}
C. Error: missing required parameter
D. {"number": null}

Solution

  1. Step 1: Understand dependency injection

    The get_number function returns 42, and FastAPI injects this value into the number parameter.
  2. Step 2: Check the returned response

    The route returns a dictionary with key "number" and value 42, so the output is {"number": 42}.
  3. Final Answer:

    {"number": 42} -> Option B
  4. Quick Check:

    Depends injects 42 = {"number": 42} [OK]
Hint: Depends calls function and injects return value [OK]
Common Mistakes:
  • Expecting the function name instead of its return value
  • Thinking parameter is missing if not passed explicitly
  • Assuming null is returned if no argument given
4. What is wrong with the following FastAPI code using Depends? How to fix it?
from fastapi import FastAPI, Depends

app = FastAPI()

def get_user():
    return "Alice"

@app.get('/user/')
def read_user(user: str = Depends):
    return {"user": user}
medium
A. Depends is missing the dependency function; fix by using Depends(get_user)
B. The route path is invalid; fix by changing '/user/' to '/users/'
C. The return type is wrong; fix by returning a list instead of dict
D. The function get_user should accept parameters; fix by adding parameters

Solution

  1. Step 1: Identify the Depends usage error

    The parameter uses Depends without specifying the dependency function, which is incorrect.
  2. Step 2: Correct the Depends syntax

    It should be Depends(get_user) to tell FastAPI which function to call for the dependency.
  3. Final Answer:

    Depends is missing the dependency function; fix by using Depends(get_user) -> Option A
  4. Quick Check:

    Depends needs function argument = Depends(get_user) [OK]
Hint: Always pass the dependency function inside Depends() [OK]
Common Mistakes:
  • Using Depends without parentheses or function
  • Changing route path unnecessarily
  • Changing return type without reason
5. How can you use Depends to share a database session across multiple routes without repeating code? Choose the best approach.
hard
A. Use Depends without any function to automatically get the session
B. Pass the session as a global variable to all routes
C. Manually create a session inside each route function
D. Create a function that returns the session and use Depends on it in each route

Solution

  1. Step 1: Understand code reuse with Depends

    Depends allows you to write a function that creates or yields a database session once and injects it wherever needed.
  2. Step 2: Identify the best practice

    Creating a session function and using Depends on it in routes avoids repetition and manages session lifecycle cleanly.
  3. Final Answer:

    Create a function that returns the session and use Depends on it in each route -> Option D
  4. Quick Check:

    Use Depends with session function for reuse = D [OK]
Hint: Use Depends with a session function to share DB session [OK]
Common Mistakes:
  • Using global variables for sessions (not safe)
  • Creating sessions manually in every route (repetitive)
  • Using Depends without specifying a function