Fresh Bakery
Fresh Bakery is a lightweight Dependency Injection framework.
Actually, the only two asyncronious things about Fresh Bakery are its opening and its closing. It doesn't add up how you open and close your bakery: just make it asynchronously. That's it.
Fresh Bakery is suitable for integrating against any async Web framework, such as Starlette, aiohttp, FastAPI, Litestar and so forth.
Requirements: Python 3.10+
Installation
$ pip install fresh-bakery
Quickstart
$ pip install fresh-bakery
For this example we'll define some simple classes:
- Settings class with
database_dsnandinfo_id_listfields - Database class that performs
fetch_infoquery - InfoManager class that performs
fetch_infoquery and enrich result with some extra data.
After that we'll define MyBakery class, that inherited from library Bakery class.
Thereafter within main function we open up MyBakery and within context assert some statements.
import asyncio
from dataclasses import dataclass
from bakery import Bakery, Cake
@dataclass
class Settings:
database_dsn: str
info_id_list: list[int]
class Database:
def __init__(self, dsn: str):
self.dsn: str = dsn
async def fetch_info(self, info_id: int) -> dict:
return {"dsn": self.dsn, "info_id": info_id}
class InfoManager:
def __init__(self, database: Database):
self.database: Database = database
async def fetch_full_info(self, info_id: int) -> dict:
info: dict = await self.database.fetch_info(info_id)
info["full"] = True
return info
class MyBakery(Bakery):
settings: Settings = Cake(Settings, database_dsn="my_dsn", info_id_list=[1, 2, 3])
database: Database = Cake(Database, dsn=settings.database_dsn)
manager: InfoManager = Cake(InfoManager, database=database)
async def main() -> None:
async with MyBakery() as bakery:
for info_id in bakery.settings.info_id_list:
info: dict = await bakery.manager.fetch_full_info(info_id)
assert info["dsn"] == bakery.settings.database_dsn
assert info["info_id"] == info_id
assert info["full"]
if __name__ == "__main__":
asyncio.run(main())
Note that you can also open and close MyBakery directly.
async def main() -> None:
bakery: MyBakery = await MyBakery.aopen()
# some statements here
await MyBakery.aclose()
You can also get cake's value directly from MyBakery class (not instance) by calling corresponding cake or cake attribute.
async def main() -> None:
async with MyBakery() as bakery:
dsn1: str = bakery.settings.database_dsn
dsn2: str = MyBakery.settings().database_dsn
# or even so
dsn3: str = MyBakery.settings.database_dsn()
assert dsn1 == dsn2 == dsn3
Fresh Bakery is MIT licensed code.