🌐
FastAPI
fastapi.tiangolo.com › tutorial › dependencies
Dependencies - FastAPI
It is designed to be very simple ... Injection" means, in programming, that there is a way for your code (in this case, your path operation functions) to declare things that it requires to work and use: "dependencies"....
🌐
Medium
medium.com › @azizmarzouki › mastering-dependency-injection-in-fastapi-clean-scalable-and-testable-apis-5f78099c3362
Mastering Dependency Injection in FastAPI: Clean, Scalable, and Testable APIs | by Aziz Marzouki | Medium
March 25, 2025 - FastAPI’s built-in container is powerful but limited in terms of configuration. Two popular libraries help overcome this: Install it with pip install dependency-injector.
Discussions

FastAPI + Dependency Injector
My feedback, actually have an example the does something other than returns "OK". An example that shows the value/power of dependency injection. Toy examples really do not help anyone understand the value of what you have created. More on reddit.com
🌐 r/Python
2
6
November 18, 2020
it's possible to do dependency injection in Fastapi using abstract class? - Stack Overflow
Note: One of the limitations of Depends is that currently there is no straight forward way to use it outside of FastAPI context, but luckily you can still use and combine it with a powerful tool like https://github.com/ets-labs/python-dependency-injector to build a robust decoupled modules ... More on stackoverflow.com
🌐 stackoverflow.com
FastAPI dependency injection
These are just examples of how you could do it. As an application grows you'd end up with a UserRepository / UserService instead of having that in the controller (and that's the recommended way of handling it - move any business logic out from the controller - it doesn't really belong there). However, these are small examples of how you could solve something like that. I'd like to point out that this doesn't really negate the use of FastAPI's dependency system - you can use a service pattern together with the dependency system (which makes the controller code rather minimal). In your specific example you'd move the logic of retrieving the user out from your controller at all: def get_user_repository(db: Session = Depends(get_db)): return UserRepository(db=db) def valid_user_from_path_id(user_id: int = Path(), user_repository: UserRepository = Depends(get_user_repository)): user = user_repository.find_by_id(user_id) if not user: raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail=f"User with id {id_} was not found") return user @router.get("/{user_id}", response_model=dto.UserResponseDto) def get_user(user: Depends(valid_user_from_path_id)): return user This way you get small, composable dependencies that you can set up when your controller need it. You no longer have to have the "find_by_id" logic in every route path that depends on a user_id (i.e. not every path under /users/{user_id} needs to reimplement the logic that you now have in your get_user) method. Your controller asks for a valid user from a path parameter, and everything else is handled outside of your controller and can be re-used in multiple locations. The end result is that you set up your controllers with "this is the information I need here" and then perform minimal logic in the controller itself, but has the business logic mapped out in distinct units of work instead. More on reddit.com
🌐 r/Python
15
12
November 26, 2022
(Better) Dependency Injection in FastAPI
Nice writeup, thanks. More on reddit.com
🌐 r/FastAPI
25
103
December 15, 2024
🌐
Reddit
reddit.com › r/fastapi › (better) dependency injection in fastapi
r/FastAPI on Reddit: (Better) Dependency Injection in FastAPI
December 15, 2024 -

I've tried to document my thought process for picking a dependency injection library, and I ended up with a bit of a rant. Followed by my actual thought process and implementation. Please let me know what you think of it (downvotes are fine :)) ), I'm curious if my approach/thought process makes sense to more experienced Python devs.

To tell you the truth, I'm a big fan of dependency injection. One you get to a certain app size (and/or component lifetime requirements), having your dependency instances handled for you is a godsend.

I just don't like how it works in FastAPI

You see, in FastAPI if you want to inject a component in, say, an endpoint you would do something like def my_endpoint(a=Depends(my_a_factory)), and have your my_a_factory create an instance of a or whatever. Simple, right? And, if a depends on, say, b, you then create a my_b_factory, responsible for creating b, then change the signature of my_a_factory to something like def my_a_factory(b=Depends(my_b_factory)). Easy.

But wait! What if b requires some dependencies itself? Well, I hope you're using your comfortable keyboard, because you're gonna have to write and wire up a lot of factories. One for each component. Each one Depends-ing on others. With you managing all their little lifetimes by hand. It's factories all the way down, friend. All the way down.

And sure, I mean, this approach is fine. You can use it to check user permissions, inject your db session, and stuff. It's easy to get your head around it.

