🌐
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_
🌐
FastAPI
fastapi.tiangolo.com › tutorial › dependencies
Dependencies - FastAPI
It is just a function that can take all the same parameters that a path operation function can take: ... from typing import Annotated from fastapi import Depends, FastAPI app = FastAPI() async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100): return {"q": q, "skip": ...
Discussions

(Better) Dependency Injection in FastAPI
Nice writeup, thanks. More on reddit.com
🌐 r/FastAPI
25
103
December 15, 2024
how to inject FastAPI bearer instances into Depends
the oauth_factory produces as callable with fastapi know signature · def user_checker(oauth_header:HTTPAuthorizationCredentials = Security(bearer)) ... return user · My problem now is when I want the some_token_extractor be provided by python-dependency-injector More on github.com
🌐 github.com
15
July 12, 2021
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 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
🌐
Ets-labs
python-dependency-injector.ets-labs.org › examples › fastapi-sqlalchemy.html
FastAPI + SQLAlchemy example — Dependency Injector 4.49.1 documentation
"""Endpoints module.""" from typing import Annotated from fastapi import APIRouter, Depends, Response, status from dependency_injector.wiring import Provide, inject from .containers import Container from .repositories import NotFoundError from .services import UserService router = APIRouter() @router.get("/users") @inject def get_list( user_service: Annotated[UserService, Depends(Provide[Container.user_service])], ): return user_service.get_users() @router.get("/users/{user_id}") @inject def get_by_id( user_id: int, user_service: Annotated[UserService, Depends(Provide[Container.user_service])]
🌐
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)

🌐
GeeksforGeeks
geeksforgeeks.org › python › dependency-injection-in-fastapi
Dependency Injection in FastAPI - GeeksforGeeks
July 23, 2025 - This article explores Dependency Injection (DI) in FastAPI, a modern Python web framework for building APIs. FastAPI's versatility is evident when there's a need to reuse code or override specific sections.
🌐
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
🌐
Vlad Iliescu
vladiliescu.net › posts › (better) dependency injection in fastapi
(Better) Dependency Injection in FastAPI | Vlad Iliescu
December 17, 2024 - 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.
🌐
Medium
medium.com › @guillaume.launay › dependency-injection-in-python-beyond-fastapis-depends-eec237b1327b
Dependency Injection in Python, Beyond FastAPI’s Depends | by Guillaume Launay | Medium
March 6, 2026 - - When you call attach_injector, FastAPI is configured to resolve Injecteddependencies using your injector container. - This means that instead of manually writing factory functions (def get_user_repository) and passing them into Depends you just ask for a class (`UserService`), and injector figures out how to build it based on the bindings in your AppModule.
Find elsewhere
🌐
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 - To effectively integrate dependency injection using the Dependency Injector framework in a FastAPI application, two critical steps need to be implemented: container.wire(modules=[…]) — It Registers Modules: You’re telling the DI container which Python modules (or files) contain components that should have dependencies injected into them.
🌐
GitHub
github.com › shimat › fastapi_di_sample
GitHub - shimat/fastapi_di_sample: FastAPI + Dependency Injector code samples · GitHub
task fastapi · $ curl -s "http://localhost:8000/?word=alice" {"is_ok":true} $ curl -s "http://localhost:8000/?word=xxxxx" {"is_ok":false} PS> Invoke-RestMethod http://localhost:8000/ -Body @{"word"="alice"} is_ok ----- True PS> Invoke-RestMethod http://localhost:8000/ -Body @{"word"="xxxxx"} is_ok ----- False · task test · task flake8 task mypy · https://python-dependency-injector.ets-labs.org/examples/fastapi.html
Author   shimat
🌐
GitHub
github.com › ets-labs › python-dependency-injector › issues › 470
how to inject FastAPI bearer instances into Depends · Issue #470 · ets-labs/python-dependency-injector
July 12, 2021 - the oauth_factory produces as callable with fastapi know signature · def user_checker(oauth_header:HTTPAuthorizationCredentials = Security(bearer)) ... return user · My problem now is when I want the some_token_extractor be provided by python-dependency-injector
Author   ets-labs
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=()

🌐
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 - FastAPI's dependency injection system is a built-in mechanism for declaring and resolving the dependencies your endpoint functions need to run. Unlike traditional DI containers (like Spring or Guice) that focus on wiring up entire object graphs, ...
🌐
DeepWiki
deepwiki.com › ets-labs › python-dependency-injector › 6.2-fastapi-integration
FastAPI Integration | ets-labs/python-dependency-injector | DeepWiki
February 23, 2026 - FastAPI integration uses the wiring system to inject dependencies into endpoint handlers. The framework's Depends() function wraps Dependency Injector's Provide markers, enabling seamless integration with FastAPI's dependency injection system.
🌐
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.
🌐
Leapcell
leapcell.io › blog › unlocking-fastapi-s-power-with-dependency-injection
Unlocking FastAPI's Power with Dependency Injection | Leapcell
September 29, 2025 - These functions are often decorated with @Depends or directly referenced in the route function's signature. FastAPI's dependency injection system is built upon the foundation of standard Python type hints and the Depends utility.
🌐
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.

🌐
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 - We use the FastAPI app dependency_overrides to replace dependencies. We replace what the selected dependency (in this case get_reddit_client) callable is, pointing to a new callable which will be used in testing (in this case override_reddi...
🌐
LinkedIn
linkedin.com › pulse › dependency-injection-python-fastapi-raheel-siddiqui
Dependency Injection in Python FastAPI
September 28, 2023 - Dependency injection is a design pattern that allows you to decouple your code by passing dependencies to your functions and classes instead of instantiating them directly. This makes your code more reusable, maintainable, ...
🌐
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....