A simple and efficient Python library for handling dependency injection.
Project description
haldi
Async-first dependency injection container for Python. It supports transient, scoped, and singleton lifetimes, resolves constructor (or callable) dependencies via type annotations, and can manage async context managers during resolution.
Features
- Async
resolve()andget_executor()APIs - Service lifetimes: transient, scoped, singleton
- Multiple registrations per interface (resolve returns a list)
- Optional lifetime-compatibility warning (singleton depending on scoped)
- Async context manager support for factories
Installation
pip install haldi
Quick start
from haldi import Container
class Repo:
...
class Service:
def __init__(self, repo: Repo):
self.repo = repo
container = Container()
container.add_transient(Repo)
container.add_scoped(Service)
# Resolve inside an async context
service = await container.get(Service)
Service lifetimes
- Transient: a new instance every time.
- Scoped: one instance per scope. Use
create_scope()orscoped(). - Singleton: one instance for the container lifetime.
container = Container()
container.add_transient(Repo)
container.add_scoped(Service)
container.add_singleton(Config)
scope = container.create_scope()
svc_a = await scope.get(Service)
svc_b = await scope.get(Service)
assert svc_a is svc_b
Multiple implementations
Register multiple providers for the same interface and resolve() returns a list.
class Interface:
...
class ImplA(Interface):
...
class ImplB(Interface):
...
container.add_transient(Interface, ImplA)
container.add_transient(Interface, ImplB)
instances = await container.resolve(Interface)
Factory registration
Factories can be callables (sync or async). Return annotations are required unless using a lambda.
async def build_client() -> Client:
return Client()
container.add_singleton(Client, build_client)
Scoped context helper
Use scoped() to automatically close async context managers created during resolution.
async with container.scoped() as scope:
service = await scope.get(Service)
Warnings
If a singleton depends on a scoped service, a UserWarning is emitted because the scoped instance would be captured for the lifetime of the singleton.
API overview
Container.add_transient(type, concrete_type=None)Container.add_scoped(type, concrete_type=None)Container.add_singleton(type, concrete_type=None)await Container.resolve(type, strict=True)await Container.get(type)await Container.try_get(type)await Container.get_executor(callable, strict=True)Container.create_scope()Container.scoped()
Development
pip install -e .
pytest
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file haldi-0.3.tar.gz.
File metadata
- Download URL: haldi-0.3.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4dbb9cf2ba6d03139f9e0febf1adbd09735e04b83d7e4500d7a313972efa4a5
|
|
| MD5 |
8304da08e6e63c2f22c9a49720c52309
|
|
| BLAKE2b-256 |
ad93ac72bd6e5e31e40896153762dc14ec2512786b5d7f2eca2cb6909e2dbe1d
|
File details
Details for the file haldi-0.3-py3-none-any.whl.
File metadata
- Download URL: haldi-0.3-py3-none-any.whl
- Upload date:
- Size: 5.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb857890327f5e867f85361e97fcad1ea14796a3da7345127cced8604aca38f6
|
|
| MD5 |
d1b9992e5632a0a18cbf076b78bcc305
|
|
| BLAKE2b-256 |
582dbd8da7e6e39bca16345a98a360d72e186d5d61a4e79c5a8b83fa76150860
|