Skip to content

fix: support async def views in inject and auto_inject - #40

Merged
lesnik512 merged 2 commits into
mainfrom
fix/async-view-inject
Oct 17, 2026
Merged

lesnik512 merged 2 commits into
mainfrom
fix/async-view-inject

Conversation

@lesnik512

@lesnik512 lesnik512 commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Closes #39

inject now checks inspect.iscoroutinefunction(func). For a coroutine function it returns an async def wrapper that resolves the markers from the request's child container on flask.g and awaits the view. Flask sees a coroutine function and runs it through ensure_sync (asgiref). Sync views get the same wrapper as before. auto_inject=True goes through the same inject, so it covers async views with no extra code, and mark_injected is applied to both wrappers.

Marker resolution inside the async wrapper stays sync, and the child container is closed with close_sync() at teardown. Closing it with close_async is out of scope per the issue, so the README now says Scope.REQUEST providers with async finalizers are not supported.

The async wrapper is cast to Callable[..., T], since T is the coroutine type when the input is a coroutine function. That keeps the public signature unchanged and keeps ty happy.

Tests (tests/test_async_views.py, written first and seen failing with the "it was a coroutine" error):

  • @inject on an async view returns 200 with the injected value, and the result is a coroutine function
  • the same with auto_inject=True and no decorator
  • a Scope.REQUEST cached provider resolved in the async view is the same instance a sync @inject helper resolves in that request, which shows the async wrapper reads that request's child container from flask.g

asgiref>=3.2 (the floor of Flask's async extra) is added to the dev group only. Runtime deps are unchanged.

The matching note for the Flask page in the modern-di docs will go in a separate modern-di PR as a follow-up.

@lesnik512
lesnik512 merged commit ec18d37 into main Oct 17, 2026
12 checks passed
@lesnik512
lesnik512 deleted the fix/async-view-inject branch October 17, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@inject on an async view returns a coroutine to Flask

1 participant