Dependencies in FastAPI
You have probably come across the term “dependency injection” if you are exploring FastAPI. Understanding dependencies is essential for making the most of FastAPI’s features, despite the fact that it may sound complicated. We will discuss dependencies, the common issues they cause, and how FastAPI makes using them easier.
What’s a Dependency?
Dependencies in the context of FastAPI are particular pieces of data that your application requires periodically. Dependencies are necessary for smooth web development, whether they are used for user authentication verification, input validation, or retrieving parameters from an HTTP request.
Problems with Dependencies
While dependencies solve specific needs, they come with challenges:
- Testing: Testing variations of a function that obtains a dependency differently becomes challenging.
Hidden Dependencies: Hiding details may lead to issues when external code changes, affecting the functionality of your function.
Code Duplication: Common dependencies, like looking up a user in a database, might result in duplicated code across functions.
OpenAPI Visibility: FastAPI’s automatic test page relies on information from the dependency injection mechanism.
Dependency Injection
The fundamental idea behind dependency injection is straightforward: provide any unique data a function requires directly to the function. FastAPI goes above and beyond where conventional methods stop at passing in helper functions.
FastAPI Dependencies
Dependencies can be defined directly as arguments to your functions using FastAPI. FastAPI calls these dependencies automatically and passes in the values they return. For example, a user_dep dependency could manage user authentication by obtaining data from HTTP arguments and providing a token in return.
Let’s take a look at a basic example:
from fastapi import FastAPI, Depends
app = FastAPI()
# Dependency function
def user_dep():
# Implementation details for user authentication
return {“name”: “John Doe”, “valid”: True}
# Path function using the dependency
@app.get(“/user”)
def get_user(user: dict = Depends(user_dep)):
return user
In this example, get_user expects a variable named user and obtains its value from the user_dep dependency function.
Dependency Scope
You can define dependencies at different scopes, including:
- Single Path: Apply a dependency to a single path function.
- Multiple Paths: Define a dependency for a group of path functions.
- Global: Attach dependencies to the top-level FastAPI application, affecting all path functions.
Here’s a brief example demonstrating a single path and global scope:
from fastapi import FastAPI, Depends
app = FastAPI()
# Single path with dependency
@app.get(“/user”)
def get_user(user_dep: dict = Depends()):
return user_dep
# Global scope
app = FastAPI(dependencies=[Depends(dep1), Depends(dep2)])
@app.get(“/main”)
def get_main():
# Function details here
Writing a Dependency
In FastAPI, a dependency is executed, so it must be of type Callable, including functions and classes. Let’s create a simple user authentication dependency:
from fastapi import FastAPI, Depends
app = FastAPI()
# Dependency function
def user_dep(name: str = “John”, password: str = “password”):
# Validate user and return relevant information
return {“name”: name, “valid”: True}
# Path function using the dependency
@app.get(“/login”)
def login(user: dict = Depends(user_dep)):
return user
In this example, user_dep takes name and password as parameters and returns a dictionary indicating the user’s validity.
A useful tool for creating scalable and reliable online applications is knowing the dependencies in FastAPI. Dependencies make tasks like data retrieval, input validation, and authentication easier to manage. Think about how dependencies can improve your web development process by offering flexibility and efficiency as you continue to explore FastAPI.