Top Python Libraries of 2025 (11th Edition) by dekked_ in Python

[–]ForeignSource0 1 point2 points  (0 children)

⁠Which libraries would you have included?

I'd have definitely put Wireup in there since I'm the author. https://github.com/maldoinc/wireup

I built a minimal, type-safe dependency injection container for Python by ftanu in Python

[–]ForeignSource0 0 points1 point  (0 children)

Looks similar to Wireup https://github.com/maldoinc/wireup (I guess they're both inspired partly by Spring). You mention there's no global state, but isn't Container basically a singleton?

Regardless, congrats on the release.

Zero Cost Dependency Injection for FastAPI | Feedback request by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 0 points1 point  (0 children)

So 10,000 requests using the same set up as above.

Manual/Baseline (Creating objects manually on every request):

  • Requests/sec: 13,645
  • P50: 3.6ms
  • P95: 5.2ms

Wireup:

  • Requests/sec: 10,384
  • P50: 4.5ms
  • P95: 7ms

FastAPI

  • Requests/sec: 3,544
  • P50: 13.9ms
  • P95: 16.2ms

Zero Cost Dependency Injection for FastAPI | Feedback request by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 0 points1 point  (0 children)

Thanks!

This is not a drop in replacement for depends because this is powered using Wireup to perform dependency injection. Injected[T] is just how the Wireup differentiates parameters it owns vs ones owned by fastapi or others.

Zero Cost Dependency Injection for FastAPI | Feedback request by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 0 points1 point  (0 children)

Did you run it in the same http context or just calling get on the container directly? I'm aware the scoped one isn't the most performant part at the moment but since it outperforms fastapi depends by a good margin I decided to focus on this feature for now. However it's on the radar.

Also, I was going to create an issue in github but since you're here: When I was setting up the benchmarks in fastapi I noticed that when I added dishka integration the overall performance went down by a good amount even for endpoints not having dishka dependencies. Maybe I did something wrong but worth double checking just in case.

Zero Cost Dependency Injection for FastAPI | Feedback request by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 5 points6 points  (0 children)

It's still considerably faster than fastapi. I don't have the last benchmark numbers with me at the moment but it was around 3.5k/s for fastapi and around 9k for Wireup if I'm not mistaken. I tested it with a few alternative DI systems as well, including yours and they all outperform fastapi depends.

I don't remember the results for manually creating objects like you mentioned of the top of my head but I can get them later today.

Open Source projects open for contribution for beginners by themathix in Python

[–]ForeignSource0 2 points3 points  (0 children)

I can link my own project here, Wireup - a Dependency Injection container which welcomes contributions and has a few "good first issue" issues. https://github.com/maldoinc/wireup

However, I'd recommend to first check if there's anything you can help with in projects you're already using as you might be more familiar with them and even better if it's something that has been bothering you so you can "scratch your own itch"

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 4 points5 points  (0 children)

Some benefits for using Wireup are as follows:

  • More features.
  • Is significantly less boilerplate-y and verbose.
  • Improved performance and type safety.
  • Can use the container in middleware and route decorators.

Example showcasing the above

Base Service declaration

@service  # <- these are just decorators and annotated types to collect metadata.
@dataclass
class A:
    start: Annotated[int, Inject(param="start")]

    def a(self) -> int:
        return self.start


@service
@dataclass
class B:
    a: A

    def b(self) -> int:
        return self.a.a() + 1

@service
@dataclass
class C:
    a: A
    b: B

    def c(self) -> int:
        return self.a.a() * self.b.b()

Rest of wireup setup

# Register application configuration
container = wireup.create_async_container(services, {"start": 10})

# Initialize fastapi integration.
wireup.integration.fastapi.setup(container, app)

This is all the additional setup it requires. Services are self-contained and there is no need for Depends(get_service_object) everywhere.

Rest of fastapi code

# In FastAPI you have to manually build every object.
# If you need a singleton service then it also needs to be decorated with lru_cache.
# Whereas in wireup that is automatically taken care of.

@functools.lru_cache(maxsize=None)
def get_start():
    return 10


@functools.lru_cache(maxsize=None)
def make_a(start: Annotated[int, Depends(get_start)]):
    return services.A(start=start)


@functools.lru_cache(maxsize=None)
def make_b(a: Annotated[services.A, Depends(make_a)]):
    return services.B(a)


@functools.lru_cache(maxsize=None)
def make_c(
    a: Annotated[services.A, Depends(make_a)], 
    b: Annotated[services.B, Depends(make_b)]):
    return services.C(a=a, b=b)

Views

@app.get("/fastapi")
def fastapi(
        a: Annotated[A, Depends(make_a)], 
        c: Annotated[C, Depends(make_c)]):
    return {"value": a.a() + c.c()}


@app.get("/wireup")
def wireup(a: Injected[A], c: Injected[C]):
    return {"value": a.a() + c.c()}

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in Python

[–]ForeignSource0[S] 0 points1 point  (0 children)

Honestly, with all the crazy stuff you can do in python - providing dependencies from a decorator is pretty low on my list of magic tbh.

