Skip to content

Releases: modern-python/modern-di-flask

Release list

2.0.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 14:56
5d07dd8

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
    on app.extensions (read back with fetch_di_container(app)), registers the
    request context provider, and wires before_request (build a Scope.REQUEST
    child seeded with the current flask.Request, stash it on flask.g) and
    teardown_appcontext (close the child). Returns the container. Call it after
    registering your routes
    when using auto_inject.
  • Per-request child containers. One Scope.REQUEST child 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's app.view_functions) so views need no per-view
    @inject.
  • flask_request_provider. A ContextProvider exposing flask.Request at
    Scope.REQUEST for injection into factories.

Packaging

  • Requires flask>=3,<4 and modern-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 — call fetch_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, and eof-fixer clean across Python
    3.10–3.14. Tests use Flask's test_client().
  • Uses the portable planning convention (planning/) with an architecture/
    truth home; releases are tag-driven.