✨ Allow decorating async routes with class based decorator#11200
Closed
zzzzlzzzz wants to merge 10 commits into
Closed
✨ Allow decorating async routes with class based decorator#11200zzzzlzzzz wants to merge 10 commits into
async routes with class based decorator#11200zzzzlzzzz wants to merge 10 commits into
Conversation
Member
|
Alternative solution: #11508 |
async routes with class based decorator
YuriiMotov
approved these changes
Jul 22, 2025
YuriiMotov
left a comment
Member
There was a problem hiding this comment.
LGTM
The idea of PR is that for now we can use function-based decorators to decorate route function:
def noop_wrap(func):
@wraps(func)
async def wrapper(*args, **kwargs):
return await func(*args, **kwargs)
return wrapper
@app.get("/function-decorator")
@noop_wrap # This works
async def route2():
return {"working": True}But we can not use class-based decorators:
class SomeDecorator:
def __init__(self, original_route):
update_wrapper(wrapper=self, wrapped=original_route)
self.route = original_route
async def __call__(self, *args, **kwargs):
return await self.route(*args, **kwargs)
@app.get("/class-decorator")
@SomeDecorator # This doesn't work for now, but this PR fixes this
async def route1():
return {"working": True}This PR makes it possible to use class-based decorators to decorate route functions.
Implementation looks nice to me (I simplified the test a bit).
Full tests code in details:
Details
from functools import wraps
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
def noop_wrap(func):
@wraps(func)
async def wrapper(*args, **kwargs):
return await func(*args, **kwargs)
return wrapper
@app.get("/function-decorator")
@noop_wrap
async def route2():
return {"working": True}
client = TestClient(app)
def test_endpoint_with_async_function_decorator():
response = client.get("/function-decorator")
assert response.status_code == 200
assert response.json() == {"working": True}from functools import update_wrapper
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
class SomeDecorator:
def __init__(self, original_route):
update_wrapper(wrapper=self, wrapped=original_route)
self.route = original_route
async def __call__(self, *args, **kwargs):
return await self.route(*args, **kwargs)
@app.get("/class-decorator")
@SomeDecorator
async def route1():
return {"working": True}
client = TestClient(app)
def test_endpoint_with_async_class_decorator():
response = client.get("/class-decorator")
# ValueError: [TypeError("'coroutine' object is not iterable ...
assert response.status_code == 200
assert response.json() == {"working": True}
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
Contributor
|
This pull request has a merge conflict that needs to be resolved. |
Member
|
This was fixed by #9555. Test passes on Will be available in FastAPI 0.123.5 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi, I can't use class based decorator with async call, so proposes this changes for review.