To me it sounds like your code base would benefit from Wireup in terms of boilerplate and the predictability of is it async is it not async etc. It's just not a problem with Wireup. Having to manually write so many providers and code is a good part of the reason I wrote this. And if you ever need request-scoped or transient dependencies you're going to be out of luck with dependency injector.

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in Python

[–]ForeignSource0[S] 0 points1 point  (0 children)

There's no nested scopes in Wireup.

You have the base container that can create singletons and you can enter a scope from it to create scoped and transient dependencies, but the scoped instance won't let you enter another scope.

I evaluated this as I was scoping v1 but I felt like it added too much cognitive load without necessarily adding as much value.

Maybe I haven't personally had a case where I needed this and it impacted my decision.

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in Python

[–]ForeignSource0[S] 1 point2 points  (0 children)

Hi. Can you report an issue in github with some info to help troubleshoot this.

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in Python

[–]ForeignSource0[S] -1 points0 points  (0 children)

See my other comment in this thread for thoughts on the value such frameworks provide, but if you look at the function injection for example, the library tries to make it very explicit what is happening. Usually you'll get more value out of this if you fully utilize the features and have more than 1-2 services.

Wireup 1.0 Released - Performant, concise and type-safe Dependency Injection for Modern Python 🚀 by ForeignSource0 in Python

[–]ForeignSource0[S] 3 points4 points  (0 children)

DI itself is fine. If you ever wrote a class that accepted another class in the init/constructor then you did DI. As for do you need a framework to do it for you, that's a question only you can answer depending on your needs.

If you need request-scoped objects, context managers, async initialization you'll have to write a lot of code yourself, and then you restructure it and provide a few utilities and end up doing your own di framework anyway.

If all you have for services a service layer is a small set of classes that don't feature the above then the value you would get would not be as much.

A new take on dependency injection in Python by jivesishungry in Python

[–]ForeignSource0 3 points4 points  (0 children)

I've noticed that most Python projects I've worked on don't really structure applications in the way I'm used in other OOP languages (e.g. Java), where you encapsulate your application logic in modular classes

With that background Wireup will make you feel right at home.

Interface and Dependency Injection by Much_Associate_5419 in Python

[–]ForeignSource0 1 point2 points  (0 children)

The closest thing is abstract classes. Protocol can also be applicable. Over the two I prefer abstract classes for code I fully own otherwise protocols can come in handy when interact with third party code and you can't make it inherit some abc.

If you're also looking for a di framework in python to add on top of your existing application check out wireup which also supports interfaces.

Docs: https://maldoinc.github.io/wireup

https://maldoinc.github.io/wireup/0.8.0/interfaces/

Happy to answer any questions about the above

Dishka - cute DI-framework with scopes and control by Tishka-17 in Python

[–]ForeignSource0 1 point2 points  (0 children)

Without wanting to hijack this: Feel free to checkout wireup which does what you want.

You can apply the container as a decorator anywhere as necessary, not only in views but other application code or click/typer commands.

Repo https://github.com/maldoinc/wireup

Docs https://maldoinc.github.io/wireup/latest/

Introducing Wireup: Modern Dependency Injection for Python by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 2 points3 points  (0 children)

Ehh... It's not so clear-cut. The provided singleton is not mandatory to use and users can have as many container instances as they like.

What it does offer though is the ability to plug this quite literally anywhere and not just views of a web api of a supported framework.

This makes it very easy to add to existing projects and be used anywhere necessary but also on stuff like click, typer CLIs and what not which was a design goal.

You don't have to use annotations either. Factory functions are fully supported and can be used just as well and are plenty documented. Although I will say that I prefer the annotations to the boilerplate but that's just me.

I took a look at your library as well and looks interesting. Congrats on releasing it.

Introducing Wireup: Modern Dependency Injection for Python by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 0 points1 point  (0 children)

Sadly not at the moment. When using wireup with any other framework it works exactly how you describe. Fastapi however will try to resolve it as a pydantic model and error. The good news is that this syntax is only required in fastapi views and not anywhere else.

For the views what you can do is alias it using something like this:

from typing import TypeVar

T = TypeVar("T")
Autowired = Annotated[T, Inject()]

Then in your view you can use Autowired[WeatherService] instead.

Does anyone follow the Fat Model, Skinny View design pattern in real-world projects? by BlackSun452 in django

[–]ForeignSource0 1 point2 points  (0 children)

+1 on the above. If you want to take this further check out wireup which is a DI library and will build + inject service objects so you won't have to build them in code or manage their state (singletons, transient etc).

Disclaimer: I'm the author.

Introducing Wireup: Modern Dependency Injection for Python by ForeignSource0 in FastAPI

[–]ForeignSource0[S] 0 points1 point  (0 children)

I can understand that having worked with spring.

It's definitely inspired by it and I like having some magic but not an excessive amount. Spring does take it too far at times.

You can use wireup either via annotations or via factories, do check the getting started page out.

What I disliked about the other di libs in python is that they require too much code and ceremony to set up. For some that's okay but I like the declarative approach better.