But for building something more complex? Where class A needs an instance of class B, and B in turn needs C & D instances, and (guess what) D depends on E & F? Nah, man, ain't nobody got time for that.

And I haven't even mentioned the plethora of instance lifetimes -- say, B, D, & E are singletons, C is per-FastAPI-request, and F is transient, i.e. it's instantiated every time. Implement this with Depends and you'll be working on your very own, extremely private, utterly personal, HELL.

So anyway, this is how I ended up looking at DI libraries for Python

There's not that many Python dependency injection libraries, mind you. Looks like a lot of Python devs are happily building singletons left and right and don't need to inject no dependencies, while most of the others think DI is all about simplifying unit tests and just don't see the point of inverting control.

To me though, dependency inversion/injection is all about component lifetime management. I don't want to care how to instantiate nor how to dispose a dependency. I just want to declare it and then jump straight to using it. And the harder it is for me to use it, i.e. by instantiating it and its "rich" dependency tree, disposing each one when appropriate, etc, the more likely that I won't even bother at all. Simple things should be simple.

So as I said, there's not a lot of DI frameworks in Python. Just take a look at this Awesome Dependency Injection in Python, it's depressing, really (the content, not the list, the list is cool). Only 3 libraries have more than 1k stars on Github. Some of the smaller ones are cute, others not so much.

