From 54bee71f746c4ee5aa0ad5b22078b2d1a8042be8 Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Mon, 29 Jan 2024 18:46:51 +0000 Subject: [PATCH 1/6] Add args/kwargs to get route --- fastapi/applications.py | 5 ++++- fastapi/routing.py | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index 597c60a56..0be6423ae 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1469,7 +1469,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -1788,6 +1787,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP GET operation. @@ -1828,6 +1829,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def put( diff --git a/fastapi/routing.py b/fastapi/routing.py index acebabfca..4d4fa3e5a 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -403,7 +403,6 @@ class APIRoute(routing.Route): self, path: str, endpoint: Callable[..., Any], - *, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -432,6 +431,8 @@ class APIRoute(routing.Route): generate_unique_id_function: Union[ Callable[["APIRoute"], str], DefaultPlaceholder ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> None: self.path = path self.endpoint = endpoint @@ -844,7 +845,6 @@ class APIRouter(routing.Router): self, path: str, endpoint: Callable[..., Any], - *, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -873,6 +873,8 @@ class APIRouter(routing.Router): generate_unique_id_function: Union[ Callable[[APIRoute], str], DefaultPlaceholder ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> None: route_class = route_class_override or self.route_class responses = responses or {} @@ -919,13 +921,14 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=openapi_extra, generate_unique_id_function=current_generate_unique_id, + *args, + **kwargs ) self.routes.append(route) def api_route( self, path: str, - *, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -951,6 +954,8 @@ class APIRouter(routing.Router): generate_unique_id_function: Callable[[APIRoute], str] = Default( generate_unique_id ), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: def decorator(func: DecoratedCallable) -> DecoratedCallable: self.add_api_route( @@ -1333,7 +1338,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -1652,6 +1656,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP GET operation. From 0022fc77c09858413148626fbb0581ea6f808560 Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Mon, 29 Jan 2024 18:48:53 +0000 Subject: [PATCH 2/6] Add args/kwargs to put route --- fastapi/applications.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index 0be6423ae..393d25173 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1845,7 +1845,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2164,6 +2163,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PUT operation. @@ -2209,6 +2210,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def post( From d5548ac802a88855940c1f7399bcc23262df619b Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Tue, 30 Jan 2024 10:41:37 +0000 Subject: [PATCH 3/6] Add args/kwargs to rest of the methods and fix test --- fastapi/applications.py | 30 ++++++++++++++++---- fastapi/routing.py | 44 +++++++++++++++++++++++------ tests/test_operations_signatures.py | 32 +++++++++++---------- 3 files changed, 77 insertions(+), 29 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index 393d25173..540563f6c 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -2226,7 +2226,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2545,6 +2544,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP POST operation. @@ -2590,6 +2591,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def delete( @@ -2604,7 +2607,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2923,6 +2925,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP DELETE operation. @@ -2963,6 +2967,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def options( @@ -2977,7 +2983,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -3296,6 +3301,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP OPTIONS operation. @@ -3336,6 +3343,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def head( @@ -3350,7 +3359,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -3669,6 +3677,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP HEAD operation. @@ -3709,6 +3719,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def patch( @@ -3723,7 +3735,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -4042,6 +4053,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PATCH operation. @@ -4087,6 +4100,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def trace( @@ -4101,7 +4116,6 @@ class FastAPI(Starlette): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -4420,6 +4434,8 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP TRACE operation. @@ -4460,6 +4476,8 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs ) def websocket_route( diff --git a/fastapi/routing.py b/fastapi/routing.py index 4d4fa3e5a..08a8014ac 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -984,6 +984,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) return func @@ -1089,7 +1091,6 @@ class APIRouter(routing.Router): def include_router( self, router: Annotated["APIRouter", Doc("The `APIRouter` to include.")], - *, prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", tags: Annotated[ Optional[List[Union[str, Enum]]], @@ -1197,6 +1198,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> None: """ Include another `APIRouter` in the same current `APIRouter`. @@ -1295,6 +1298,8 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=route.openapi_extra, generate_unique_id_function=current_generate_unique_id, + *args, + **kwargs ) elif isinstance(route, routing.Route): methods = list(route.methods or []) @@ -1702,6 +1707,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def put( @@ -1716,7 +1723,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2035,6 +2041,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PUT operation. @@ -2084,6 +2092,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def post( @@ -2098,7 +2108,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2417,6 +2426,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP POST operation. @@ -2466,6 +2477,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def delete( @@ -2480,7 +2493,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -2799,6 +2811,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP DELETE operation. @@ -2843,6 +2857,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def options( @@ -2857,7 +2873,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -3176,6 +3191,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP OPTIONS operation. @@ -3220,6 +3237,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def head( @@ -3234,7 +3253,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -3553,6 +3571,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP HEAD operation. @@ -3602,6 +3622,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def patch( @@ -3616,7 +3638,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -3935,6 +3956,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PATCH operation. @@ -3984,6 +4007,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) def trace( @@ -3998,7 +4023,6 @@ class APIRouter(routing.Router): """ ), ], - *, response_model: Annotated[ Any, Doc( @@ -4317,6 +4341,8 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + *args: Any, + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP TRACE operation. @@ -4366,6 +4392,8 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, + *args, + **kwargs, ) @deprecated( diff --git a/tests/test_operations_signatures.py b/tests/test_operations_signatures.py index 1a749651d..b5eeaeb77 100644 --- a/tests/test_operations_signatures.py +++ b/tests/test_operations_signatures.py @@ -1,22 +1,24 @@ import inspect +import pytest + from fastapi import APIRouter, FastAPI method_names = ["get", "put", "post", "delete", "options", "head", "patch", "trace"] -def test_signatures_consistency(): - base_sig = inspect.signature(APIRouter.get) - for method_name in method_names: - router_method = getattr(APIRouter, method_name) - app_method = getattr(FastAPI, method_name) - router_sig = inspect.signature(router_method) - app_sig = inspect.signature(app_method) - param: inspect.Parameter - for key, param in base_sig.parameters.items(): - router_param: inspect.Parameter = router_sig.parameters[key] - app_param: inspect.Parameter = app_sig.parameters[key] - assert param.annotation == router_param.annotation - assert param.annotation == app_param.annotation - assert param.default == router_param.default - assert param.default == app_param.default +@pytest.mark.parametrize('method_name', ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) +@pytest.mark.parametrize('sig_param', inspect.signature(APIRouter.get).parameters.items()) +def test_signatures_consistency(method_name, sig_param): + router_method = getattr(APIRouter, method_name) + app_method = getattr(FastAPI, method_name) + router_sig = inspect.signature(router_method) + app_sig = inspect.signature(app_method) + param: inspect.Parameter + key, param = sig_param + router_param: inspect.Parameter = router_sig.parameters[key] + app_param: inspect.Parameter = app_sig.parameters[key] + assert param.annotation == router_param.annotation + assert param.annotation == app_param.annotation + assert param.default == router_param.default + assert param.default == app_param.default From a0f72eec314bebe025bc13e18052797735678805 Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Tue, 30 Jan 2024 12:08:12 +0000 Subject: [PATCH 4/6] Fix types --- fastapi/applications.py | 32 +++++++++++----------- fastapi/routing.py | 59 +++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index 540563f6c..a6da31537 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1028,7 +1028,6 @@ class FastAPI(Starlette): self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False) if self.swagger_ui_oauth2_redirect_url: - async def swagger_ui_redirect(req: Request) -> HTMLResponse: return get_swagger_ui_oauth2_redirect_html() @@ -1038,7 +1037,6 @@ class FastAPI(Starlette): include_in_schema=False, ) if self.openapi_url and self.redoc_url: - async def redoc_html(req: Request) -> HTMLResponse: root_path = req.scope.get("root_path", "").rstrip("/") openapi_url = root_path + self.openapi_url @@ -1469,6 +1467,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -1787,8 +1786,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP GET operation. @@ -1807,6 +1805,7 @@ class FastAPI(Starlette): """ return self.router.get( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -1829,7 +1828,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs ) @@ -1845,6 +1843,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2163,7 +2162,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -2226,6 +2224,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2544,7 +2543,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -2607,6 +2605,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2925,7 +2924,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -2983,6 +2981,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -3301,7 +3300,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -3321,6 +3319,7 @@ class FastAPI(Starlette): """ return self.router.options( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -3343,7 +3342,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs ) @@ -3359,6 +3357,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -3677,7 +3676,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -3697,6 +3695,7 @@ class FastAPI(Starlette): """ return self.router.head( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -3719,7 +3718,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs ) @@ -4053,7 +4051,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, + # *args, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -4100,7 +4098,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, + # *args, **kwargs ) @@ -4116,6 +4114,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -4434,8 +4433,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - *args: Any, - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP TRACE operation. @@ -4454,6 +4452,7 @@ class FastAPI(Starlette): """ return self.router.trace( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -4476,7 +4475,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs ) diff --git a/fastapi/routing.py b/fastapi/routing.py index 08a8014ac..33e9ab4cf 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -403,6 +403,7 @@ class APIRoute(routing.Route): self, path: str, endpoint: Callable[..., Any], + *args: Any, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -431,7 +432,6 @@ class APIRoute(routing.Route): generate_unique_id_function: Union[ Callable[["APIRoute"], str], DefaultPlaceholder ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> None: self.path = path @@ -584,7 +584,7 @@ class APIRouter(routing.Router): def __init__( self, - *, + *args: Any, prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", tags: Annotated[ Optional[List[Union[str, Enum]]], @@ -796,6 +796,7 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), + **kwargs: Any ) -> None: super().__init__( routes=routes, @@ -845,6 +846,7 @@ class APIRouter(routing.Router): self, path: str, endpoint: Callable[..., Any], + *args: Any, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -873,7 +875,6 @@ class APIRouter(routing.Router): generate_unique_id_function: Union[ Callable[[APIRoute], str], DefaultPlaceholder ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> None: route_class = route_class_override or self.route_class @@ -896,7 +897,8 @@ class APIRouter(routing.Router): ) route = route_class( self.prefix + path, - endpoint=endpoint, + endpoint, + *args, response_model=response_model, status_code=status_code, tags=current_tags, @@ -921,7 +923,6 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=openapi_extra, generate_unique_id_function=current_generate_unique_id, - *args, **kwargs ) self.routes.append(route) @@ -929,6 +930,7 @@ class APIRouter(routing.Router): def api_route( self, path: str, + *args: Any, response_model: Any = Default(None), status_code: Optional[int] = None, tags: Optional[List[Union[str, Enum]]] = None, @@ -954,7 +956,6 @@ class APIRouter(routing.Router): generate_unique_id_function: Callable[[APIRoute], str] = Default( generate_unique_id ), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: def decorator(func: DecoratedCallable) -> DecoratedCallable: @@ -1091,6 +1092,7 @@ class APIRouter(routing.Router): def include_router( self, router: Annotated["APIRouter", Doc("The `APIRouter` to include.")], + *args: Any, prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", tags: Annotated[ Optional[List[Union[str, Enum]]], @@ -1198,7 +1200,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> None: """ @@ -1343,6 +1344,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -1661,7 +1663,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -1683,7 +1684,7 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, response_model=response_model, status_code=status_code, tags=tags, @@ -1723,6 +1724,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2041,7 +2043,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -2068,7 +2069,7 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, response_model=response_model, status_code=status_code, tags=tags, @@ -2108,6 +2109,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2426,8 +2428,7 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, - **kwargs: Any, + **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP POST operation. @@ -2453,7 +2454,7 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, response_model=response_model, status_code=status_code, tags=tags, @@ -2493,6 +2494,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -2811,7 +2813,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -2833,7 +2834,8 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2857,7 +2859,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -2873,6 +2874,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -3191,7 +3193,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -3213,7 +3214,8 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -3237,7 +3239,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -3253,6 +3254,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -3571,7 +3573,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -3598,7 +3599,8 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -3622,7 +3624,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -3638,6 +3639,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -3956,7 +3958,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -3983,7 +3984,8 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -4007,7 +4009,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -4023,6 +4024,7 @@ class APIRouter(routing.Router): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -4341,7 +4343,6 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - *args: Any, **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ @@ -4368,7 +4369,8 @@ class APIRouter(routing.Router): ``` """ return self.api_route( - path=path, + path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -4392,7 +4394,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) From 304b55d658fc03ad6ad9ed0087163190ed855353 Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Tue, 30 Jan 2024 12:17:10 +0000 Subject: [PATCH 5/6] Fix types --- fastapi/applications.py | 8 ++++---- fastapi/routing.py | 10 +++++----- tests/test_operations_signatures.py | 3 --- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index a6da31537..a5405eff4 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -2186,6 +2186,7 @@ class FastAPI(Starlette): """ return self.router.put( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2208,7 +2209,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs ) @@ -2567,6 +2567,7 @@ class FastAPI(Starlette): """ return self.router.post( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2589,7 +2590,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -2943,6 +2943,7 @@ class FastAPI(Starlette): """ return self.router.delete( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2965,7 +2966,6 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -3733,6 +3733,7 @@ class FastAPI(Starlette): """ ), ], + *args: Any, response_model: Annotated[ Any, Doc( @@ -4051,7 +4052,6 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - # *args, **kwargs: Any ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ diff --git a/fastapi/routing.py b/fastapi/routing.py index 33e9ab4cf..f922dec8c 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -962,6 +962,7 @@ class APIRouter(routing.Router): self.add_api_route( path, func, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -985,7 +986,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) return func @@ -1273,6 +1273,7 @@ class APIRouter(routing.Router): self.add_api_route( prefix + route.path, route.endpoint, + *args, response_model=route.response_model, status_code=route.status_code, tags=current_tags, @@ -1299,7 +1300,6 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=route.openapi_extra, generate_unique_id_function=current_generate_unique_id, - *args, **kwargs ) elif isinstance(route, routing.Route): @@ -1685,6 +1685,7 @@ class APIRouter(routing.Router): """ return self.api_route( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -1708,7 +1709,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -2070,6 +2070,7 @@ class APIRouter(routing.Router): """ return self.api_route( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2093,7 +2094,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) @@ -2455,6 +2455,7 @@ class APIRouter(routing.Router): """ return self.api_route( path, + *args, response_model=response_model, status_code=status_code, tags=tags, @@ -2478,7 +2479,6 @@ class APIRouter(routing.Router): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - *args, **kwargs, ) diff --git a/tests/test_operations_signatures.py b/tests/test_operations_signatures.py index b5eeaeb77..7859fa234 100644 --- a/tests/test_operations_signatures.py +++ b/tests/test_operations_signatures.py @@ -1,11 +1,8 @@ import inspect import pytest - from fastapi import APIRouter, FastAPI -method_names = ["get", "put", "post", "delete", "options", "head", "patch", "trace"] - @pytest.mark.parametrize('method_name', ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) @pytest.mark.parametrize('sig_param', inspect.signature(APIRouter.get).parameters.items()) From 20a84fdf5fc16f51dcdf027ad37118a4ccff2f33 Mon Sep 17 00:00:00 2001 From: Alexey Kotenko Date: Tue, 30 Jan 2024 12:19:47 +0000 Subject: [PATCH 6/6] Reformat --- fastapi/applications.py | 26 ++++++++++++++------------ fastapi/routing.py | 8 ++++---- tests/test_operations_signatures.py | 8 ++++++-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/fastapi/applications.py b/fastapi/applications.py index a5405eff4..871ac3da6 100644 --- a/fastapi/applications.py +++ b/fastapi/applications.py @@ -1028,6 +1028,7 @@ class FastAPI(Starlette): self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False) if self.swagger_ui_oauth2_redirect_url: + async def swagger_ui_redirect(req: Request) -> HTMLResponse: return get_swagger_ui_oauth2_redirect_html() @@ -1037,6 +1038,7 @@ class FastAPI(Starlette): include_in_schema=False, ) if self.openapi_url and self.redoc_url: + async def redoc_html(req: Request) -> HTMLResponse: root_path = req.scope.get("root_path", "").rstrip("/") openapi_url = root_path + self.openapi_url @@ -1828,7 +1830,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - **kwargs + **kwargs, ) def put( @@ -2162,7 +2164,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PUT operation. @@ -2209,7 +2211,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - **kwargs + **kwargs, ) def post( @@ -2543,7 +2545,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP POST operation. @@ -2924,7 +2926,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP DELETE operation. @@ -3300,7 +3302,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP OPTIONS operation. @@ -3342,7 +3344,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - **kwargs + **kwargs, ) def head( @@ -3676,7 +3678,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP HEAD operation. @@ -3718,7 +3720,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - **kwargs + **kwargs, ) def patch( @@ -4052,7 +4054,7 @@ class FastAPI(Starlette): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP PATCH operation. @@ -4099,7 +4101,7 @@ class FastAPI(Starlette): openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, # *args, - **kwargs + **kwargs, ) def trace( @@ -4475,7 +4477,7 @@ class FastAPI(Starlette): callbacks=callbacks, openapi_extra=openapi_extra, generate_unique_id_function=generate_unique_id_function, - **kwargs + **kwargs, ) def websocket_route( diff --git a/fastapi/routing.py b/fastapi/routing.py index f922dec8c..2324be65d 100644 --- a/fastapi/routing.py +++ b/fastapi/routing.py @@ -796,7 +796,7 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> None: super().__init__( routes=routes, @@ -923,7 +923,7 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=openapi_extra, generate_unique_id_function=current_generate_unique_id, - **kwargs + **kwargs, ) self.routes.append(route) @@ -1300,7 +1300,7 @@ class APIRouter(routing.Router): callbacks=current_callbacks, openapi_extra=route.openapi_extra, generate_unique_id_function=current_generate_unique_id, - **kwargs + **kwargs, ) elif isinstance(route, routing.Route): methods = list(route.methods or []) @@ -2428,7 +2428,7 @@ class APIRouter(routing.Router): """ ), ] = Default(generate_unique_id), - **kwargs: Any + **kwargs: Any, ) -> Callable[[DecoratedCallable], DecoratedCallable]: """ Add a *path operation* using an HTTP POST operation. diff --git a/tests/test_operations_signatures.py b/tests/test_operations_signatures.py index 7859fa234..832f9a0c9 100644 --- a/tests/test_operations_signatures.py +++ b/tests/test_operations_signatures.py @@ -4,8 +4,12 @@ import pytest from fastapi import APIRouter, FastAPI -@pytest.mark.parametrize('method_name', ["get", "put", "post", "delete", "options", "head", "patch", "trace"]) -@pytest.mark.parametrize('sig_param', inspect.signature(APIRouter.get).parameters.items()) +@pytest.mark.parametrize( + "method_name", ["get", "put", "post", "delete", "options", "head", "patch", "trace"] +) +@pytest.mark.parametrize( + "sig_param", inspect.signature(APIRouter.get).parameters.items() +) def test_signatures_consistency(method_name, sig_param): router_method = getattr(APIRouter, method_name) app_method = getattr(FastAPI, method_name)