Releases: modern-python/modern-di-flask
Releases · modern-python/modern-di-flask
Release list
2.0.0
modern-di-flask 2.0.0 — first release
First release of the Flask integration for modern-di. It wires a
modern-di container into a
Flask app and resolves dependencies into
views, scoped per request. The version starts at 2.0.0 to track the modern-di
2.x ecosystem alongside the other official integrations.
Flask has no dependency-injection seam of its own (views are plain callables),
so this integration is the synchronous twin of modern-di-starlette/
-aiohttp: a per-request middleware owns the container scope and an @inject
decorator (or auto_inject=True) resolves FromDI markers.
Feature
setup_di(app, container, *, auto_inject=False). Stores the root container
onapp.extensions(read back withfetch_di_container(app)), registers the
request context provider, and wiresbefore_request(build aScope.REQUEST
child seeded with the currentflask.Request, stash it onflask.g) and
teardown_appcontext(close the child). Returns the container. Call it after
registering your routes when usingauto_inject.- Per-request child containers. One
Scope.REQUESTchild per request, closed
when the request's app context tears down — including on the error path. FromDI+@inject. Mark a view parameter with
Annotated[T, FromDI(provider_or_type)]and decorate the view with@inject;
it resolves each marked parameter from the request's child container. No
signature rewrite is needed — Flask dispatches views by URL args without
inspecting the signature.auto_inject=True. Wraps every registered view (app routes and blueprint
routes alike, via Flask'sapp.view_functions) so views need no per-view
@inject.flask_request_provider. AContextProviderexposingflask.Requestat
Scope.REQUESTfor injection into factories.
Packaging
- Requires
flask>=3,<4andmodern-di>=2.25,<3; Python 3.10–3.14. (Flask 2.x
is excluded: its unpinned Werkzeug dependency is incompatible with the current
Werkzeug 3.x, so Flask 3.0 is the earliest that installs and works today.) - Ships
py.typed; zero runtime dependencies beyond Flask and modern-di. - Fully synchronous (
close_sync), matching Flask's WSGI model. - No app-shutdown hook exists in Flask (WSGI), so the root container's
teardown is the user's responsibility — callfetch_di_container(app).close_sync()
at your own shutdown point if you have APP-scoped finalizers to run.
Downstream
No action needed — this is a new package.
Internals
- 100% line coverage;
ruff,ty, andeof-fixerclean across Python
3.10–3.14. Tests use Flask'stest_client(). - Uses the portable planning convention (
planning/) with anarchitecture/
truth home; releases are tag-driven.