A minimalist, zero-dependency Inversion of Control (IoC) container for Python.
Project description
📦 Pico-IoC: A Robust, Async-Native IoC Container for Python
Pico-IoC is a lightweight, async-ready, decorator-driven IoC container built for clarity, testability, and performance. It brings Inversion of Control and dependency injection to Python in a deterministic, modern, and framework-agnostic way.
🐍 Requires Python 3.10+
⚖️ Core Principles
- Single Purpose – Do one thing: dependency management.
- Declarative – Use simple decorators (
@component,@factory,@configuration) instead of config files or YAML magic. - Deterministic – No hidden scanning or side-effects; everything flows from an explicit
init(). - Async-Native – Fully supports async providers, async lifecycle hooks, and async interceptors.
- Fail-Fast – Detects missing bindings and circular dependencies at bootstrap.
- Testable by Design – Use
overridesandprofilesto swap components instantly. - Zero Core Dependencies – Built entirely on the Python standard library. Optional features may require external packages (see Installation).
🚀 Why Pico-IoC?
As Python systems evolve, wiring dependencies by hand becomes fragile and unmaintainable. Pico-IoC eliminates that friction by letting you declare how components relate — not how they’re created.
| Feature | Manual Wiring | With Pico-IoC |
|---|---|---|
| Object creation | svc = Service(Repo(Config())) |
svc = container.get(Service) |
| Replacing deps | Monkey-patch | overrides={Repo: FakeRepo()} |
| Coupling | Tight | Loose |
| Testing | Painful | Instant |
| Async support | Manual | Built-in |
🧩 Highlights (v2.0.0)
- Full redesign: unified architecture with simpler, more powerful APIs.
- Async-aware AOP system — method interceptors via
@intercepted_by. - Typed configuration — dataclasses with JSON/YAML/env sources.
- Scoped resolution — singleton, prototype, request, session, transaction.
- UnifiedComponentProxy — transparent lazy/AOP proxy supporting serialization.
- Tree-based configuration runtime with reusable adapters and discriminators.
- Observable container context with stats, health checks, and async cleanup.
📦 Installation
pip install pico-ioc
For optional features, you can install extras:
-
YAML Configuration:
pip install pico-ioc[yaml]
(Requires
PyYAML) -
Dependency Graph Export:
pip install pico-ioc[graphviz]
(Requires the
graphvizPython package and the Graphviz command-line tools)
⚙️ Quick Example
from dataclasses import dataclass
from pico_ioc import component, configuration, init
@configuration
@dataclass
class Config:
db_url: str = "sqlite:///demo.db"
@component
class Repo:
def __init__(self, cfg: Config):
self.cfg = cfg
def fetch(self):
return f"fetching from {self.cfg.db_url}"
@component
class Service:
def __init__(self, repo: Repo):
self.repo = repo
def run(self):
return self.repo.fetch()
container = init(modules=[__name__])
svc = container.get(Service)
print(svc.run())
Output:
fetching from sqlite:///demo.db
🧪 Testing with Overrides
class FakeRepo:
def fetch(self): return "fake-data"
container = init(modules=[__name__], overrides={Repo: FakeRepo()})
svc = container.get(Service)
assert svc.run() == "fake-data"
🩺 Lifecycle & AOP
from pico_ioc import intercepted_by, MethodInterceptor, MethodCtx
class LogInterceptor(MethodInterceptor):
def invoke(self, ctx: MethodCtx, call_next):
print(f"→ calling {ctx.name}")
res = call_next(ctx)
print(f"← {ctx.name} done")
return res
@component
class Demo:
@intercepted_by(LogInterceptor)
def work(self):
return "ok"
c = init(modules=[__name__])
c.get(Demo).work()
📖 Documentation
The full documentation is available within the docs/ directory of the project repository. Start with docs/README.md for navigation.
- Getting Started:
docs/getting-started.md - User Guide:
docs/user-guide/README.md - Advanced Features:
docs/advanced-features/README.md - Observability:
docs/observability/README.md - Integrations:
docs/integrations/README.md - Cookbook (Patterns):
docs/cookbook/README.md - Architecture:
docs/architecture/README.md - API Reference:
docs/api-reference/README.md - ADR Index:
docs/adr/README.md
🧩 Development
pip install tox
tox
🧾 Changelog
See CHANGELOG.md — Full redesign for v2.0.0.
📜 License
MIT — LICENSE
Project details
Release history Release notifications | RSS feed
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 pico_ioc-2.0.5.tar.gz.
File metadata
- Download URL: pico_ioc-2.0.5.tar.gz
- Upload date:
- Size: 152.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5697dc1638f8ecf122c7e090c877f733438757d4fcf231fcce8c87ef454c5374
|
|
| MD5 |
bc1509797d62a5ac6a188351c2c61fe0
|
|
| BLAKE2b-256 |
f53c1d24ad2eeae5a6fef558aa9d886f4ee63934c1aa43b9c5bba16e9a15e1d2
|
File details
Details for the file pico_ioc-2.0.5-py3-none-any.whl.
File metadata
- Download URL: pico_ioc-2.0.5-py3-none-any.whl
- Upload date:
- Size: 33.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d82d8506877d8fc58f24f40a0612b26dc33809ec0b451c5a151d89f3d33e8e19
|
|
| MD5 |
e2a17b77670e744c615923fa539b28c6
|
|
| BLAKE2b-256 |
55b5176a7e28d7de573874eed79e1eb1081fe0c94bfe4150ce8fa2d10acebc66
|