Composition Root
Summary
All wiring happens in exactly one module. It builds a flat resource registry and exposes it to the HTTP layer and to scripts.
The resource registry
init.py returns a plain dict[str, Any]. Keys follow two conventions:
<resource>_repo— a repository adapter for a resource.<resource>_svc— a service for a resource.
Plus named infrastructure adaptors:
http_cache_store— response cache backend.progress_bus— progress/event bus.<vendor>_<kind>— fetchers, clients, stores.
The API stores the dict on app.state.db_resources during lifespan startup.
Handlers read from it; nothing imports concrete adapters.
Shape
Typed accessors
Expose a get_svc(name) helper with one @overload per key so scripts get
typing without importing concrete classes:
Also expose get_db() (raw database handle) and pure helpers such as
compute_fingerprint(payload) (canonical hash used for deduplication).
Rules
init()is idempotent.- The composition root is the only place that imports concrete adapters.
- Handlers never call
init(); they readrequest.app.state.db_resources. - Scripts call
init()/shutdown()around their work.