Out of the three, the most popular seemed to be python-dependency-injector, but I didn't like the big development gap between Dec 2022 and Aug 2024. Development seems to have picked up recently, but I've decided to give it a little more time to settle. It has a bunch of providers, but it wasn't clear to me how I would get a per-request lifetime. Their FastAPI example looks a bit weird to me, I'm not a fan of those Depends(Provide[Container.config.default.query]) calls (why should ALL my code know where I'm configuring my dependencies?!?).

The second most popular one is returns, which looks interesting and a bit weird, but ultimely it doesn't seem to be what I'm after.

The third one is injector. Not terribly updated, but not abandoned either. I like that I can define the lifetimes of my components in a single place. I..kinda dislike that I need to decorate all my injectable classes with @inject but beggars can't be choosers, am I right? The documentation is not nearly as good as python-dependency-injector's. I can couple it with fastapi-injector to get request-scoped dependencies.

In the end, after looking at a gazillion other options, I went with the injector + fastapi-injector combo -- it covered most of my pain points (single point for defining my dependencies and their lifetimes, easy to integrate with FastAPI, reasonably up to date), and the drawbacks (that pesky @inject) were minimal.

Here's how I set it up to handle my convoluted example above

Where class A needs an instance of class B, and B in turn needs C & D instances, and (guess what) D depends on E & F

First, the classes. The only thing they need to know is that they'll be @injected somewhere, and, if they require some dependencies, to declare and annotated them.

# classes.py
from injector import inject

@inject
class F
    def __init__(self)
        pass

@inject
class E
    def __init__(self)
        pass

@inject
class D
    def __init__(self, e: E, f: F):
        self.e = e
        self.f = f

@inject
class C:
    def __init__(self)
        pass

@inject
class B:
    def __init__(self, c: C, d: D):
        self.c = c
        self.d = d

@inject
class A:
    def __init__(self, b: B):
        self.b = b

say, B, D, & E are singletons, C is per-FastAPI-request, and F is transient, i.e. it's instantiated every time.

The lifetimes are defined in one place and one place only, while the rest of the code doesn't know anything about this.

# dependencies.py

from classes import A, B, C, D, E, F
from fastapi_injector import request_scope
from injector import Module, singleton, noscope

class Dependencies(Module):
    def configure(self, binder):
        binder.bind(A, scope=noscope)
        binder.bind(B, scope=singleton)
        binder.bind(C, scope=request_scope)
        binder.bind(D, scope=singleton)
        binder.bind(E, scope=singleton)
        binder.bind(F, scope=noscope)

        # this one's just for fun 🙃
        binder.bind(logging.Logger, to=lambda: logging.getLogger())

Then, attach the injector middleware to your app, and start injecting dependencies in your routes with Injected.

# main.py

from fastapi_injector import InjectorMiddleware, attach_injector
from injector import Injector

app = FastAPI()

injector = Injector(Dependencies())
app.add_middleware(InjectorMiddleware, injector=injector)
attach_injector(app, injector)

@app.get("/")
def root(a: A = Injected(A)):
    pass

Not too shabby. It's not a perfect solution, but it's quite close to what I had gotten used to in .NET land. I'm sticking with it for now.

(and yes, I've posted this online too, over here)

🌐
Ets-labs
python-dependency-injector.ets-labs.org › examples › fastapi.html
FastAPI example — Dependency Injector 4.49.1 documentation
"""Endpoints module.""" from typing import Annotated, List from fastapi import APIRouter, Depends from pydantic import BaseModel from dependency_injector.wiring import Provide, inject from .containers import Container from .services import SearchService class Gif(BaseModel): url: str class Response(BaseModel): query: str limit: int gifs: List[Gif] router = APIRouter() @router.get("/", response_model=Response) @inject async def index( default_query: Annotated[str, Depends(Provide[Container.config.default.query])], default_limit: Annotated[ int, Depends(Provide[Container.config.default.limit.as_
🌐
Ets-labs
python-dependency-injector.ets-labs.org › examples › fastapi-sqlalchemy.html
FastAPI + SQLAlchemy example — Dependency Injector 4.49.1 documentation
"""Application module.""" from fastapi import FastAPI from .containers import Container from . import endpoints def create_app() -> FastAPI: container = Container() db = container.db() db.create_database() app = FastAPI() app.container = container app.include_router(endpoints.router) return app app = create_app() Module endpoints contains example endpoints. Endpoints have a dependency on user service.
🌐
PropelAuth
propelauth.com › post › a-practical-guide-to-dependency-injection-with-fastapis-depends
Guide to Dependency Injection with FastAPI's Depends | PropelAuth
March 2, 2025 - You can see that just by adding ... make you write too much "glue everything together" code. FastAPI has its own dependency injection built in to the framework....
🌐
Vlad Iliescu
vladiliescu.net › posts › (better) dependency injection in fastapi
(Better) Dependency Injection in FastAPI | Vlad Iliescu
December 17, 2024 - You see, in FastAPI if you want to inject a component in, say, an endpoint you would do something like def my_endpoint(a=Depends(my_a_factory)), and have your my_a_factory create an instance of a or whatever.
🌐
ChristopherGS
christophergs.com › tutorials › ultimate-fastapi-tutorial-pt-11-dependency-injection
The Ultimate FastAPI Tutorial Part 11 - Dependency Injection via FastAPI Depends
December 4, 2021 - If you want to get more technical: Dependency injection relies on composition, and is a method for achieving inversion of control. FastAPI has an elegant and simple dependency injection system.
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python › dependency-injection-in-fastapi
Dependency Injection in FastAPI - GeeksforGeeks
July 23, 2025 - This is achieved by adhering to ... integration efforts. ... In FastAPI, the Depends function is employed to manage dependency injection, serving as a common parameter for other functions....
🌐
FastAPI Tutorial
fastapitutorial.com › blog › dependency-injection-fastapi
7. Dependency Injection in FastAPI
FastAPI embraces this concept and it is at the core of FastAPI. The first question is: What is dependency injection? It is a pattern in which an object receives other objects that it depends on.
🌐
PyPI
pypi.org › project › fastapi-injector
fastapi-injector · PyPI
Under the hood, it uses Context Variables introduced in Python 3.7, generates a UUID4 for each request, and caches dependencies in a dictionary with this uuid as the key. from injector import Injector from fastapi import FastAPI from fastapi_injector import InjectorMiddleware, request_scope, attach_injector from foo.bar import Interface, Implementation inj = Injector() # Use request_scope when binding the dependency inj.binder.bind(Interface, to=Implementation, scope=request_scope) app = FastAPI() # Add the injector middleware to the app instance app.add_middleware(InjectorMiddleware, injector=inj) attach_injector(app, inj)
      » pip install fastapi-injector
    
Published   Oct 10, 2025
Version   0.9.0
🌐
Medium
medium.com › @spraneeth4 › python-dependency-injector-simplifying-dependency-injection-in-your-projects-14385af0bf78
Python Dependency Injector: Simplifying Dependency Injection in Your Projects | by praneeth_vvs | Medium
September 27, 2024 - This could be your FastAPI endpoints, service classes, or any other components. @inject — Placing @inject above your endpoint function definitions signals to the Dependency Injector framework to automatically inject the necessary dependencies declared in the function’s parameters.
🌐
TheCodeForge
thecodeforge.io › home › python › fastapi dependency injection — how and why to use it
FastAPI Dependency Injection — How and Why to Use It | TheCodeForge
March 5, 2026 - Unlike traditional DI containers ... more Pythonic: you define dependencies as callable functions (or classes) that accept their own dependencies, and FastAPI automatically resolves the chain at request time....
🌐
LinkedIn
linkedin.com › pulse › dependency-injection-python-fastapi-raheel-siddiqui
Dependency Injection in Python FastAPI
September 28, 2023 - The Depends() dependency is a function that takes a dependency as its argument and returns the dependency. For example, the following code shows how to inject a database session into a function: from fastapi import FastAPI, Depends from sqlalchemy ...
🌐
Reddit
reddit.com › r/python › fastapi + dependency injector
r/Python on Reddit: FastAPI + Dependency Injector
November 18, 2020 -

Hey,

I've released a new version of the Dependency Injector 4.4. It makes possible to use Dependency Injector with FastAPI.
Example

File fastapi_di_example.py:

import sys

from fastapi import FastAPI, Depends
from dependency_injector import containers, providers
from dependency_injector.wiring import inject, Provide


class Service:
    async def process(self) -> str:
        return 'Ok'


class Container(containers.DeclarativeContainer):

    service = providers.Factory(Service)


app = FastAPI()


@app.api_route('/')
@inject
async def index(service: Service = Depends(Provide[Container.service])):
    result = await service.process()
    return {'result': result}


container = Container()
container.wire(modules=[sys.modules[__name__]])

To run the example install the dependencies:

pip install fastapi dependency-injector uvicorn 

and run uvicorn:

uvicorn fastapi_di_example:app --reload 

You should see in the terminal something like:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [11910] using watchgod
INFO:     Started server process [11912]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

and http://127.0.0.1:8000 should return:

{"result": "Ok"}

Testing

File tests.py:

from unittest import mock

import pytest
from httpx import AsyncClient

from fastapi_di_example import app, container, Service


@pytest.fixture
def client(event_loop):
    client = AsyncClient(app=app, base_url='http://test')
    yield client
    event_loop.run_until_complete(client.aclose())


@pytest.mark.asyncio
async def test_index(client):
    service_mock = mock.AsyncMock(spec=Service)
    service_mock.process.return_value = 'Foo'

    with container.service.override(service_mock):
        response = await client.get('/')

    assert response.status_code == 200
    assert response.json() == {'result': 'Foo'}

To run the test install the dependencies:

pip install pytest pytest-asyncio httpx

and execute:

pytest tests.py

You will something like that in the terminal:

======= test session starts =======
platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: ...
plugins: asyncio-0.14.0
collected 1 item

tests.py .                                                      [100%]

======= 1 passed in 0.17s =======

What is the advantage?

FastAPI is a powerful framework for building API. It has basic dependency injection mechanism.

This integration brings the dependency injection in FastAPI to the next level. It makes possible to use it with Dependency Injector providers, overridings, config, and resources.

🌐
Medium
medium.com › @melthaw › exploring-fastapi-dependency-injection-a-comprehensive-guide-103bc48d111f
Exploring FastAPI Dependency Injection: A Comprehensive Guide | by DZ | Medium
August 18, 2024 - You can specify the scope of a dependency using parameters in Depends: from fastapi import FastAPI, Depends app = FastAPI() # Define a dependency with scoped lifecycle def get_db(): db = "Database connection" yield db # Use yield to simulate destruction after the request completes @app.get("/items/") async def read_items(db: str = Depends(get_db)): return {"db": db}
🌐
OneUptime
oneuptime.com › home › blog › how to build dependency injection in fastapi
How to Build Dependency Injection in FastAPI
January 25, 2026 - Dependency injection (DI) separates the creation of an object from its use. Instead of instantiating dependencies inside your functions, you declare what you need and let the framework provide it.
🌐
Medium
medium.com › @dsjayamal › building-scalable-and-maintainable-fastapi-applications-part-2-dependancy-injection-a61626626aad
Building Scalable and Maintainable FastAPI Applications: Part-2 Dependancy Injection | by Danushaka Dissanayaka | Medium
March 13, 2024 - To facilitate log creation, update, and retrieval operations requiring storage interactions, we’ll inject a log repository instance into the log service class using FastAPI’s dependency injection framework.
Top answer
1 of 2
6

The dependency injection technique can be accomplished with FastAPI using the Depends class.
Here's an example of what FastAPI can offer.

Repository:
Start building the repository by combining python's ABC class with a product repo, and assuming the scope is to CRUD a product, then pydantic can help us represent the model using the BaseModel

from abc import ABC, abstractmethod

from fastapi import FastAPI, Depends
from pydantic import BaseModel


class ProductModel(BaseModel):
    """
    Pydantic model for request/response
    """
    title: str


class ProductRepositoryABC(ABC):
    """
    Abstract base product repository
    """

    @abstractmethod
    def create_product(self, product: ProductModel) -> ProductModel:
        raise NotImplementedError


class ProductRepository(ProductRepositoryABC):
    """
    Product repository
    """

    def create_product(self, product: ProductModel) -> ProductModel:
        print(f"I'm creating a new product: {product}")
        return product

Service:
After creating the model and the repository, we can start creating a service by injecting the repo as a dependency.

class ProductService(object):
    """
    Product service
    """

    def __init__(self, product_repo: ProductRepositoryABC = Depends(ProductRepository)):
        self.product_repo = product_repo

    def create_product(self, product: ProductModel) -> ProductModel:
        return self.product_repo.create_product(product=product)

Views/Routes:
Injecting a service into the route function is one step ahead; pass the service to the function as a param and use Depends to inject the service, which will be accessible in the function scope.

app = FastAPI()


@app.post(
    "/products",
    name="products:create",
    response_model=ProductModel
)
def create_product(
        product: ProductModel,
        product_srv: ProductService = Depends(ProductService)
) -> ProductModel:
    return product_srv.create_product(product=product)

Complete code:

main.py

from abc import ABC, abstractmethod

from fastapi import FastAPI, Depends
from pydantic import BaseModel


class ProductModel(BaseModel):
    """
    Pydantic model for request/response
    """
    title: str


class ProductRepositoryABC(ABC):
    """
    Abstract base product repository
    """

    @abstractmethod
    def create_product(self, product: ProductModel) -> ProductModel:
        raise NotImplementedError


class ProductRepository(ProductRepositoryABC):
    """
    Product repository
    """

    def create_product(self, product: ProductModel) -> ProductModel:
        print(f"I'm creating a new product: {product}")
        return product


class ProductService(object):
    """
    Product service
    """

    def __init__(self, product_repo: ProductRepositoryABC = Depends(ProductRepository)):
        self.product_repo = product_repo

    def create_product(self, product: ProductModel) -> ProductModel:
        return self.product_repo.create_product(product=product)


app = FastAPI()


@app.post(
    "/products",
    name="products:create",
    response_model=ProductModel
)
def create_product(
        product: ProductModel,
        product_srv: ProductService = Depends(ProductService)
) -> ProductModel:
    return product_srv.create_product(product=product)

Global settings:

You can use Pydantic to build config-base settings with a class mapper for global settings, and build a utility for string imports, and there's a quite good well-testing functions on the Django community which you can use to import from string or use the import_module directly dynamically from importlib

config.py

from pydantic import BaseSettings
from .utils import import_string #YOUR IMPORT STRING FUNCTION

class Settings(BaseSettings):
    app_name: str = "Awesome API"
    services = {
"product_repo": {"class": import_string("repositories.ProductRepository")}
}

settings.py

from functools import lru_cache

from . import config

app = FastAPI()


@lru_cache()
def get_settings():
    return config.Settings()

Start packaging your module with a more robust structure like the following

services/products.py

from settings import get_settings

settings = get_settings()

class ProductService(object):
    """
    Product service
    """

    def __init__(self, product_repo: ProductRepositoryABC = Depends(settings.get('services').get('class')):
        self.product_repo = product_repo

    def create_product(self, product: ProductModel) -> ProductModel:
        return self.product_repo.create_product(product=product)

Note: One of the limitations of Depends is that currently there is no straight forward way to use it outside of FastAPI context, but luckily you can still use and combine it with a powerful tool like https://github.com/ets-labs/python-dependency-injector to build a robust decoupled modules FastAPI example

Final result:

2 of 2
1

@Josu16

I also had the same problem in FastAPI class as dependency, what I did and it may funny, is I created instance of the ProductService and pass the ProductRepository itslef to the argument of it. out side of the @router

pro_service = ProductService(ProductRepository)

it may notbest practice but it just work.

the product service file is like this :

 def __init__(self, repo: ProductRepositoryABC = Depends()) -> None:

I'm trying to figureout the way based on Depends=()

🌐
freeCodeCamp
freecodecamp.org › news › how-to-implement-dependency-injection-in-fastapi
How to Implement Dependency Injection in FastAPI
November 14, 2025 - Dependency injection (DI) is how FastAPI delivers these dependencies to specific parts of your application: you declare them using Depends() and FastAPI automatically executes them when the associated route receives a request.