Skip to content

Repository files navigation

modern-di-flask

PyPI version Supported Python versions Downloads Coverage CI License GitHub stars uv Ruff ty

modern-di integration for Flask.

Full guide: Flask integration docs

Usage example: examples/

Installation

uv add modern-di-flask      # or: pip install modern-di-flask

Usage

Flask has no dependency-injection system of its own, so modern-di-flask pairs an @inject decorator with inert FromDI markers (there is no Depends). setup_di installs a before_request/teardown_appcontext pair that builds a per-request Scope.REQUEST child container and closes it once the request finishes. Resolution is sync-only, and the child container is closed with close_sync().

import typing

from flask import Flask
from modern_di import Container, Group, Scope, providers
from modern_di_flask import FromDI, inject, setup_di


class Settings:
    def __init__(self) -> None:
        self.greeting = "hello"


class Dependencies(Group):
    settings = providers.Factory(scope=Scope.APP, creator=Settings)


app = Flask(__name__)


@app.route("/hello/<name>")
@inject
def hello(name: str, settings: typing.Annotated[Settings, FromDI(Dependencies.settings)]) -> str:
    return f"{settings.greeting}, {name}"


container = Container(groups=[Dependencies])
setup_di(app, container)
container.validate()  # optional fail-fast; must come after setup_di registers its providers

Pass auto_inject=True to setup_di to wire every registered view (app and blueprint routes alike) without a per-view @inject. It walks app.view_functions when setup_di runs, so call setup_di after all routes are registered. flask.Request is resolvable within DI via the pre-built flask_request_provider context provider.

A container is open from construction. To fail fast at boot, call .validate() after setup_di, which registers flask_request_provider. Flask has no shutdown hook, so call fetch_di_container(app).close_sync() at process shutdown.

API

Symbol Description
setup_di(app, container, *, auto_inject=False) Registers the container on app.extensions, installs the before_request/teardown_appcontext pair that builds and closes a per-request Scope.REQUEST child, and, if auto_inject=True, wraps every currently registered view with inject; returns the container
FromDI(dependency) Inert marker (used with @inject) that resolves a provider or type from the per-request child container
inject(view) Decorator for a view function; resolves its FromDI-annotated parameters without rewriting the function's signature. Raises RuntimeError naming setup_di when a request reaches it without setup_di called
fetch_di_container(app) Returns the root Container stored on app.extensions
flask_request_provider ContextProvider for flask.Request (REQUEST scope), auto-registered by type

📦 PyPI

📝 License

Part of modern-python

Built on modern-di, a dependency-injection framework with an IoC container and scopes.

Browse the full list of templates and libraries in modern-python; the org profile has the categorized index.

Releases

Packages

Contributors

Languages