A minimal dependency injection framework for Python with zero dependencies. Features type-hints support, singleton caching, and both type and string-based identifiers.
Project description
mindi
A lightweight dependency injection framework for Python.
- Zero external dependencies
- Type hint support
- Automatic singleton instance caching
- Support for both type and string identifiers
- Dependency cycle detection
- Dependency graph verification
- Support for dataclasses and named tuples
Quick Start
Installation:
python3 -m pip install mindi
A simple example to get you started:
from mindi import Container
di = Container()
@di.bind
class Database:
def query(self):
return "data from database"
@di.wire
def main(db: Database = di.use(Database)):
print(db.query())
main() # Prints: "data from database"
Examples
Binding Providers
Bind your providers in multiple ways:
# Simple class binding
@di.bind
class Service:
pass
# With constructor arguments
@di.bind(url="localhost")
class Database:
def __init__(self, url):
self.url = url
# Using string identifiers
di.bind("dev_db", Database, url="dev-host")
di.bind("prod_db", Database, url="prod-host")
# Using factory functions
di.bind("config", lambda: {"api_key": "secret"})
Dependency Injection
It automatically resolves dependencies marked with di.use():
# Constructor injection
@di.bind
class Service:
# @di.wire <== This line is not needed, this is handled by @di.bind
def __init__(self, db: Database = di.use(Database)):
self.db = db
# Function injection by type
@di.wire
def handle_request(service: Service = di.use(Service)):
return service.db.query()
# Function injection by string identifier
di.bind("dev_db", Database)
@di.wire
def handle_dev_request(db = di.use("dev_db")):
return db.query()
String Identifiers
from mindi import Container
from mindi.core import identifier
di = Container()
class Foo:
pass
# These binding examples are equivalent:
di.bind(Foo)
di.bind(Foo, Foo)
di.bind(Foo, lambda: Foo())
di.bind(identifier(Foo), Foo)
di.bind(f"{Foo.__module__}.{Foo.__qualname__}", Foo)
Working with Dataclasses
from dataclasses import dataclass, field
@dataclass
class Config:
api_key: str
timeout: int = field(default=30)
database: Database = di.use(Database)
di.bind("config", Config, api_key="secret")
@di.wire
def process(config: Config = di.use("config")):
print(f"Using API key: {config.api_key}")
print(f"Database: {config.database.url}")
Wiring Classes and Binding Functions
You can wire both functions and classes:
di.bind("value", lambda: 123)
@di.bind
class Service:
def __init__(self, value: int = di.use("value")):
self.value = value
# Create a wired service factory
@di.bind
def WiredService():
return di.wire(Service)()
@di.wire
def get_value(service: Service = di.use(WiredService)):
return service.value # Returns 123
Rebinding for Tests
Dependency overriding for tests:
# Enable rebinding
di = Container(rebind=True)
class MockDatabase:
def query(self):
return "test data"
# Override production database with mock
di.bind(Database, lambda: MockDatabase())
Dependency Verification
Verify your dependency graph:
# Verify all dependencies
di.instantiate()
# Verify specific service
db = di.instantiate("db")
The framework will detect and report circular dependencies with clear error messages.
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 mindi-0.1.0.tar.gz.
File metadata
- Download URL: mindi-0.1.0.tar.gz
- Upload date:
- Size: 3.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e8ea6ff3543c988633bcf458b9bbb913c551da90dddfcf4310c7631731f61a5
|
|
| MD5 |
386b8ba5d1abc7be86f6904c3f308a3c
|
|
| BLAKE2b-256 |
d81ae3cfc8c3e529526bb8f506e0233ee8a824306efd1a7b5ad5c759b925aba5
|
File details
Details for the file mindi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mindi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b07d1dc355ca910974eb29671bc689d5e85b21bda08c52100cd444599ef536a
|
|
| MD5 |
43830547e7280b962f95d4c43d08a56f
|
|
| BLAKE2b-256 |
f6ac7f022747be6c20d9b3a425a54b1dda583b923181525c7508504051fd0174
|