Browse Source

feat: issue-2008 fix tests

pull/10861/head
Volodymyr Kochetkov 1 year ago
parent
commit
97361b02be
  1. 76
      fastapi/applications.py
  2. 107
      fastapi/routing.py

76
fastapi/applications.py

@ -1136,6 +1136,7 @@ class FastAPI(Starlette):
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
generate_unique_id
),
add_auto_options_route: bool = False,
) -> None:
self.router.add_api_route(
path,
@ -1162,6 +1163,7 @@ class FastAPI(Starlette):
name=name,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def api_route(
@ -1192,6 +1194,7 @@ class FastAPI(Starlette):
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
generate_unique_id
),
add_auto_options_route: bool = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.router.add_api_route(
@ -1219,6 +1222,7 @@ class FastAPI(Starlette):
name=name,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
return func
@ -1840,6 +1844,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP GET operation.
@ -1880,6 +1892,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def put(
@ -2213,6 +2226,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP PUT operation.
@ -2258,6 +2279,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def post(
@ -2591,6 +2613,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP POST operation.
@ -2636,6 +2666,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def delete(
@ -2969,6 +3000,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP DELETE operation.
@ -3009,6 +3048,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def options(
@ -3342,6 +3382,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP OPTIONS operation.
@ -3382,6 +3430,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def head(
@ -3715,6 +3764,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP HEAD operation.
@ -3755,6 +3812,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def patch(
@ -4088,6 +4146,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP PATCH operation.
@ -4133,6 +4199,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def trace(
@ -4466,6 +4533,14 @@ class FastAPI(Starlette):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP TRACE operation.
@ -4506,6 +4581,7 @@ class FastAPI(Starlette):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def websocket_route(

107
fastapi/routing.py

@ -397,6 +397,7 @@ class APIRoute(routing.Route):
generate_unique_id_function: Union[
Callable[["APIRoute"], str], DefaultPlaceholder
] = Default(generate_unique_id),
is_auto_options: bool = False,
) -> None:
self.path = path
self.endpoint = endpoint
@ -495,6 +496,7 @@ class APIRoute(routing.Route):
)
self.body_field = get_body_field(dependant=self.dependant, name=self.unique_id)
self.app = request_response(self.get_route_handler())
self.is_auto_options = is_auto_options
def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
return get_request_handler(
@ -838,6 +840,7 @@ class APIRouter(routing.Router):
generate_unique_id_function: Union[
Callable[[APIRoute], str], DefaultPlaceholder
] = Default(generate_unique_id),
add_auto_options_route: bool = False,
) -> None:
route_class = route_class_override or self.route_class
responses = responses or {}
@ -886,6 +889,36 @@ class APIRouter(routing.Router):
generate_unique_id_function=current_generate_unique_id,
)
self.routes.append(route)
if add_auto_options_route:
self._update_auto_options_routes(route, path)
def _update_auto_options_routes(self, new_route: APIRoute, path: str) -> None:
auto_options_index: Optional[int] = None
allowed_methods: Set[str] = set()
for index, route in enumerate(self.routes):
if route.path == new_route.path:
if hasattr(route, "is_auto_options") and route.is_auto_options:
auto_options_index = index
else:
allowed_methods.update(route.methods)
if auto_options_index is not None:
self.routes.pop(auto_options_index)
if "OPTIONS" not in new_route.methods:
async def options_route():
return Response(headers={"Allow": ", ".join(allowed_methods)})
self.routes.append(
APIRoute(
self.prefix + path,
endpoint=options_route,
methods=["OPTIONS"],
include_in_schema=False,
is_auto_options=True,
)
)
def api_route(
self,
@ -916,6 +949,7 @@ class APIRouter(routing.Router):
generate_unique_id_function: Callable[[APIRoute], str] = Default(
generate_unique_id
),
add_auto_options_route: bool = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
def decorator(func: DecoratedCallable) -> DecoratedCallable:
self.add_api_route(
@ -944,6 +978,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
return func
@ -1617,6 +1652,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP GET operation.
@ -1661,6 +1704,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def put(
@ -1994,6 +2038,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP PUT operation.
@ -2043,6 +2095,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def post(
@ -2376,6 +2429,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP POST operation.
@ -2425,6 +2486,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def delete(
@ -2758,6 +2820,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP DELETE operation.
@ -2802,6 +2872,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def options(
@ -3135,6 +3206,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP OPTIONS operation.
@ -3179,6 +3258,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def head(
@ -3512,6 +3592,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP HEAD operation.
@ -3561,6 +3649,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def patch(
@ -3894,6 +3983,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP PATCH operation.
@ -3943,6 +4040,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
def trace(
@ -4276,6 +4374,14 @@ class APIRouter(routing.Router):
"""
),
] = Default(generate_unique_id),
add_auto_options_route: Annotated[
Optional[bool],
Doc(
"""
Auto create options route.
"""
),
] = False,
) -> Callable[[DecoratedCallable], DecoratedCallable]:
"""
Add a *path operation* using an HTTP TRACE operation.
@ -4325,6 +4431,7 @@ class APIRouter(routing.Router):
callbacks=callbacks,
openapi_extra=openapi_extra,
generate_unique_id_function=generate_unique_id_function,
add_auto_options_route=add_auto_options_route,
)
@deprecated(

Loading…
Cancel
Save