Pico-IoC Documentation
pico-ioc is a lightweight, async-native Inversion of Control (IoC) container for Python 3.11+. It brings enterprise-grade dependency injection, configuration binding, and AOP to the Python ecosystem.
Quick Install
pip install pico-ioc
# Optional: YAML configuration support
pip install pico-ioc[yaml]
30-Second Example
from pico_ioc import component, init
@component
class Database:
def query(self) -> str:
return "data from DB"
@component
class UserService:
def __init__(self, db: Database): # Auto-injected
self.db = db
def get_users(self) -> str:
return self.db.query()
# Initialize and use
container = init(modules=[__name__])
service = container.get(UserService)
print(service.get_users()) # "data from DB"
Key Features
| Feature | Description |
| Async-Native | Full async/await support: aget(), __ainit__, async @cleanup |
| Unified Configuration | @configured maps ENV vars or YAML/JSON to dataclasses |
| Fail-Fast Validation | All wiring errors detected at init(), not runtime |
| AOP Interceptors | @intercepted_by for logging, caching, security |
| Scoped Lifecycles | singleton, prototype, request, session, transaction |
| Observable | Built-in stats, health checks, dependency graph export |
Documentation Structure
| # | Section | Description | Link |
| 1 | Getting Started | 5-minute tutorial | getting-started.md |
| 2 | User Guide | Core concepts, configuration, scopes, testing | user-guide/ |
| 3 | Advanced Features | Async, AOP, Event Bus, conditional binding | advanced-features/ |
| 4 | Observability | Metrics, tracing, graph export | observability/ |
| 5 | Cookbook | Real-world patterns (multi-tenant, CQRS, etc.) | cookbook/ |
| 6 | Architecture | Design principles, internals | architecture/ |
| 7 | API Reference | Decorators, exceptions, protocols | api-reference/ |
| 8 | FAQ | Common questions and solutions | faq.md |
| 9 | Troubleshooting | Symptom-first debugging guide | troubleshooting.md |
| 10 | Examples | Complete runnable applications | examples/ |
| 11 | Learning Roadmap | Step-by-step path from zero to advanced | LEARN.md |
Core APIs at a Glance
Registration
from pico_ioc import component, factory, provides
@component # Register a class
class MyService: ...
@factory # Group related providers
class ClientFactory:
@provides(RedisClient) # Provide third-party types
def build_redis(self, config: RedisConfig) -> RedisClient:
return RedisClient(config.url)
Configuration
from dataclasses import dataclass
from pico_ioc import configured, configuration, init
@configured(prefix="DB_")
@dataclass
class DBConfig:
host: str = "localhost"
port: int = 5432
container = init(
modules=[__name__],
config=configuration() # Reads from ENV: DB_HOST, DB_PORT
)
Async Support
@component
class AsyncService:
async def __ainit__(self):
self.conn = await open_connection()
@cleanup
async def close(self):
await self.conn.close()
# Resolve async components
service = await container.aget(AsyncService)
# Cleanup
await container.ashutdown()
Testing with Overrides
container = init(
modules=[__name__],
overrides={Database: FakeDatabase()} # Replace for tests
)
Next Steps
- New to pico-ioc? Start with the Getting Started tutorial
- Learning from scratch? Follow the Learning Roadmap from zero to advanced
- Coming from Spring/Guice? Check the Architecture Comparison
- Building a real app? See the Cookbook patterns