Python dependency injection with minimal API using context managers
Project description
context-dep
Python dependency injection with minimal API using context managers. Works as DI for any Python code, including frameworks like FastAPI. Use it for configs, clients, db sessions, contexts, loggers, etc.
Instead of passing the same stuff (database, config, API clients, current user) into every function, your code can grab it when needed — it’s reused for the duration of the work, cleaned up afterward, and easy to replace with fakes in tests from one place.
pip install context-dep
Basic usage
from context_dep import dep, context
@dep(cached=True)
def get_db():
db = Database()
yield db
db.close()
def my_func():
with get_db() as db:
...
Overrides
@dep()
def get_mock_db():
yield MockDatabase()
def main():
with context({get_db: get_mock_db}):
my_func()
Recipe: argument-scoped caching
from context_dep import dep
@dep(cached=True)
def get_session_db(env: str):
...
with get_session_db(env='test') as db:
# separate cache for each environment
...
Recipe: stub dependency for later injection
@dep()
async def get_db():
raise NotImplementedError
async with get_db() as db:
...
Cache Lifetime
When cached=True, the dependency is reused within nested calls and cleaned up once:
@dep(cached=True)
def get_db():
db = Database()
yield db
db.close()
with get_db() as db:
with get_db() as db2: # Reuses the same instance
assert db is db2
# Cleanup runs once when the outermost context exits
Notes
- Works with both sync and async functions
- Context is managed with
contextvars- safe for async/await
API Reference
def dep(
cached: bool = False,
cache_key_func = lambda *args, **kwargs: json.dumps(
{"args": args, "kwargs": kwargs},
sort_keys=True,
default=str
),
):
"""
Decorator for defining dependencies.
Args:
cached: If True, the dependency is reused within nested calls
cache_key_func: Function to generate cache keys from arguments.
Defaults to JSON serialization with sorted keys (sort_keys=True, default=str)
"""
...
class context:
"""Context manager to scope dependencies"""
def __init__(self, overrides: dict[Callable, Callable]): ...
class Container:
"""
Dependency injection container, stores the cache and overrides
By default, `dep` and `context` use a shared global container.
Create separate containers for isolation (e.g., testing, multi-tenancy)
"""
def dep(self, cached: bool = False, cache_key_func = ...): ...
def context(self, overrides: dict[Callable, Callable]): ...
License
MIT License
Author
Mark Lidenberg marklidenberg@gmail.com
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 context_dep-0.1.1.tar.gz.
File metadata
- Download URL: context_dep-0.1.1.tar.gz
- Upload date:
- Size: 42.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0bc6da9c83f4d94195492206926ab4e3d4c7d250fb1b87dd71ff50f54cd092a8
|
|
| MD5 |
2874de2faf4b344c45ea7e4c88ed9c70
|
|
| BLAKE2b-256 |
7dbd2088ecb3b20451d95c98b2aeb27e9d4b9928319e81edf2a845c5ab4c0aba
|
File details
Details for the file context_dep-0.1.1-py3-none-any.whl.
File metadata
- Download URL: context_dep-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
889147eedd1cc60ab0702752a51b5a8a6b2a53ee99b47dd9ad1a480aab96aba1
|
|
| MD5 |
6d881720a36413938328e6c5343e3b62
|
|
| BLAKE2b-256 |
7e10b3cb9e7c40839e90644145fbd930a96fda61e0959b2df41a171f5b9a8792
|