Canteen
Lightweight dependency injection for Python. Zero dependencies, full type safety, async/sync compatible.
Canteen handles three common injection patterns:
- Singleton — created once, cached forever
- Factory — new instance every call
- Resource — context manager with setup/teardown
The API is inspired by FastAPI's Depends, but works anywhere — no framework required.
Install
Requires Python 3.11+.
uv add canteen-di
The distribution is named canteen-di (the canteen name on PyPI belongs to an
unrelated project abandoned in 2015), but you import it as canteen:
import canteen
Quick start
Decorate any function to turn it into a provider. Use Depends() in default parameter values to declare dependencies between them.
from canteen import singleton, factory, resource, Depends
@singleton
def get_config() -> Config:
return Config.from_env()
@factory
def get_user_service(config: Config = Depends(get_config)) -> UserService:
return UserService(config)
@resource
def get_db(config: Config = Depends(get_config)) -> Iterator[Session]:
session = Session(config.db_url)
try:
yield session
finally:
session.close()
Call them like normal functions — dependencies resolve automatically:
config = get_config() # cached after first call
service = get_user_service() # new instance, config injected
with get_db() as session: # context manager, config injected
session.query(...)
Async providers work identically; the decorator preserves the sync/async nature of the function, so you await them and use async with.
Group related providers into a Container to get auto-wiring by parameter name and per-instance singleton caches:
from canteen import Container
class AppContainer(Container):
config = singleton(create_config)
db = resource(create_db)
user_service = factory(create_user_service)
app = AppContainer()
app.user_service() # config auto-injected
Testing
Swap any provider with override(), or pass replacements to a container constructor:
with override(get_config, lambda: Config(env="test")):
service = get_user_service() # receives test config
app = AppContainer(config=singleton(lambda: Config(env="test")))
Overrides nest, and are safe across threads and asyncio tasks (backed by contextvars). Each container instance has independent state, so test isolation needs no cleanup.
Rules
- Resources can depend on singletons, factories, and other resources. Nested resource lifetimes are managed automatically via
ExitStack. - Singletons and factories cannot depend on resources — use a resource provider instead.
- Sync providers cannot depend on async providers. Canteen raises rather than injecting an un-awaited coroutine.
@resourcerequires a generator function that yields exactly once.- Dependency cycles are rejected when a container is constructed.
Violations raise a subclass of CanteenError: ProviderError (also a TypeError), CircularDependencyError, or ResourceError (also a RuntimeError).
Documentation
Full guides — providers, dependencies, containers, async, and testing — live in docs/.
Development
uv sync
uv run pytest # tests
uv run ruff check . # lint
uv run mypy # types
License
MIT — see LICENSE.
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 canteen_di-0.1.0.tar.gz.
File metadata
- Download URL: canteen_di-0.1.0.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eac79fdce763440897362def362ea65684e15c688425afef3870e0b0755735da
|
|
| MD5 |
9d19c5afc23c9ce057e21f8c04e87875
|
|
| BLAKE2b-256 |
6db5932d129c269e1f28538c838cea81656b0d264c712e0b87775e446cf9c9b1
|
File details
Details for the file canteen_di-0.1.0-py3-none-any.whl.
File metadata
- Download URL: canteen_di-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf427a89750f318f3972e95b772e36632748c6f658a1c2f30d2a6dcf30cccb6d
|
|
| MD5 |
8562e5ad7880ee16d449796c21590c1a
|
|
| BLAKE2b-256 |
5ccc9af986f5a3214d128a331e71c30a5aaa1674f67c2ca0345711af73151c73
|