|
|
@ -1,18 +1,19 @@ |
|
|
import dataclasses |
|
|
import dataclasses |
|
|
import inspect |
|
|
import inspect |
|
|
import sys |
|
|
import sys |
|
|
from collections.abc import Mapping, Sequence |
|
|
from collections.abc import Callable, Mapping, Sequence |
|
|
from contextlib import AsyncExitStack, contextmanager |
|
|
from contextlib import AsyncExitStack, contextmanager |
|
|
from copy import copy, deepcopy |
|
|
from copy import copy, deepcopy |
|
|
from dataclasses import dataclass |
|
|
from dataclasses import dataclass |
|
|
from typing import ( |
|
|
from typing import ( |
|
|
Annotated, |
|
|
Annotated, |
|
|
Any, |
|
|
Any, |
|
|
Callable, |
|
|
|
|
|
ForwardRef, |
|
|
ForwardRef, |
|
|
Optional, |
|
|
Literal, |
|
|
Union, |
|
|
Union, |
|
|
cast, |
|
|
cast, |
|
|
|
|
|
get_args, |
|
|
|
|
|
get_origin, |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
from fastapi import params |
|
|
from fastapi import params |
|
|
@ -63,7 +64,6 @@ from starlette.datastructures import ( |
|
|
from starlette.requests import HTTPConnection, Request |
|
|
from starlette.requests import HTTPConnection, Request |
|
|
from starlette.responses import Response |
|
|
from starlette.responses import Response |
|
|
from starlette.websockets import WebSocket |
|
|
from starlette.websockets import WebSocket |
|
|
from typing_extensions import Literal, get_args, get_origin |
|
|
|
|
|
from typing_inspection.typing_objects import is_typealiastype |
|
|
from typing_inspection.typing_objects import is_typealiastype |
|
|
|
|
|
|
|
|
multipart_not_installed_error = ( |
|
|
multipart_not_installed_error = ( |
|
|
@ -127,8 +127,8 @@ def get_flat_dependant( |
|
|
dependant: Dependant, |
|
|
dependant: Dependant, |
|
|
*, |
|
|
*, |
|
|
skip_repeats: bool = False, |
|
|
skip_repeats: bool = False, |
|
|
visited: Optional[list[DependencyCacheKey]] = None, |
|
|
visited: list[DependencyCacheKey] | None = None, |
|
|
parent_oauth_scopes: Optional[list[str]] = None, |
|
|
parent_oauth_scopes: list[str] | None = None, |
|
|
) -> Dependant: |
|
|
) -> Dependant: |
|
|
if visited is None: |
|
|
if visited is None: |
|
|
visited = [] |
|
|
visited = [] |
|
|
@ -255,11 +255,11 @@ def get_dependant( |
|
|
*, |
|
|
*, |
|
|
path: str, |
|
|
path: str, |
|
|
call: Callable[..., Any], |
|
|
call: Callable[..., Any], |
|
|
name: Optional[str] = None, |
|
|
name: str | None = None, |
|
|
own_oauth_scopes: Optional[list[str]] = None, |
|
|
own_oauth_scopes: list[str] | None = None, |
|
|
parent_oauth_scopes: Optional[list[str]] = None, |
|
|
parent_oauth_scopes: list[str] | None = None, |
|
|
use_cache: bool = True, |
|
|
use_cache: bool = True, |
|
|
scope: Union[Literal["function", "request"], None] = None, |
|
|
scope: Literal["function", "request"] | None = None, |
|
|
) -> Dependant: |
|
|
) -> Dependant: |
|
|
dependant = Dependant( |
|
|
dependant = Dependant( |
|
|
call=call, |
|
|
call=call, |
|
|
@ -328,7 +328,7 @@ def get_dependant( |
|
|
|
|
|
|
|
|
def add_non_field_param_to_dependency( |
|
|
def add_non_field_param_to_dependency( |
|
|
*, param_name: str, type_annotation: Any, dependant: Dependant |
|
|
*, param_name: str, type_annotation: Any, dependant: Dependant |
|
|
) -> Optional[bool]: |
|
|
) -> bool | None: |
|
|
if lenient_issubclass(type_annotation, Request): |
|
|
if lenient_issubclass(type_annotation, Request): |
|
|
dependant.request_param_name = param_name |
|
|
dependant.request_param_name = param_name |
|
|
return True |
|
|
return True |
|
|
@ -353,8 +353,8 @@ def add_non_field_param_to_dependency( |
|
|
@dataclass |
|
|
@dataclass |
|
|
class ParamDetails: |
|
|
class ParamDetails: |
|
|
type_annotation: Any |
|
|
type_annotation: Any |
|
|
depends: Optional[params.Depends] |
|
|
depends: params.Depends | None |
|
|
field: Optional[ModelField] |
|
|
field: ModelField | None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def analyze_param( |
|
|
def analyze_param( |
|
|
@ -396,7 +396,7 @@ def analyze_param( |
|
|
) |
|
|
) |
|
|
] |
|
|
] |
|
|
if fastapi_specific_annotations: |
|
|
if fastapi_specific_annotations: |
|
|
fastapi_annotation: Union[FieldInfo, params.Depends, None] = ( |
|
|
fastapi_annotation: FieldInfo | params.Depends | None = ( |
|
|
fastapi_specific_annotations[-1] |
|
|
fastapi_specific_annotations[-1] |
|
|
) |
|
|
) |
|
|
else: |
|
|
else: |
|
|
@ -557,20 +557,20 @@ async def _solve_generator( |
|
|
class SolvedDependency: |
|
|
class SolvedDependency: |
|
|
values: dict[str, Any] |
|
|
values: dict[str, Any] |
|
|
errors: list[Any] |
|
|
errors: list[Any] |
|
|
background_tasks: Optional[StarletteBackgroundTasks] |
|
|
background_tasks: StarletteBackgroundTasks | None |
|
|
response: Response |
|
|
response: Response |
|
|
dependency_cache: dict[DependencyCacheKey, Any] |
|
|
dependency_cache: dict[DependencyCacheKey, Any] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def solve_dependencies( |
|
|
async def solve_dependencies( |
|
|
*, |
|
|
*, |
|
|
request: Union[Request, WebSocket], |
|
|
request: Request | WebSocket, |
|
|
dependant: Dependant, |
|
|
dependant: Dependant, |
|
|
body: Optional[Union[dict[str, Any], FormData]] = None, |
|
|
body: dict[str, Any] | FormData | None = None, |
|
|
background_tasks: Optional[StarletteBackgroundTasks] = None, |
|
|
background_tasks: StarletteBackgroundTasks | None = None, |
|
|
response: Optional[Response] = None, |
|
|
response: Response | None = None, |
|
|
dependency_overrides_provider: Optional[Any] = None, |
|
|
dependency_overrides_provider: Any | None = None, |
|
|
dependency_cache: Optional[dict[DependencyCacheKey, Any]] = None, |
|
|
dependency_cache: dict[DependencyCacheKey, Any] | None = None, |
|
|
# TODO: remove this parameter later, no longer used, not removing it yet as some |
|
|
# TODO: remove this parameter later, no longer used, not removing it yet as some |
|
|
# people might be monkey patching this function (although that's not supported) |
|
|
# people might be monkey patching this function (although that's not supported) |
|
|
async_exit_stack: AsyncExitStack, |
|
|
async_exit_stack: AsyncExitStack, |
|
|
@ -718,7 +718,7 @@ def _is_json_field(field: ModelField) -> bool: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_multidict_value( |
|
|
def _get_multidict_value( |
|
|
field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None |
|
|
field: ModelField, values: Mapping[str, Any], alias: str | None = None |
|
|
) -> Any: |
|
|
) -> Any: |
|
|
alias = alias or get_validation_alias(field) |
|
|
alias = alias or get_validation_alias(field) |
|
|
if ( |
|
|
if ( |
|
|
@ -750,7 +750,7 @@ def _get_multidict_value( |
|
|
|
|
|
|
|
|
def request_params_to_args( |
|
|
def request_params_to_args( |
|
|
fields: Sequence[ModelField], |
|
|
fields: Sequence[ModelField], |
|
|
received_params: Union[Mapping[str, Any], QueryParams, Headers], |
|
|
received_params: Mapping[str, Any] | QueryParams | Headers, |
|
|
) -> tuple[dict[str, Any], list[Any]]: |
|
|
) -> tuple[dict[str, Any], list[Any]]: |
|
|
values: dict[str, Any] = {} |
|
|
values: dict[str, Any] = {} |
|
|
errors: list[dict[str, Any]] = [] |
|
|
errors: list[dict[str, Any]] = [] |
|
|
@ -898,7 +898,7 @@ async def _extract_form_body( |
|
|
): |
|
|
): |
|
|
# For types |
|
|
# For types |
|
|
assert isinstance(value, sequence_types) |
|
|
assert isinstance(value, sequence_types) |
|
|
results: list[Union[bytes, str]] = [] |
|
|
results: list[bytes | str] = [] |
|
|
for sub_value in value: |
|
|
for sub_value in value: |
|
|
results.append(await sub_value.read()) |
|
|
results.append(await sub_value.read()) |
|
|
value = serialize_sequence_value(field=field, value=results) |
|
|
value = serialize_sequence_value(field=field, value=results) |
|
|
@ -917,7 +917,7 @@ async def _extract_form_body( |
|
|
|
|
|
|
|
|
async def request_body_to_args( |
|
|
async def request_body_to_args( |
|
|
body_fields: list[ModelField], |
|
|
body_fields: list[ModelField], |
|
|
received_body: Optional[Union[dict[str, Any], FormData]], |
|
|
received_body: dict[str, Any] | FormData | None, |
|
|
embed_body_fields: bool, |
|
|
embed_body_fields: bool, |
|
|
) -> tuple[dict[str, Any], list[dict[str, Any]]]: |
|
|
) -> tuple[dict[str, Any], list[dict[str, Any]]]: |
|
|
values: dict[str, Any] = {} |
|
|
values: dict[str, Any] = {} |
|
|
@ -947,7 +947,7 @@ async def request_body_to_args( |
|
|
return {first_field.name: v_}, errors_ |
|
|
return {first_field.name: v_}, errors_ |
|
|
for field in body_fields: |
|
|
for field in body_fields: |
|
|
loc = ("body", get_validation_alias(field)) |
|
|
loc = ("body", get_validation_alias(field)) |
|
|
value: Optional[Any] = None |
|
|
value: Any | None = None |
|
|
if body_to_process is not None: |
|
|
if body_to_process is not None: |
|
|
try: |
|
|
try: |
|
|
value = body_to_process.get(get_validation_alias(field)) |
|
|
value = body_to_process.get(get_validation_alias(field)) |
|
|
@ -967,7 +967,7 @@ async def request_body_to_args( |
|
|
|
|
|
|
|
|
def get_body_field( |
|
|
def get_body_field( |
|
|
*, flat_dependant: Dependant, name: str, embed_body_fields: bool |
|
|
*, flat_dependant: Dependant, name: str, embed_body_fields: bool |
|
|
) -> Optional[ModelField]: |
|
|
) -> ModelField | None: |
|
|
""" |
|
|
""" |
|
|
Get a ModelField representing the request body for a path operation, combining |
|
|
Get a ModelField representing the request body for a path operation, combining |
|
|
all body parameters into a single field if necessary. |
|
|
all body parameters into a single field if necessary. |
|
|
|