Provide[pysyringe]
Dependency injection that keeps your domain clean. No decorators on your classes, no registration boilerplate — wiring happens at the call site.
Tests Coverage PyPI version License
$ pip install pysyringe click to copy
Read the docs
// THE IDEA

Your business logic should not know a container exists.

Mark exactly which parameters to inject with Provide[T]. Everything else is left for the caller — so it works with Django, Flask, Dramatiq, or any framework without interfering with their signatures.

typed framework-agnostic async-aware
views.py
from django.http import HttpRequest, HttpResponse
from pysyringe import Container, Provide
from myapp.domain import CalendarInterface
from myapp.infra import Calendar

container = Container()
container.alias(CalendarInterface, Calendar)

@container.inject
def get_now(
    request: HttpRequest,
    calendar: Provide[CalendarInterface],
) -> HttpResponse:
    return HttpResponse(calendar.now().isoformat())
// FEATURES

Small API, sharp edges filed off.

[inject]
Zero-decorator DI
Your domain never imports the container. Injection happens only at call sites — HTTP handlers, CLI commands, consumers.
[Provide[T]]
Explicit markers
Only parameters annotated with Provide[T] are injected; the rest are left for the caller. Safe with any framework.
[factory]
Factory-based wiring
Resolve by return-type annotations on your factory, with recursive constructor inference for everything else.
[override]
Test-friendly overrides
Swap any dependency per test with a context manager. Cleanup is automatic, even when the test raises.
[contextvars]
Thread & async safe
Overrides are scoped to the current thread or asyncio task, so concurrent tests never leak state into each other.
[singleton]
Singleton helpers
singleton() shares thread-safe resources globally; thread_local_singleton() keeps unsafe ones per-thread.