Picodi - Python DI (Dependency Injection) Library
Documentation
Picodi simplifies Dependency Injection (DI) for Python applications.
DI is a design pattern
that allows objects to receive their dependencies from
an external source rather than creating them internally.
This library supports both synchronous and asynchronous contexts,
and offers features like lifecycle management.
Table of Contents
Status
Picodi is currently in the experimental stage.
Public APIs may change without notice until the library reaches a 1.x.x version.
Installation
pip install picodi
Features
- 🌟 Simple and lightweight
- 📦 Zero dependencies
- ⏱️ Supports both sync and async contexts
- 🔄 Lifecycle management
- 🔍 Type hints support
- 🐍 Python & PyPy 3.10+ support
- 🚀 Works well with FastAPI
- 🧪 Integration with pytest
Quick Start
import asyncio
from collections.abc import Callable
from datetime import date
from typing import Any
import httpx
from picodi import (
Provide,
init_dependencies,
inject,
dependency,
SingletonScope,
shutdown_dependencies,
)
from picodi.helpers import get_value
def get_settings() -> dict:
return {
"nasa_api": {
"api_key": "DEMO_KEY",
"base_url": "https://api.nasa.gov",
"timeout": 10,
}
}
@inject
def get_setting(path: str, settings: dict = Provide(get_settings)) -> Callable[[], Any]:
value = get_value(path, settings)
return lambda: value
@dependency(scope_class=SingletonScope)
@inject
async def get_nasa_client(
api_key: str = Provide(get_setting("nasa_api.api_key")),
base_url: str = Provide(get_setting("nasa_api.base_url")),
timeout: int = Provide(get_setting("nasa_api.timeout")),
) -> httpx.AsyncClient:
async with httpx.AsyncClient(
base_url=base_url, params={"api_key": api_key}, timeout=timeout
) as client:
yield client
@inject
async def get_apod(
date: date, client: httpx.AsyncClient = Provide(get_nasa_client)
) -> dict[str, Any]:
print("Client ID:", id(client))
response = await client.get("/planetary/apod", params={"date": date.isoformat()})
response.raise_for_status()
return response.json()
@inject
def print_client_info(client: httpx.AsyncClient = Provide(get_nasa_client)):
print("Client ID:", id(client))
print("Client Base URL:", client.base_url)
print("Client Params:", client.params)
print("Client Timeout:", client.timeout)
async def main():
await init_dependencies()
print_client_info()
apod_data = await get_apod(date(2011, 7, 19))
print("Title:", apod_data["title"])
apod_data = await get_apod(date(2011, 7, 26))
print("Title:", apod_data["title"])
await shutdown_dependencies()
if __name__ == "__main__":
asyncio.run(main())
Integration with other libraries
Read on the documentation site
FastAPI Example Project
Here is an example of a FastAPI application
that uses Picodi for dependency injection:
Picodi FastAPI Example
Known Issues
Read on the documentation site
License
MIT
Contributing
Contributions are welcome!
Please read the CONTRIBUTING.md file for more information.
Credits
This project was generated with yakimka/cookiecutter-pyproject
.