-from typing import Annotated, List, Union
+from typing import Annotated, Union
from fastapi import FastAPI, Header
@app.get("/items/")
-async def read_items(x_token: Annotated[Union[List[str], None], Header()] = None):
+async def read_items(x_token: Annotated[Union[list[str], None], Header()] = None):
return {"X-Token values": x_token}
import sys
+from collections.abc import Sequence
from functools import lru_cache
from typing import (
Any,
- Dict,
- List,
- Sequence,
- Tuple,
- Type,
)
from fastapi._compat import may_v1
@lru_cache
-def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+def get_cached_model_fields(model: type[BaseModel]) -> list[ModelField]:
if lenient_issubclass(model, may_v1.BaseModel):
from fastapi._compat import v1
def create_body_model(
*, fields: Sequence[ModelField], model_name: str
-) -> Type[BaseModel]:
+) -> type[BaseModel]:
if fields and isinstance(fields[0], may_v1.ModelField):
from fastapi._compat import v1
return v2.serialize_sequence_value(field=field, value=value) # type: ignore[arg-type]
-def _model_rebuild(model: Type[BaseModel]) -> None:
+def _model_rebuild(model: type[BaseModel]) -> None:
if lenient_issubclass(model, may_v1.BaseModel):
from fastapi._compat import v1
v2._model_rebuild(model)
-def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
+def get_compat_model_name_map(fields: list[ModelField]) -> ModelNameMap:
v1_model_fields = [
field for field in fields if isinstance(field, may_v1.ModelField)
]
def get_definitions(
*,
- fields: List[ModelField],
+ fields: list[ModelField],
model_name_map: ModelNameMap,
separate_input_output_schemas: bool = True,
-) -> Tuple[
- Dict[
- Tuple[ModelField, Literal["validation", "serialization"]],
+) -> tuple[
+ dict[
+ tuple[ModelField, Literal["validation", "serialization"]],
may_v1.JsonSchemaValue,
],
- Dict[str, Dict[str, Any]],
+ dict[str, dict[str, Any]],
]:
if sys.version_info < (3, 14):
v1_fields = [field for field in fields if isinstance(field, may_v1.ModelField)]
*,
field: ModelField,
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]],
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]],
may_v1.JsonSchemaValue,
],
separate_input_output_schemas: bool = True,
-) -> Dict[str, Any]:
+) -> dict[str, Any]:
if isinstance(field, may_v1.ModelField):
from fastapi._compat import v1
import sys
-from typing import Any, Dict, List, Literal, Sequence, Tuple, Type, Union
+from collections.abc import Sequence
+from typing import Any, Literal, Union
from fastapi.types import ModelNameMap
def get_definitions(
*,
- fields: List[ModelField],
+ fields: list[ModelField],
model_name_map: ModelNameMap,
separate_input_output_schemas: bool = True,
- ) -> Tuple[
- Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ) -> tuple[
+ dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
- Dict[str, Dict[str, Any]],
+ dict[str, dict[str, Any]],
]:
return {}, {} # pragma: no cover
from .v1 import get_definitions as get_definitions
-RequestErrorModel: Type[BaseModel] = create_model("Request")
+RequestErrorModel: type[BaseModel] = create_model("Request")
-def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
- use_errors: List[Any] = []
+def _normalize_errors(errors: Sequence[Any]) -> list[dict[str, Any]]:
+ use_errors: list[Any] = []
for error in errors:
if isinstance(error, ErrorWrapper):
new_errors = ValidationError( # type: ignore[call-arg]
def _regenerate_error_with_loc(
- *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]
-) -> List[Dict[str, Any]]:
- updated_loc_errors: List[Any] = [
+ *, errors: Sequence[Any], loc_prefix: tuple[Union[str, int], ...]
+) -> list[dict[str, Any]]:
+ updated_loc_errors: list[Any] = [
{**err, "loc": loc_prefix + err.get("loc", ())}
for err in _normalize_errors(errors)
]
from typing import (
Any,
- Dict,
- List,
- Tuple,
Union,
)
def validate(
self,
value: Any,
- values: Dict[str, Any] = {}, # noqa: B006
+ values: dict[str, Any] = {}, # noqa: B006
*,
- loc: Tuple[Union[int, str], ...] = (),
- ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]: ...
+ loc: tuple[Union[int, str], ...] = (),
+ ) -> tuple[Any, Union[list[dict[str, Any]], None]]: ...
def serialize(
self,
import types
import typing
from collections import deque
+from collections.abc import Mapping, Sequence
from dataclasses import is_dataclass
from typing import (
+ Annotated,
Any,
- Deque,
- FrozenSet,
- List,
- Mapping,
- Sequence,
- Set,
- Tuple,
- Type,
Union,
)
from pydantic import BaseModel
from pydantic.version import VERSION as PYDANTIC_VERSION
from starlette.datastructures import UploadFile
-from typing_extensions import Annotated, get_args, get_origin
+from typing_extensions import get_args, get_origin
# Copy from Pydantic v2, compatible with v1
if sys.version_info < (3, 10):
sequence_annotation_to_type = {
Sequence: list,
- List: list,
list: list,
- Tuple: tuple,
tuple: tuple,
- Set: set,
set: set,
- FrozenSet: frozenset,
frozenset: frozenset,
- Deque: deque,
deque: deque,
}
sequence_types = tuple(sequence_annotation_to_type.keys())
-Url: Type[Any]
+Url: type[Any]
# Copy of Pydantic v2, compatible with v1
def lenient_issubclass(
- cls: Any, class_or_tuple: Union[Type[Any], Tuple[Type[Any], ...], None]
+ cls: Any, class_or_tuple: Union[type[Any], tuple[type[Any], ...], None]
) -> bool:
try:
return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type]
raise # pragma: no cover
-def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
+def _annotation_is_sequence(annotation: Union[type[Any], None]) -> bool:
if lenient_issubclass(annotation, (str, bytes)):
return False
- return lenient_issubclass(annotation, sequence_types) # type: ignore[arg-type]
+ return lenient_issubclass(annotation, sequence_types)
-def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
+def field_annotation_is_sequence(annotation: Union[type[Any], None]) -> bool:
origin = get_origin(annotation)
if origin is Union or origin is UnionType:
for arg in get_args(annotation):
def value_is_sequence(value: Any) -> bool:
- return isinstance(value, sequence_types) and not isinstance(value, (str, bytes)) # type: ignore[arg-type]
+ return isinstance(value, sequence_types) and not isinstance(value, (str, bytes))
-def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
+def _annotation_is_complex(annotation: Union[type[Any], None]) -> bool:
return (
lenient_issubclass(
annotation, (BaseModel, may_v1.BaseModel, Mapping, UploadFile)
)
-def field_annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
+def field_annotation_is_complex(annotation: Union[type[Any], None]) -> bool:
origin = get_origin(annotation)
if origin is Union or origin is UnionType:
return any(field_annotation_is_complex(arg) for arg in get_args(annotation))
return annotation is Ellipsis or not field_annotation_is_complex(annotation)
-def field_annotation_is_scalar_sequence(annotation: Union[Type[Any], None]) -> bool:
+def field_annotation_is_scalar_sequence(annotation: Union[type[Any], None]) -> bool:
origin = get_origin(annotation)
if origin is Union or origin is UnionType:
at_least_one_scalar_sequence = False
+from collections.abc import Sequence
from copy import copy
from dataclasses import dataclass, is_dataclass
from enum import Enum
from typing import (
Any,
Callable,
- Dict,
- List,
- Sequence,
- Set,
- Tuple,
- Type,
Union,
)
GetJsonSchemaHandler = Any
-JsonSchemaValue = Dict[str, Any]
+JsonSchemaValue = dict[str, Any]
CoreSchema = Any
Url = AnyUrl
pass
-RequestErrorModel: Type[BaseModel] = create_model("Request")
+RequestErrorModel: type[BaseModel] = create_model("Request")
def with_info_plain_validator_function(
def get_model_definitions(
*,
- flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
- model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
-) -> Dict[str, Any]:
- definitions: Dict[str, Dict[str, Any]] = {}
+ flat_models: set[Union[type[BaseModel], type[Enum]]],
+ model_name_map: dict[Union[type[BaseModel], type[Enum]], str],
+) -> dict[str, Any]:
+ definitions: dict[str, dict[str, Any]] = {}
for model in flat_models:
m_schema, m_definitions, m_nested_models = model_process_schema(
model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
return False
-def _model_rebuild(model: Type[BaseModel]) -> None:
+def _model_rebuild(model: type[BaseModel]) -> None:
model.update_forward_refs()
*,
field: ModelField,
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
separate_input_output_schemas: bool = True,
-) -> Dict[str, Any]:
+) -> dict[str, Any]:
return field_schema( # type: ignore[no-any-return]
field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
)[0]
def get_definitions(
*,
- fields: List[ModelField],
+ fields: list[ModelField],
model_name_map: ModelNameMap,
separate_input_output_schemas: bool = True,
-) -> Tuple[
- Dict[Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
- Dict[str, Dict[str, Any]],
+) -> tuple[
+ dict[tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
+ dict[str, dict[str, Any]],
]:
models = get_flat_models_from_fields(fields, known_models=set())
return {}, get_model_definitions(flat_models=models, model_name_map=model_name_map)
return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return]
-def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
+def get_missing_field_error(loc: tuple[str, ...]) -> dict[str, Any]:
missing_field_error = ErrorWrapper(MissingError(), loc=loc)
new_error = ValidationError([missing_field_error], RequestErrorModel)
return new_error.errors()[0] # type: ignore[return-value]
def create_body_model(
*, fields: Sequence[ModelField], model_name: str
-) -> Type[BaseModel]:
+) -> type[BaseModel]:
BodyModel = create_model(model_name)
for f in fields:
BodyModel.__fields__[f.name] = f # type: ignore[index]
return BodyModel
-def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+def get_model_fields(model: type[BaseModel]) -> list[ModelField]:
return list(model.__fields__.values()) # type: ignore[attr-defined]
import re
import warnings
+from collections.abc import Sequence
from copy import copy, deepcopy
from dataclasses import dataclass, is_dataclass
from enum import Enum
from typing import (
+ Annotated,
Any,
- Dict,
- List,
- Sequence,
- Set,
- Tuple,
- Type,
Union,
cast,
)
from pydantic_core import CoreSchema as CoreSchema
from pydantic_core import PydanticUndefined, PydanticUndefinedType
from pydantic_core import Url as Url
-from typing_extensions import Annotated, Literal, get_args, get_origin
+from typing_extensions import Literal, get_args, get_origin
try:
from pydantic_core.core_schema import (
# TODO: remove when dropping support for Pydantic < v2.12.3
-def asdict(field_info: FieldInfo) -> Dict[str, Any]:
+def asdict(field_info: FieldInfo) -> dict[str, Any]:
attributes = {}
for attr in _Attrs:
value = getattr(field_info, attr, Undefined)
def validate(
self,
value: Any,
- values: Dict[str, Any] = {}, # noqa: B006
+ values: dict[str, Any] = {}, # noqa: B006
*,
- loc: Tuple[Union[int, str], ...] = (),
- ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:
+ loc: tuple[Union[int, str], ...] = (),
+ ) -> tuple[Any, Union[list[dict[str, Any]], None]]:
try:
return (
self._type_adapter.validate_python(value, from_attributes=True),
return annotation
-def _model_rebuild(model: Type[BaseModel]) -> None:
+def _model_rebuild(model: type[BaseModel]) -> None:
model.model_rebuild()
*,
field: ModelField,
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
separate_input_output_schemas: bool = True,
-) -> Dict[str, Any]:
+) -> dict[str, Any]:
override_mode: Union[Literal["validation"], None] = (
None
if (separate_input_output_schemas or _has_computed_fields(field))
fields: Sequence[ModelField],
model_name_map: ModelNameMap,
separate_input_output_schemas: bool = True,
-) -> Tuple[
- Dict[Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
- Dict[str, Dict[str, Any]],
+) -> tuple[
+ dict[tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
+ dict[str, dict[str, Any]],
]:
schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE)
validation_fields = [field for field in fields if field.mode == "validation"]
for field in list(fields) + list(unique_flat_model_fields)
]
field_mapping, definitions = schema_generator.generate_definitions(inputs=inputs)
- for item_def in cast(Dict[str, Dict[str, Any]], definitions).values():
+ for item_def in cast(dict[str, dict[str, Any]], definitions).values():
if "description" in item_def:
item_description = cast(str, item_def["description"]).split("\f")[0]
item_def["description"] = item_description
def _replace_refs(
*,
- schema: Dict[str, Any],
- old_name_to_new_name_map: Dict[str, str],
-) -> Dict[str, Any]:
+ schema: dict[str, Any],
+ old_name_to_new_name_map: dict[str, str],
+) -> dict[str, Any]:
new_schema = deepcopy(schema)
for key, value in new_schema.items():
if key == "$ref":
def _remap_definitions_and_field_mappings(
*,
model_name_map: ModelNameMap,
- definitions: Dict[str, Any],
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ definitions: dict[str, Any],
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
-) -> Tuple[
- Dict[Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
- Dict[str, Any],
+) -> tuple[
+ dict[tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue],
+ dict[str, Any],
]:
old_name_to_new_name_map = {}
for field_key, schema in field_mapping.items():
continue
old_name_to_new_name_map[old_name] = new_name
- new_field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ new_field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
] = {}
for field_key, schema in field_mapping.items():
new_schema = _replace_refs(
origin_type = get_origin(union_arg) or union_arg
break
assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type]
- return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return]
+ return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return,index]
-def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
+def get_missing_field_error(loc: tuple[str, ...]) -> dict[str, Any]:
error = ValidationError.from_exception_data(
"Field required", [{"type": "missing", "loc": loc, "input": {}}]
).errors(include_url=False)[0]
def create_body_model(
*, fields: Sequence[ModelField], model_name: str
-) -> Type[BaseModel]:
+) -> type[BaseModel]:
field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields}
- BodyModel: Type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload]
+ BodyModel: type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload]
return BodyModel
-def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
- model_fields: List[ModelField] = []
+def get_model_fields(model: type[BaseModel]) -> list[ModelField]:
+ model_fields: list[ModelField] = []
for name, field_info in model.model_fields.items():
type_ = field_info.annotation
if lenient_issubclass(type_, (BaseModel, dict)) or is_dataclass(type_):
# Duplicate of several schema functions from Pydantic v1 to make them compatible with
# Pydantic v2 and allow mixing the models
-TypeModelOrEnum = Union[Type["BaseModel"], Type[Enum]]
-TypeModelSet = Set[TypeModelOrEnum]
+TypeModelOrEnum = Union[type["BaseModel"], type[Enum]]
+TypeModelSet = set[TypeModelOrEnum]
def normalize_name(name: str) -> str:
return re.sub(r"[^a-zA-Z0-9.\-_]", "_", name)
-def get_model_name_map(unique_models: TypeModelSet) -> Dict[TypeModelOrEnum, str]:
+def get_model_name_map(unique_models: TypeModelSet) -> dict[TypeModelOrEnum, str]:
name_model_map = {}
- conflicting_names: Set[str] = set()
+ conflicting_names: set[str] = set()
for model in unique_models:
model_name = normalize_name(model.__name__)
if model_name in conflicting_names:
def get_flat_models_from_model(
- model: Type["BaseModel"], known_models: Union[TypeModelSet, None] = None
+ model: type["BaseModel"], known_models: Union[TypeModelSet, None] = None
) -> TypeModelSet:
known_models = known_models or set()
fields = get_model_fields(model)
+from collections.abc import Awaitable, Coroutine, Sequence
from enum import Enum
from typing import (
+ Annotated,
Any,
- Awaitable,
Callable,
- Coroutine,
- Dict,
- List,
Optional,
- Sequence,
- Type,
TypeVar,
Union,
)
from starlette.responses import HTMLResponse, JSONResponse, Response
from starlette.routing import BaseRoute
from starlette.types import ASGIApp, ExceptionHandler, Lifespan, Receive, Scope, Send
-from typing_extensions import Annotated, deprecated
+from typing_extensions import deprecated
AppType = TypeVar("AppType", bound="FastAPI")
),
] = False,
routes: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
**Note**: you probably shouldn't use this parameter, it is inherited
),
] = "/openapi.json",
openapi_tags: Annotated[
- Optional[List[Dict[str, Any]]],
+ Optional[list[dict[str, Any]]],
Doc(
"""
A list of tags used by OpenAPI, these are the same `tags` you can set
),
] = None,
servers: Annotated[
- Optional[List[Dict[str, Union[str, Any]]]],
+ Optional[list[dict[str, Union[str, Any]]]],
Doc(
"""
A `list` of `dict`s with connectivity information to a target server.
),
] = None,
default_response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
The default response class to be used.
),
] = "/docs/oauth2-redirect",
swagger_ui_init_oauth: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
OAuth2 configuration for the Swagger UI, by default shown at `/docs`.
] = None,
exception_handlers: Annotated[
Optional[
- Dict[
- Union[int, Type[Exception]],
+ dict[
+ Union[int, type[Exception]],
Callable[[Request, Any], Coroutine[Any, Any, Response]],
]
],
),
] = None,
contact: Annotated[
- Optional[Dict[str, Union[str, Any]]],
+ Optional[dict[str, Union[str, Any]]],
Doc(
"""
A dictionary with the contact information for the exposed API.
),
] = None,
license_info: Annotated[
- Optional[Dict[str, Union[str, Any]]],
+ Optional[dict[str, Union[str, Any]]],
Doc(
"""
A dictionary with the license information for the exposed API.
),
] = True,
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses to be shown in OpenAPI.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
OpenAPI callbacks that should apply to all *path operations*.
),
] = True,
swagger_ui_parameters: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Parameters to configure Swagger UI, the autogenerated interactive API
),
] = True,
openapi_external_docs: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
This field allows you to provide additional external documentation links.
"""
),
] = "3.1.0"
- self.openapi_schema: Optional[Dict[str, Any]] = None
+ self.openapi_schema: Optional[dict[str, Any]] = None
if self.openapi_url:
assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'"
assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'"
),
] = State()
self.dependency_overrides: Annotated[
- Dict[Callable[..., Any], Callable[..., Any]],
+ dict[Callable[..., Any], Callable[..., Any]],
Doc(
"""
A dictionary with overrides for the dependencies.
responses=responses,
generate_unique_id_function=generate_unique_id_function,
)
- self.exception_handlers: Dict[
+ self.exception_handlers: dict[
Any, Callable[[Request, Any], Union[Response, Awaitable[Response]]]
] = {} if exception_handlers is None else dict(exception_handlers)
self.exception_handlers.setdefault(HTTPException, http_exception_handler)
websocket_request_validation_exception_handler, # type: ignore
)
- self.user_middleware: List[Middleware] = (
+ self.user_middleware: list[Middleware] = (
[] if middleware is None else list(middleware)
)
self.middleware_stack: Union[ASGIApp, None] = None
app = cls(app, *args, **kwargs)
return app
- def openapi(self) -> Dict[str, Any]:
+ def openapi(self) -> dict[str, Any]:
"""
Generate the OpenAPI schema of the application. This is called by FastAPI
internally.
*,
response_model: Any = Default(None),
status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
+ tags: Optional[list[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
- methods: Optional[List[str]] = None,
+ methods: Optional[list[str]] = None,
operation_id: Optional[str] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
include_in_schema: bool = True,
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ response_class: Union[type[Response], DefaultPlaceholder] = Default(
JSONResponse
),
name: Optional[str] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
+ openapi_extra: Optional[dict[str, Any]] = None,
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
generate_unique_id
),
*,
response_model: Any = Default(None),
status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
+ tags: Optional[list[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
- methods: Optional[List[str]] = None,
+ methods: Optional[list[str]] = None,
operation_id: Optional[str] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
+ response_class: type[Response] = Default(JSONResponse),
name: Optional[str] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
+ openapi_extra: Optional[dict[str, Any]] = None,
generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
generate_unique_id
),
*,
prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to all the *path operations* in this
),
] = None,
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses to be shown in OpenAPI.
),
] = True,
default_response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Default response class to be used for the *path operations* in this
),
] = Default(JSONResponse),
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
def exception_handler(
self,
exc_class_or_status_code: Annotated[
- Union[int, Type[Exception]],
+ Union[int, type[Exception]],
Doc(
"""
The Exception class this would handle, or a status code.
-from typing import Any, Callable
+from typing import Annotated, Any, Callable
from annotated_doc import Doc
from starlette.background import BackgroundTasks as StarletteBackgroundTasks
-from typing_extensions import Annotated, ParamSpec
+from typing_extensions import ParamSpec
P = ParamSpec("P")
+from collections.abc import AsyncGenerator
+from contextlib import AbstractContextManager
from contextlib import asynccontextmanager as asynccontextmanager
-from typing import AsyncGenerator, ContextManager, TypeVar
+from typing import TypeVar
import anyio.to_thread
from anyio import CapacityLimiter
@asynccontextmanager
async def contextmanager_in_threadpool(
- cm: ContextManager[_T],
+ cm: AbstractContextManager[_T],
) -> AsyncGenerator[_T, None]:
# blocking __exit__ from running waiting on a free thread
# can create race conditions/deadlocks if the context manager itself
+from collections.abc import Iterable
from typing import (
+ Annotated,
Any,
BinaryIO,
Callable,
- Dict,
- Iterable,
Optional,
- Type,
TypeVar,
cast,
)
from starlette.datastructures import QueryParams as QueryParams # noqa: F401
from starlette.datastructures import State as State # noqa: F401
from starlette.datastructures import UploadFile as StarletteUploadFile
-from typing_extensions import Annotated
class UploadFile(StarletteUploadFile):
return await super().close()
@classmethod
- def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
+ def __get_validators__(cls: type["UploadFile"]) -> Iterable[Callable[..., Any]]:
yield cls.validate
@classmethod
- def validate(cls: Type["UploadFile"], v: Any) -> Any:
+ def validate(cls: type["UploadFile"], v: Any) -> Any:
if not isinstance(v, StarletteUploadFile):
raise ValueError(f"Expected UploadFile, received: {type(v)}")
return v
# TODO: remove when deprecating Pydantic v1
@classmethod
- def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
+ def __modify_schema__(cls, field_schema: dict[str, Any]) -> None:
field_schema.update({"type": "string", "format": "binary"})
@classmethod
@classmethod
def __get_pydantic_core_schema__(
- cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+ cls, source: type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
from ._compat.v2 import with_info_plain_validator_function
import sys
from dataclasses import dataclass, field
from functools import cached_property, partial
-from typing import Any, Callable, List, Optional, Union
+from typing import Any, Callable, Optional, Union
from fastapi._compat import ModelField
from fastapi.security.base import SecurityBase
@dataclass
class Dependant:
- path_params: List[ModelField] = field(default_factory=list)
- query_params: List[ModelField] = field(default_factory=list)
- header_params: List[ModelField] = field(default_factory=list)
- cookie_params: List[ModelField] = field(default_factory=list)
- body_params: List[ModelField] = field(default_factory=list)
- dependencies: List["Dependant"] = field(default_factory=list)
+ path_params: list[ModelField] = field(default_factory=list)
+ query_params: list[ModelField] = field(default_factory=list)
+ header_params: list[ModelField] = field(default_factory=list)
+ cookie_params: list[ModelField] = field(default_factory=list)
+ body_params: list[ModelField] = field(default_factory=list)
+ dependencies: list["Dependant"] = field(default_factory=list)
name: Optional[str] = None
call: Optional[Callable[..., Any]] = None
request_param_name: Optional[str] = None
response_param_name: Optional[str] = None
background_tasks_param_name: Optional[str] = None
security_scopes_param_name: Optional[str] = None
- own_oauth_scopes: Optional[List[str]] = None
- parent_oauth_scopes: Optional[List[str]] = None
+ own_oauth_scopes: Optional[list[str]] = None
+ parent_oauth_scopes: Optional[list[str]] = None
use_cache: bool = True
path: Optional[str] = None
scope: Union[Literal["function", "request"], None] = None
@cached_property
- def oauth_scopes(self) -> List[str]:
+ def oauth_scopes(self) -> list[str]:
scopes = self.parent_oauth_scopes.copy() if self.parent_oauth_scopes else []
# This doesn't use a set to preserve order, just in case
for scope in self.own_oauth_scopes or []:
return unwrapped
@cached_property
- def _security_dependencies(self) -> List["Dependant"]:
+ def _security_dependencies(self) -> list["Dependant"]:
security_deps = [dep for dep in self.dependencies if dep._is_security_scheme]
return security_deps
import dataclasses
import inspect
import sys
+from collections.abc import Coroutine, Mapping, Sequence
from contextlib import AsyncExitStack, contextmanager
from copy import copy, deepcopy
from dataclasses import dataclass
from typing import (
+ Annotated,
Any,
Callable,
- Coroutine,
- Dict,
ForwardRef,
- List,
- Mapping,
Optional,
- Sequence,
- Tuple,
- Type,
Union,
cast,
)
from starlette.requests import HTTPConnection, Request
from starlette.responses import Response
from starlette.websockets import WebSocket
-from typing_extensions import Annotated, Literal, get_args, get_origin
+from typing_extensions import Literal, get_args, get_origin
from .. import temp_pydantic_v1_params
assert callable(depends.dependency), (
"A parameter-less dependency must have a callable dependency"
)
- own_oauth_scopes: List[str] = []
+ own_oauth_scopes: list[str] = []
if isinstance(depends, params.Security) and depends.scopes:
own_oauth_scopes.extend(depends.scopes)
return get_dependant(
dependant: Dependant,
*,
skip_repeats: bool = False,
- visited: Optional[List[DependencyCacheKey]] = None,
- parent_oauth_scopes: Optional[List[str]] = None,
+ visited: Optional[list[DependencyCacheKey]] = None,
+ parent_oauth_scopes: Optional[list[str]] = None,
) -> Dependant:
if visited is None:
visited = []
return flat_dependant
-def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
+def _get_flat_fields_from_params(fields: list[ModelField]) -> list[ModelField]:
if not fields:
return fields
first_field = fields[0]
return fields
-def get_flat_params(dependant: Dependant) -> List[ModelField]:
+def get_flat_params(dependant: Dependant) -> list[ModelField]:
flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
path_params = _get_flat_fields_from_params(flat_dependant.path_params)
query_params = _get_flat_fields_from_params(flat_dependant.query_params)
return typed_signature
-def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any:
+def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any:
if isinstance(annotation, str):
annotation = ForwardRef(annotation)
annotation = evaluate_forwardref(annotation, globalns, globalns)
path: str,
call: Callable[..., Any],
name: Optional[str] = None,
- own_oauth_scopes: Optional[List[str]] = None,
- parent_oauth_scopes: Optional[List[str]] = None,
+ own_oauth_scopes: Optional[list[str]] = None,
+ parent_oauth_scopes: Optional[list[str]] = None,
use_cache: bool = True,
scope: Union[Literal["function", "request"], None] = None,
) -> Dependant:
f'The dependency "{dependant.call.__name__}" has a scope of '
'"request", it cannot depend on dependencies with scope "function".'
)
- sub_own_oauth_scopes: List[str] = []
+ sub_own_oauth_scopes: list[str] = []
if isinstance(param_details.depends, params.Security):
if param_details.depends.scopes:
sub_own_oauth_scopes = list(param_details.depends.scopes)
async def _solve_generator(
- *, dependant: Dependant, stack: AsyncExitStack, sub_values: Dict[str, Any]
+ *, dependant: Dependant, stack: AsyncExitStack, sub_values: dict[str, Any]
) -> Any:
assert dependant.call
if dependant.is_async_gen_callable:
@dataclass
class SolvedDependency:
- values: Dict[str, Any]
- errors: List[Any]
+ values: dict[str, Any]
+ errors: list[Any]
background_tasks: Optional[StarletteBackgroundTasks]
response: Response
- dependency_cache: Dict[DependencyCacheKey, Any]
+ dependency_cache: dict[DependencyCacheKey, Any]
async def solve_dependencies(
*,
request: Union[Request, WebSocket],
dependant: Dependant,
- body: Optional[Union[Dict[str, Any], FormData]] = None,
+ body: Optional[Union[dict[str, Any], FormData]] = None,
background_tasks: Optional[StarletteBackgroundTasks] = None,
response: Optional[Response] = None,
dependency_overrides_provider: Optional[Any] = None,
- dependency_cache: Optional[Dict[DependencyCacheKey, Any]] = None,
+ dependency_cache: Optional[dict[DependencyCacheKey, Any]] = None,
# 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)
async_exit_stack: AsyncExitStack,
assert isinstance(function_astack, AsyncExitStack), (
"fastapi_function_astack not found in request scope"
)
- values: Dict[str, Any] = {}
- errors: List[Any] = []
+ values: dict[str, Any] = {}
+ errors: list[Any] = []
if response is None:
response = Response()
del response.headers["content-length"]
def _validate_value_with_model_field(
- *, field: ModelField, value: Any, values: Dict[str, Any], loc: Tuple[str, ...]
-) -> Tuple[Any, List[Any]]:
+ *, field: ModelField, value: Any, values: dict[str, Any], loc: tuple[str, ...]
+) -> tuple[Any, list[Any]]:
if value is None:
if field.required:
return None, [get_missing_field_error(loc=loc)]
def request_params_to_args(
fields: Sequence[ModelField],
received_params: Union[Mapping[str, Any], QueryParams, Headers],
-) -> Tuple[Dict[str, Any], List[Any]]:
- values: Dict[str, Any] = {}
- errors: List[Dict[str, Any]] = []
+) -> tuple[dict[str, Any], list[Any]]:
+ values: dict[str, Any] = {}
+ errors: list[dict[str, Any]] = []
if not fields:
return values, errors
first_field.field_info, "convert_underscores", True
)
- params_to_process: Dict[str, Any] = {}
+ params_to_process: dict[str, Any] = {}
processed_keys = set()
assert isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param)), (
"Params must be subclasses of Param"
)
- loc: Tuple[str, ...] = (field_info.in_.value,)
+ loc: tuple[str, ...] = (field_info.in_.value,)
v_, errors_ = _validate_value_with_model_field(
field=first_field, value=params_to_process, values=values, loc=loc
)
return True
-def _should_embed_body_fields(fields: List[ModelField]) -> bool:
+def _should_embed_body_fields(fields: list[ModelField]) -> bool:
if not fields:
return False
# More than one dependency could have the same field, it would show up as multiple
async def _extract_form_body(
- body_fields: List[ModelField],
+ body_fields: list[ModelField],
received_body: FormData,
-) -> Dict[str, Any]:
+) -> dict[str, Any]:
values = {}
for field in body_fields:
and value_is_sequence(value)
):
# For types
- assert isinstance(value, sequence_types) # type: ignore[arg-type]
- results: List[Union[bytes, str]] = []
+ assert isinstance(value, sequence_types)
+ results: list[Union[bytes, str]] = []
async def process_fn(
fn: Callable[[], Coroutine[Any, Any, Any]],
async def request_body_to_args(
- body_fields: List[ModelField],
- received_body: Optional[Union[Dict[str, Any], FormData]],
+ body_fields: list[ModelField],
+ received_body: Optional[Union[dict[str, Any], FormData]],
embed_body_fields: bool,
-) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
- values: Dict[str, Any] = {}
- errors: List[Dict[str, Any]] = []
+) -> tuple[dict[str, Any], list[dict[str, Any]]]:
+ values: dict[str, Any] = {}
+ errors: list[dict[str, Any]] = []
assert body_fields, "request_body_to_args() should be called with fields"
single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields
first_field = body_fields[0]
body_to_process = received_body
- fields_to_extract: List[ModelField] = body_fields
+ fields_to_extract: list[ModelField] = body_fields
if (
single_not_embedded_field
body_to_process = await _extract_form_body(fields_to_extract, received_body)
if single_not_embedded_field:
- loc: Tuple[str, ...] = ("body",)
+ loc: tuple[str, ...] = ("body",)
v_, errors_ = _validate_value_with_model_field(
field=first_field, value=body_to_process, values=values, loc=loc
)
fields=flat_dependant.body_params, model_name=model_name
)
required = any(True for f in flat_dependant.body_params if f.required)
- BodyFieldInfo_kwargs: Dict[str, Any] = {
+ BodyFieldInfo_kwargs: dict[str, Any] = {
"annotation": BodyModel,
"alias": "body",
}
if not required:
BodyFieldInfo_kwargs["default"] = None
if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
- BodyFieldInfo: Type[params.Body] = params.File
+ BodyFieldInfo: type[params.Body] = params.File
elif any(
isinstance(f.field_info, temp_pydantic_v1_params.File)
for f in flat_dependant.body_params
):
- BodyFieldInfo: Type[temp_pydantic_v1_params.Body] = temp_pydantic_v1_params.File # type: ignore[no-redef]
+ BodyFieldInfo: type[temp_pydantic_v1_params.Body] = temp_pydantic_v1_params.File # type: ignore[no-redef]
elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
BodyFieldInfo = params.Form
elif any(
from pathlib import Path, PurePath
from re import Pattern
from types import GeneratorType
-from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
+from typing import Annotated, Any, Callable, Optional, Union
from uuid import UUID
from annotated_doc import Doc
from pydantic.color import Color
from pydantic.networks import AnyUrl, NameEmail
from pydantic.types import SecretBytes, SecretStr
-from typing_extensions import Annotated
from ._compat import Url, _is_undefined, _model_dump
return float(dec_value)
-ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
+ENCODERS_BY_TYPE: dict[type[Any], Callable[[Any], Any]] = {
bytes: lambda o: o.decode(),
Color: str,
may_v1.Color: str,
def generate_encoders_by_class_tuples(
- type_encoder_map: Dict[Any, Callable[[Any], Any]],
-) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]:
- encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(
+ type_encoder_map: dict[Any, Callable[[Any], Any]],
+) -> dict[Callable[[Any], Any], tuple[Any, ...]]:
+ encoders_by_class_tuples: dict[Callable[[Any], Any], tuple[Any, ...]] = defaultdict(
tuple
)
for type_, encoder in type_encoder_map.items():
),
] = False,
custom_encoder: Annotated[
- Optional[Dict[Any, Callable[[Any], Any]]],
+ Optional[dict[Any, Callable[[Any], Any]]],
Doc(
"""
Pydantic's `custom_encoder` parameter, passed to Pydantic models to define
exclude = set(exclude)
if isinstance(obj, (BaseModel, may_v1.BaseModel)):
# TODO: remove when deprecating Pydantic v1
- encoders: Dict[Any, Any] = {}
+ encoders: dict[Any, Any] = {}
if isinstance(obj, may_v1.BaseModel):
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
if custom_encoder:
try:
data = dict(obj)
except Exception as e:
- errors: List[Exception] = []
+ errors: list[Exception] = []
errors.append(e)
try:
data = vars(obj)
-from typing import Any, Dict, Optional, Sequence, Type, TypedDict, Union
+from collections.abc import Sequence
+from typing import Annotated, Any, Optional, TypedDict, Union
from annotated_doc import Doc
from pydantic import BaseModel, create_model
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.exceptions import WebSocketException as StarletteWebSocketException
-from typing_extensions import Annotated
class EndpointContext(TypedDict, total=False):
),
] = None,
headers: Annotated[
- Optional[Dict[str, str]],
+ Optional[dict[str, str]],
Doc(
"""
Any headers to send to the client in the response.
super().__init__(code=code, reason=reason)
-RequestErrorModel: Type[BaseModel] = create_model("Request")
-WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
+RequestErrorModel: type[BaseModel] = create_model("Request")
+WebSocketErrorModel: type[BaseModel] = create_model("WebSocket")
class FastAPIError(RuntimeError):
import json
-from typing import Any, Dict, Optional
+from typing import Annotated, Any, Optional
from annotated_doc import Doc
from fastapi.encoders import jsonable_encoder
from starlette.responses import HTMLResponse
-from typing_extensions import Annotated
swagger_ui_default_parameters: Annotated[
- Dict[str, Any],
+ dict[str, Any],
Doc(
"""
Default configurations for Swagger UI.
),
] = None,
init_oauth: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
A dictionary with Swagger UI OAuth2 initialization configurations.
),
] = None,
swagger_ui_parameters: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Configuration parameters for Swagger UI.
+from collections.abc import Iterable
from enum import Enum
-from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union
+from typing import Annotated, Any, Callable, Optional, Union
from fastapi._compat import (
PYDANTIC_V2,
)
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
-from typing_extensions import Annotated, Literal, TypedDict
+from typing_extensions import Literal, TypedDict
from typing_extensions import deprecated as typing_deprecated
try:
@classmethod
def __get_pydantic_core_schema__(
- cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+ cls, source: type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
return with_info_plain_validator_function(cls._validate)
class ServerVariable(BaseModelWithConfig):
- enum: Annotated[Optional[List[str]], Field(min_length=1)] = None
+ enum: Annotated[Optional[list[str]], Field(min_length=1)] = None
default: str
description: Optional[str] = None
class Server(BaseModelWithConfig):
url: Union[AnyUrl, str]
description: Optional[str] = None
- variables: Optional[Dict[str, ServerVariable]] = None
+ variables: Optional[dict[str, ServerVariable]] = None
class Reference(BaseModel):
class Discriminator(BaseModel):
propertyName: str
- mapping: Optional[Dict[str, str]] = None
+ mapping: Optional[dict[str, str]] = None
class XML(BaseModelWithConfig):
dynamicAnchor: Optional[str] = Field(default=None, alias="$dynamicAnchor")
ref: Optional[str] = Field(default=None, alias="$ref")
dynamicRef: Optional[str] = Field(default=None, alias="$dynamicRef")
- defs: Optional[Dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs")
+ defs: Optional[dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs")
comment: Optional[str] = Field(default=None, alias="$comment")
# Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-a-vocabulary-for-applying-s
# A Vocabulary for Applying Subschemas
- allOf: Optional[List["SchemaOrBool"]] = None
- anyOf: Optional[List["SchemaOrBool"]] = None
- oneOf: Optional[List["SchemaOrBool"]] = None
+ allOf: Optional[list["SchemaOrBool"]] = None
+ anyOf: Optional[list["SchemaOrBool"]] = None
+ oneOf: Optional[list["SchemaOrBool"]] = None
not_: Optional["SchemaOrBool"] = Field(default=None, alias="not")
if_: Optional["SchemaOrBool"] = Field(default=None, alias="if")
then: Optional["SchemaOrBool"] = None
else_: Optional["SchemaOrBool"] = Field(default=None, alias="else")
- dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None
- prefixItems: Optional[List["SchemaOrBool"]] = None
+ dependentSchemas: Optional[dict[str, "SchemaOrBool"]] = None
+ prefixItems: Optional[list["SchemaOrBool"]] = None
# TODO: uncomment and remove below when deprecating Pydantic v1
# It generates a list of schemas for tuples, before prefixItems was available
# items: Optional["SchemaOrBool"] = None
- items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None
+ items: Optional[Union["SchemaOrBool", list["SchemaOrBool"]]] = None
contains: Optional["SchemaOrBool"] = None
- properties: Optional[Dict[str, "SchemaOrBool"]] = None
- patternProperties: Optional[Dict[str, "SchemaOrBool"]] = None
+ properties: Optional[dict[str, "SchemaOrBool"]] = None
+ patternProperties: Optional[dict[str, "SchemaOrBool"]] = None
additionalProperties: Optional["SchemaOrBool"] = None
propertyNames: Optional["SchemaOrBool"] = None
unevaluatedItems: Optional["SchemaOrBool"] = None
unevaluatedProperties: Optional["SchemaOrBool"] = None
# Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural
# A Vocabulary for Structural Validation
- type: Optional[Union[SchemaType, List[SchemaType]]] = None
- enum: Optional[List[Any]] = None
+ type: Optional[Union[SchemaType, list[SchemaType]]] = None
+ enum: Optional[list[Any]] = None
const: Optional[Any] = None
multipleOf: Optional[float] = Field(default=None, gt=0)
maximum: Optional[float] = None
minContains: Optional[int] = Field(default=None, ge=0)
maxProperties: Optional[int] = Field(default=None, ge=0)
minProperties: Optional[int] = Field(default=None, ge=0)
- required: Optional[List[str]] = None
- dependentRequired: Optional[Dict[str, Set[str]]] = None
+ required: Optional[list[str]] = None
+ dependentRequired: Optional[dict[str, set[str]]] = None
# Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-vocabularies-for-semantic-c
# Vocabularies for Semantic Content With "format"
format: Optional[str] = None
deprecated: Optional[bool] = None
readOnly: Optional[bool] = None
writeOnly: Optional[bool] = None
- examples: Optional[List[Any]] = None
+ examples: Optional[list[Any]] = None
# Ref: OpenAPI 3.1.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object
# Schema Object
discriminator: Optional[Discriminator] = None
class Encoding(BaseModelWithConfig):
contentType: Optional[str] = None
- headers: Optional[Dict[str, Union["Header", Reference]]] = None
+ headers: Optional[dict[str, Union["Header", Reference]]] = None
style: Optional[str] = None
explode: Optional[bool] = None
allowReserved: Optional[bool] = None
class MediaType(BaseModelWithConfig):
schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
example: Optional[Any] = None
- examples: Optional[Dict[str, Union[Example, Reference]]] = None
- encoding: Optional[Dict[str, Encoding]] = None
+ examples: Optional[dict[str, Union[Example, Reference]]] = None
+ encoding: Optional[dict[str, Encoding]] = None
class ParameterBase(BaseModelWithConfig):
allowReserved: Optional[bool] = None
schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
example: Optional[Any] = None
- examples: Optional[Dict[str, Union[Example, Reference]]] = None
+ examples: Optional[dict[str, Union[Example, Reference]]] = None
# Serialization rules for more complex scenarios
- content: Optional[Dict[str, MediaType]] = None
+ content: Optional[dict[str, MediaType]] = None
class Parameter(ParameterBase):
class RequestBody(BaseModelWithConfig):
description: Optional[str] = None
- content: Dict[str, MediaType]
+ content: dict[str, MediaType]
required: Optional[bool] = None
class Link(BaseModelWithConfig):
operationRef: Optional[str] = None
operationId: Optional[str] = None
- parameters: Optional[Dict[str, Union[Any, str]]] = None
+ parameters: Optional[dict[str, Union[Any, str]]] = None
requestBody: Optional[Union[Any, str]] = None
description: Optional[str] = None
server: Optional[Server] = None
class Response(BaseModelWithConfig):
description: str
- headers: Optional[Dict[str, Union[Header, Reference]]] = None
- content: Optional[Dict[str, MediaType]] = None
- links: Optional[Dict[str, Union[Link, Reference]]] = None
+ headers: Optional[dict[str, Union[Header, Reference]]] = None
+ content: Optional[dict[str, MediaType]] = None
+ links: Optional[dict[str, Union[Link, Reference]]] = None
class Operation(BaseModelWithConfig):
- tags: Optional[List[str]] = None
+ tags: Optional[list[str]] = None
summary: Optional[str] = None
description: Optional[str] = None
externalDocs: Optional[ExternalDocumentation] = None
operationId: Optional[str] = None
- parameters: Optional[List[Union[Parameter, Reference]]] = None
+ parameters: Optional[list[Union[Parameter, Reference]]] = None
requestBody: Optional[Union[RequestBody, Reference]] = None
# Using Any for Specification Extensions
- responses: Optional[Dict[str, Union[Response, Any]]] = None
- callbacks: Optional[Dict[str, Union[Dict[str, "PathItem"], Reference]]] = None
+ responses: Optional[dict[str, Union[Response, Any]]] = None
+ callbacks: Optional[dict[str, Union[dict[str, "PathItem"], Reference]]] = None
deprecated: Optional[bool] = None
- security: Optional[List[Dict[str, List[str]]]] = None
- servers: Optional[List[Server]] = None
+ security: Optional[list[dict[str, list[str]]]] = None
+ servers: Optional[list[Server]] = None
class PathItem(BaseModelWithConfig):
head: Optional[Operation] = None
patch: Optional[Operation] = None
trace: Optional[Operation] = None
- servers: Optional[List[Server]] = None
- parameters: Optional[List[Union[Parameter, Reference]]] = None
+ servers: Optional[list[Server]] = None
+ parameters: Optional[list[Union[Parameter, Reference]]] = None
class SecuritySchemeType(Enum):
class OAuthFlow(BaseModelWithConfig):
refreshUrl: Optional[str] = None
- scopes: Dict[str, str] = {}
+ scopes: dict[str, str] = {}
class OAuthFlowImplicit(OAuthFlow):
class Components(BaseModelWithConfig):
- schemas: Optional[Dict[str, Union[Schema, Reference]]] = None
- responses: Optional[Dict[str, Union[Response, Reference]]] = None
- parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
- examples: Optional[Dict[str, Union[Example, Reference]]] = None
- requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
- headers: Optional[Dict[str, Union[Header, Reference]]] = None
- securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
- links: Optional[Dict[str, Union[Link, Reference]]] = None
+ schemas: Optional[dict[str, Union[Schema, Reference]]] = None
+ responses: Optional[dict[str, Union[Response, Reference]]] = None
+ parameters: Optional[dict[str, Union[Parameter, Reference]]] = None
+ examples: Optional[dict[str, Union[Example, Reference]]] = None
+ requestBodies: Optional[dict[str, Union[RequestBody, Reference]]] = None
+ headers: Optional[dict[str, Union[Header, Reference]]] = None
+ securitySchemes: Optional[dict[str, Union[SecurityScheme, Reference]]] = None
+ links: Optional[dict[str, Union[Link, Reference]]] = None
# Using Any for Specification Extensions
- callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
- pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
+ callbacks: Optional[dict[str, Union[dict[str, PathItem], Reference, Any]]] = None
+ pathItems: Optional[dict[str, Union[PathItem, Reference]]] = None
class Tag(BaseModelWithConfig):
openapi: str
info: Info
jsonSchemaDialect: Optional[str] = None
- servers: Optional[List[Server]] = None
+ servers: Optional[list[Server]] = None
# Using Any for Specification Extensions
- paths: Optional[Dict[str, Union[PathItem, Any]]] = None
- webhooks: Optional[Dict[str, Union[PathItem, Reference]]] = None
+ paths: Optional[dict[str, Union[PathItem, Any]]] = None
+ webhooks: Optional[dict[str, Union[PathItem, Reference]]] = None
components: Optional[Components] = None
- security: Optional[List[Dict[str, List[str]]]] = None
- tags: Optional[List[Tag]] = None
+ security: Optional[list[dict[str, list[str]]]] = None
+ tags: Optional[list[Tag]] = None
externalDocs: Optional[ExternalDocumentation] = None
import http.client
import inspect
import warnings
-from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast
+from collections.abc import Sequence
+from typing import Any, Optional, Union, cast
from fastapi import routing
from fastapi._compat import (
},
}
-status_code_ranges: Dict[str, str] = {
+status_code_ranges: dict[str, str] = {
"1XX": "Information",
"2XX": "Success",
"3XX": "Redirection",
def get_openapi_security_definitions(
flat_dependant: Dependant,
-) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+) -> tuple[dict[str, Any], list[dict[str, Any]]]:
security_definitions = {}
# Use a dict to merge scopes for same security scheme
- operation_security_dict: Dict[str, List[str]] = {}
+ operation_security_dict: dict[str, list[str]] = {}
for security_dependency in flat_dependant._security_dependencies:
security_definition = jsonable_encoder(
security_dependency._security_scheme.model,
*,
dependant: Dependant,
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
separate_input_output_schemas: bool = True,
-) -> List[Dict[str, Any]]:
+) -> list[dict[str, Any]]:
parameters = []
flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
path_params = _get_flat_fields_from_params(flat_dependant.path_params)
*,
body_field: Optional[ModelField],
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
separate_input_output_schemas: bool = True,
-) -> Optional[Dict[str, Any]]:
+) -> Optional[dict[str, Any]]:
if not body_field:
return None
assert _is_model_field(body_field)
field_info = cast(Body, body_field.field_info)
request_media_type = field_info.media_type
required = body_field.required
- request_body_oai: Dict[str, Any] = {}
+ request_body_oai: dict[str, Any] = {}
if required:
request_body_oai["required"] = required
- request_media_content: Dict[str, Any] = {"schema": body_schema}
+ request_media_content: dict[str, Any] = {"schema": body_schema}
if field_info.openapi_examples:
request_media_content["examples"] = jsonable_encoder(
field_info.openapi_examples
def get_openapi_operation_metadata(
- *, route: routing.APIRoute, method: str, operation_ids: Set[str]
-) -> Dict[str, Any]:
- operation: Dict[str, Any] = {}
+ *, route: routing.APIRoute, method: str, operation_ids: set[str]
+) -> dict[str, Any]:
+ operation: dict[str, Any] = {}
if route.tags:
operation["tags"] = route.tags
operation["summary"] = generate_operation_summary(route=route, method=method)
def get_openapi_path(
*,
route: routing.APIRoute,
- operation_ids: Set[str],
+ operation_ids: set[str],
model_name_map: ModelNameMap,
- field_mapping: Dict[
- Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ field_mapping: dict[
+ tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
],
separate_input_output_schemas: bool = True,
-) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]:
+) -> tuple[dict[str, Any], dict[str, Any], dict[str, Any]]:
path = {}
- security_schemes: Dict[str, Any] = {}
- definitions: Dict[str, Any] = {}
+ security_schemes: dict[str, Any] = {}
+ definitions: dict[str, Any] = {}
assert route.methods is not None, "Methods must be a list"
if isinstance(route.response_class, DefaultPlaceholder):
- current_response_class: Type[Response] = route.response_class.value
+ current_response_class: type[Response] = route.response_class.value
else:
current_response_class = route.response_class
assert current_response_class, "A response class is needed to generate OpenAPI"
operation = get_openapi_operation_metadata(
route=route, method=method, operation_ids=operation_ids
)
- parameters: List[Dict[str, Any]] = []
+ parameters: list[dict[str, Any]] = []
flat_dependant = get_flat_dependant(route.dependant, skip_repeats=True)
security_definitions, operation_security = get_openapi_security_definitions(
flat_dependant=flat_dependant
"An additional response must be a dict"
)
field = route.response_fields.get(additional_status_code)
- additional_field_schema: Optional[Dict[str, Any]] = None
+ additional_field_schema: Optional[dict[str, Any]] = None
if field:
additional_field_schema = get_schema_from_model_field(
field=field,
def get_fields_from_routes(
routes: Sequence[BaseRoute],
-) -> List[ModelField]:
- body_fields_from_routes: List[ModelField] = []
- responses_from_routes: List[ModelField] = []
- request_fields_from_routes: List[ModelField] = []
- callback_flat_models: List[ModelField] = []
+) -> list[ModelField]:
+ body_fields_from_routes: list[ModelField] = []
+ responses_from_routes: list[ModelField] = []
+ request_fields_from_routes: list[ModelField] = []
+ callback_flat_models: list[ModelField] = []
for route in routes:
if getattr(route, "include_in_schema", None) and isinstance(
route, routing.APIRoute
description: Optional[str] = None,
routes: Sequence[BaseRoute],
webhooks: Optional[Sequence[BaseRoute]] = None,
- tags: Optional[List[Dict[str, Any]]] = None,
- servers: Optional[List[Dict[str, Union[str, Any]]]] = None,
+ tags: Optional[list[dict[str, Any]]] = None,
+ servers: Optional[list[dict[str, Union[str, Any]]]] = None,
terms_of_service: Optional[str] = None,
- contact: Optional[Dict[str, Union[str, Any]]] = None,
- license_info: Optional[Dict[str, Union[str, Any]]] = None,
+ contact: Optional[dict[str, Union[str, Any]]] = None,
+ license_info: Optional[dict[str, Union[str, Any]]] = None,
separate_input_output_schemas: bool = True,
- external_docs: Optional[Dict[str, Any]] = None,
-) -> Dict[str, Any]:
- info: Dict[str, Any] = {"title": title, "version": version}
+ external_docs: Optional[dict[str, Any]] = None,
+) -> dict[str, Any]:
+ info: dict[str, Any] = {"title": title, "version": version}
if summary:
info["summary"] = summary
if description:
info["contact"] = contact
if license_info:
info["license"] = license_info
- output: Dict[str, Any] = {"openapi": openapi_version, "info": info}
+ output: dict[str, Any] = {"openapi": openapi_version, "info": info}
if servers:
output["servers"] = servers
- components: Dict[str, Dict[str, Any]] = {}
- paths: Dict[str, Dict[str, Any]] = {}
- webhook_paths: Dict[str, Dict[str, Any]] = {}
- operation_ids: Set[str] = set()
+ components: dict[str, dict[str, Any]] = {}
+ paths: dict[str, dict[str, Any]] = {}
+ webhook_paths: dict[str, dict[str, Any]] = {}
+ operation_ids: set[str] = set()
all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
model_name_map = get_compat_model_name_map(all_fields)
field_mapping, definitions = get_definitions(
-from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+from collections.abc import Sequence
+from typing import Annotated, Any, Callable, Optional, Union
from annotated_doc import Doc
from fastapi import params
from fastapi._compat import Undefined
from fastapi.openapi.models import Example
-from typing_extensions import Annotated, Literal, deprecated
+from typing_extensions import Literal, deprecated
_Unset: Any = Undefined
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
),
] = _Unset,
examples: Annotated[
- Optional[List[Any]],
+ Optional[list[Any]],
Doc(
"""
Example values for this field.
),
] = _Unset,
openapi_examples: Annotated[
- Optional[Dict[str, Example]],
+ Optional[dict[str, Example]],
Doc(
"""
OpenAPI-specific examples.
),
] = True,
json_schema_extra: Annotated[
- Union[Dict[str, Any], None],
+ Union[dict[str, Any], None],
Doc(
"""
Any additional JSON schema data.
import warnings
+from collections.abc import Sequence
from dataclasses import dataclass
from enum import Enum
-from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+from typing import Annotated, Any, Callable, Optional, Union
from fastapi.openapi.models import Example
from pydantic.fields import FieldInfo
-from typing_extensions import Annotated, Literal, deprecated
+from typing_extensions import Literal, deprecated
from ._compat import (
PYDANTIC_V2,
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
if example is not _Unset:
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
assert default is ..., "Path parameters cannot have a default value"
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
self.convert_underscores = convert_underscores
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
self.embed = embed
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
import functools
import inspect
import json
-from contextlib import AsyncExitStack, asynccontextmanager
-from enum import Enum, IntEnum
-from typing import (
- Any,
+from collections.abc import (
AsyncIterator,
Awaitable,
- Callable,
Collection,
Coroutine,
- Dict,
- List,
Mapping,
- Optional,
Sequence,
- Set,
- Tuple,
- Type,
+)
+from contextlib import AsyncExitStack, asynccontextmanager
+from enum import Enum, IntEnum
+from typing import (
+ Annotated,
+ Any,
+ Callable,
+ Optional,
Union,
)
from starlette.routing import Mount as Mount # noqa
from starlette.types import AppType, ASGIApp, Lifespan, Receive, Scope, Send
from starlette.websockets import WebSocket
-from typing_extensions import Annotated, deprecated
+from typing_extensions import deprecated
# Copy of starlette.routing.request_response modified to include the
# Cache for endpoint context to avoid re-extracting on every request
-_endpoint_context_cache: Dict[int, EndpointContext] = {}
+_endpoint_context_cache: dict[int, EndpointContext] = {}
def _extract_endpoint_context(func: Any) -> EndpointContext:
async def run_endpoint_function(
- *, dependant: Dependant, values: Dict[str, Any], is_coroutine: bool
+ *, dependant: Dependant, values: dict[str, Any], is_coroutine: bool
) -> Any:
# Only called by get_request_handler. Has been split into its own function to
# facilitate profiling endpoints, since inner functions are harder to profile.
dependant: Dependant,
body_field: Optional[ModelField] = None,
status_code: Optional[int] = None,
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),
+ response_class: Union[type[Response], DefaultPlaceholder] = Default(JSONResponse),
response_field: Optional[ModelField] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
body_field.field_info, (params.Form, temp_pydantic_v1_params.Form)
)
if isinstance(response_class, DefaultPlaceholder):
- actual_response_class: Type[Response] = response_class.value
+ actual_response_class: type[Response] = response_class.value
else:
actual_response_class = response_class
raise http_error from e
# Solve dependencies and run path operation function, auto-closing dependencies
- errors: List[Any] = []
+ errors: list[Any] = []
async_exit_stack = request.scope.get("fastapi_inner_astack")
assert isinstance(async_exit_stack, AsyncExitStack), (
"fastapi_inner_astack not found in request scope"
raw_response.background = solved_result.background_tasks
response = raw_response
else:
- response_args: Dict[str, Any] = {
+ response_args: dict[str, Any] = {
"background": solved_result.background_tasks
}
# If status_code was set, use it, otherwise use the default from the
)
)
- def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
match, child_scope = super().matches(scope)
if match != Match.NONE:
child_scope["route"] = self
*,
response_model: Any = Default(None),
status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
+ tags: Optional[list[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
name: Optional[str] = None,
- methods: Optional[Union[Set[str], List[str]]] = None,
+ methods: Optional[Union[set[str], list[str]]] = None,
operation_id: Optional[str] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
include_in_schema: bool = True,
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ response_class: Union[type[Response], DefaultPlaceholder] = Default(
JSONResponse
),
dependency_overrides_provider: Optional[Any] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
+ callbacks: Optional[list[BaseRoute]] = None,
+ openapi_extra: Optional[dict[str, Any]] = None,
generate_unique_id_function: Union[
Callable[["APIRoute"], str], DefaultPlaceholder
] = Default(generate_unique_id),
self.path_regex, self.path_format, self.param_convertors = compile_path(path)
if methods is None:
methods = ["GET"]
- self.methods: Set[str] = {method.upper() for method in methods}
+ self.methods: set[str] = {method.upper() for method in methods}
if isinstance(generate_unique_id_function, DefaultPlaceholder):
current_generate_unique_id: Callable[[APIRoute], str] = (
generate_unique_id_function.value
)
response_fields[additional_status_code] = response_field
if response_fields:
- self.response_fields: Dict[Union[int, str], ModelField] = response_fields
+ self.response_fields: dict[Union[int, str], ModelField] = response_fields
else:
self.response_fields = {}
embed_body_fields=self._embed_body_fields,
)
- def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
match, child_scope = super().matches(scope)
if match != Match.NONE:
child_scope["route"] = self
*,
prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to all the *path operations* in this
),
] = None,
default_response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
The default response class to be used.
),
] = Default(JSONResponse),
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses to be shown in OpenAPI.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
OpenAPI callbacks that should apply to all *path operations* in this
),
] = None,
routes: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
**Note**: you probably shouldn't use this parameter, it is inherited
),
] = None,
route_class: Annotated[
- Type[APIRoute],
+ type[APIRoute],
Doc(
"""
Custom route (*path operation*) class to be used by this router.
"A path prefix must not end with '/', as the routes will start with '/'"
)
self.prefix = prefix
- self.tags: List[Union[str, Enum]] = tags or []
+ self.tags: list[Union[str, Enum]] = tags or []
self.dependencies = list(dependencies or [])
self.deprecated = deprecated
self.include_in_schema = include_in_schema
*,
response_model: Any = Default(None),
status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
+ tags: Optional[list[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
- methods: Optional[Union[Set[str], List[str]]] = None,
+ methods: Optional[Union[set[str], list[str]]] = None,
operation_id: Optional[str] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
include_in_schema: bool = True,
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ response_class: Union[type[Response], DefaultPlaceholder] = Default(
JSONResponse
),
name: Optional[str] = None,
- route_class_override: Optional[Type[APIRoute]] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
+ route_class_override: Optional[type[APIRoute]] = None,
+ callbacks: Optional[list[BaseRoute]] = None,
+ openapi_extra: Optional[dict[str, Any]] = None,
generate_unique_id_function: Union[
Callable[[APIRoute], str], DefaultPlaceholder
] = Default(generate_unique_id),
*,
response_model: Any = Default(None),
status_code: Optional[int] = None,
- tags: Optional[List[Union[str, Enum]]] = None,
+ tags: Optional[list[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
response_description: str = "Successful Response",
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ responses: Optional[dict[Union[int, str], dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
- methods: Optional[List[str]] = None,
+ methods: Optional[list[str]] = None,
operation_id: Optional[str] = None,
response_model_include: Optional[IncEx] = None,
response_model_exclude: Optional[IncEx] = None,
response_model_exclude_defaults: bool = False,
response_model_exclude_none: bool = False,
include_in_schema: bool = True,
- response_class: Type[Response] = Default(JSONResponse),
+ response_class: type[Response] = Default(JSONResponse),
name: Optional[str] = None,
- callbacks: Optional[List[BaseRoute]] = None,
- openapi_extra: Optional[Dict[str, Any]] = None,
+ callbacks: Optional[list[BaseRoute]] = None,
+ openapi_extra: Optional[dict[str, Any]] = None,
generate_unique_id_function: Callable[[APIRoute], str] = Default(
generate_unique_id
),
*,
prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to all the *path operations* in this
),
] = None,
default_response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
The default response class to be used.
),
] = Default(JSONResponse),
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses to be shown in OpenAPI.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
OpenAPI callbacks that should apply to all *path operations* in this
current_tags.extend(tags)
if route.tags:
current_tags.extend(route.tags)
- current_dependencies: List[params.Depends] = []
+ current_dependencies: list[params.Depends] = []
if dependencies:
current_dependencies.extend(dependencies)
if route.dependencies:
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
),
] = None,
tags: Annotated[
- Optional[List[Union[str, Enum]]],
+ Optional[list[Union[str, Enum]]],
Doc(
"""
A list of tags to be applied to the *path operation*.
),
] = "Successful Response",
responses: Annotated[
- Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Optional[dict[Union[int, str], dict[str, Any]]],
Doc(
"""
Additional responses that could be returned by this *path operation*.
),
] = True,
response_class: Annotated[
- Type[Response],
+ type[Response],
Doc(
"""
Response class to be used for this *path operation*.
),
] = None,
callbacks: Annotated[
- Optional[List[BaseRoute]],
+ Optional[list[BaseRoute]],
Doc(
"""
List of *path operations* that will be used as OpenAPI callbacks.
),
] = None,
openapi_extra: Annotated[
- Optional[Dict[str, Any]],
+ Optional[dict[str, Any]],
Doc(
"""
Extra metadata to be included in the OpenAPI schema for this *path
-from typing import Optional, Union
+from typing import Annotated, Optional, Union
from annotated_doc import Doc
from fastapi.openapi.models import APIKey, APIKeyIn
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED
-from typing_extensions import Annotated
class APIKeyBase(SecurityBase):
import binascii
from base64 import b64decode
-from typing import Dict, Optional
+from typing import Annotated, Optional
from annotated_doc import Doc
from fastapi.exceptions import HTTPException
from pydantic import BaseModel
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED
-from typing_extensions import Annotated
class HTTPBasicCredentials(BaseModel):
self.scheme_name = scheme_name or self.__class__.__name__
self.auto_error = auto_error
- def make_authenticate_headers(self) -> Dict[str, str]:
+ def make_authenticate_headers(self) -> dict[str, str]:
return {"WWW-Authenticate": f"{self.model.scheme.title()}"}
def make_not_authenticated_error(self) -> HTTPException:
self.realm = realm
self.auto_error = auto_error
- def make_authenticate_headers(self) -> Dict[str, str]:
+ def make_authenticate_headers(self) -> dict[str, str]:
if self.realm:
return {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
return {"WWW-Authenticate": "Basic"}
-from typing import Any, Dict, List, Optional, Union, cast
+from typing import Annotated, Any, Optional, Union, cast
from annotated_doc import Doc
from fastapi.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED
-# TODO: import from typing when deprecating Python 3.9
-from typing_extensions import Annotated
-
class OAuth2PasswordRequestForm:
"""
self,
*,
flows: Annotated[
- Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]],
+ Union[OAuthFlowsModel, dict[str, dict[str, Any]]],
Doc(
"""
The dictionary of OAuth2 flows.
),
] = None,
scopes: Annotated[
- Optional[Dict[str, str]],
+ Optional[dict[str, str]],
Doc(
"""
The OAuth2 scopes that would be required by the *path operations* that
),
] = None,
scopes: Annotated[
- Optional[Dict[str, str]],
+ Optional[dict[str, str]],
Doc(
"""
The OAuth2 scopes that would be required by the *path operations* that
def __init__(
self,
scopes: Annotated[
- Optional[List[str]],
+ Optional[list[str]],
Doc(
"""
This will be filled by FastAPI.
] = None,
):
self.scopes: Annotated[
- List[str],
+ list[str],
Doc(
"""
The list of all the scopes required by dependencies.
-from typing import Optional
+from typing import Annotated, Optional
from annotated_doc import Doc
from fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.status import HTTP_401_UNAUTHORIZED
-from typing_extensions import Annotated
class OpenIdConnect(SecurityBase):
-from typing import Optional, Tuple
+from typing import Optional
def get_authorization_scheme_param(
authorization_header_value: Optional[str],
-) -> Tuple[str, str]:
+) -> tuple[str, str]:
if not authorization_header_value:
return "", ""
scheme, _, param = authorization_header_value.partition(" ")
import warnings
-from typing import Any, Callable, Dict, List, Optional, Union
+from typing import Annotated, Any, Callable, Optional, Union
from fastapi.openapi.models import Example
from fastapi.params import ParamTypes
-from typing_extensions import Annotated, deprecated
+from typing_extensions import deprecated
from ._compat.may_v1 import FieldInfo, Undefined
from ._compat.shared import PYDANTIC_VERSION_MINOR_TUPLE
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
if example is not _Unset:
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
assert default is ..., "Path parameters cannot have a default value"
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
self.convert_underscores = convert_underscores
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
self.embed = embed
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
allow_inf_nan: Union[bool, None] = _Unset,
max_digits: Union[int, None] = _Unset,
decimal_places: Union[int, None] = _Unset,
- examples: Optional[List[Any]] = None,
+ examples: Optional[list[Any]] = None,
example: Annotated[
Optional[Any],
deprecated(
"although still supported. Use examples instead."
),
] = _Unset,
- openapi_examples: Optional[Dict[str, Example]] = None,
+ openapi_examples: Optional[dict[str, Example]] = None,
deprecated: Union[deprecated, str, bool, None] = None,
include_in_schema: bool = True,
- json_schema_extra: Union[Dict[str, Any], None] = None,
+ json_schema_extra: Union[dict[str, Any], None] = None,
**extra: Any,
):
super().__init__(
import types
from enum import Enum
-from typing import Any, Callable, Dict, Optional, Set, Tuple, Type, TypeVar, Union
+from typing import Any, Callable, Optional, TypeVar, Union
from pydantic import BaseModel
DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])
UnionType = getattr(types, "UnionType", Union)
-ModelNameMap = Dict[Union[Type[BaseModel], Type[Enum]], str]
-IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]]
-DependencyCacheKey = Tuple[Optional[Callable[..., Any]], Tuple[str, ...], str]
+ModelNameMap = dict[Union[type[BaseModel], type[Enum]], str]
+IncEx = Union[set[int], set[str], dict[int, Any], dict[str, Any]]
+DependencyCacheKey = tuple[Optional[Callable[..., Any]], tuple[str, ...], str]
import re
import warnings
+from collections.abc import MutableMapping
from dataclasses import is_dataclass
from typing import (
TYPE_CHECKING,
Any,
- Dict,
- MutableMapping,
Optional,
- Set,
- Type,
Union,
cast,
)
from .routing import APIRoute
# Cache for `create_cloned_field`
-_CLONED_TYPES_CACHE: MutableMapping[Type[BaseModel], Type[BaseModel]] = (
+_CLONED_TYPES_CACHE: MutableMapping[type[BaseModel], type[BaseModel]] = (
WeakKeyDictionary()
)
return not (current_status_code < 200 or current_status_code in {204, 205, 304})
-def get_path_param_names(path: str) -> Set[str]:
+def get_path_param_names(path: str) -> set[str]:
return set(re.findall("{(.*?)}", path))
def create_model_field(
name: str,
type_: Any,
- class_validators: Optional[Dict[str, Validator]] = None,
+ class_validators: Optional[dict[str, Validator]] = None,
default: Optional[Any] = Undefined,
required: Union[bool, UndefinedType] = Undefined,
- model_config: Union[Type[BaseConfig], None] = None,
+ model_config: Union[type[BaseConfig], None] = None,
field_info: Optional[FieldInfo] = None,
alias: Optional[str] = None,
mode: Literal["validation", "serialization"] = "validation",
def create_cloned_field(
field: ModelField,
*,
- cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
+ cloned_types: Optional[MutableMapping[type[BaseModel], type[BaseModel]]] = None,
) -> ModelField:
if PYDANTIC_V2:
from ._compat import v2
original_type = original_type.__pydantic_model__
use_type = original_type
if lenient_issubclass(original_type, v1.BaseModel):
- original_type = cast(Type[v1.BaseModel], original_type)
+ original_type = cast(type[v1.BaseModel], original_type)
use_type = cloned_types.get(original_type)
if use_type is None:
use_type = v1.create_model(original_type.__name__, __base__=original_type)
return operation_id
-def deep_dict_update(main_dict: Dict[Any, Any], update_dict: Dict[Any, Any]) -> None:
+def deep_dict_update(main_dict: dict[Any, Any], update_dict: dict[Any, Any]) -> None:
for key, value in update_dict.items():
if (
key in main_dict
import os
-from typing import Any, Dict
+from typing import Any
from pdm.backend.hooks import Context
def pdm_build_initialize(context: Context) -> None:
metadata = context.config.metadata
# Get custom config for the current package, from the env var
- config: Dict[str, Any] = context.config.data["tool"]["tiangolo"][
+ config: dict[str, Any] = context.config.data["tool"]["tiangolo"][
"_internal-slim-build"
]["packages"].get(TIANGOLO_BUILD_PACKAGE)
if not config:
return
- project_config: Dict[str, Any] = config["project"]
+ project_config: dict[str, Any] = config["project"]
# Override main [project] configs with custom configs for this package
for key, value in project_config.items():
metadata[key] = value
from http.server import HTTPServer, SimpleHTTPRequestHandler
from multiprocessing import Pool
from pathlib import Path
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Optional, Union
import mkdocs.utils
import typer
)
-def get_en_config() -> Dict[str, Any]:
+def get_en_config() -> dict[str, Any]:
return mkdocs.utils.yaml_load(en_config_path.read_text(encoding="utf-8"))
-def get_lang_paths() -> List[Path]:
+def get_lang_paths() -> list[Path]:
return sorted(docs_path.iterdir())
)
-def get_updated_config_content() -> Dict[str, Any]:
+def get_updated_config_content() -> dict[str, Any]:
config = get_en_config()
languages = [{"en": "/"}]
- new_alternate: List[Dict[str, str]] = []
+ new_alternate: list[dict[str, str]] = []
# Language names sourced from https://quickref.me/iso-639-1
# Contributors may wish to update or change these, e.g. to fix capitalization.
language_names_path = Path(__file__).parent / "../docs/language_names.yml"
- local_language_names: Dict[str, str] = mkdocs.utils.yaml_load(
+ local_language_names: dict[str, str] = mkdocs.utils.yaml_load(
language_names_path.read_text(encoding="utf-8")
)
for lang_path in get_lang_paths():
@app.command()
-def add_permalinks_pages(pages: List[Path], update_existing: bool = False) -> None:
+def add_permalinks_pages(pages: list[Path], update_existing: bool = False) -> None:
"""
Add or update header permalinks in specific pages of En docs.
"""
from functools import lru_cache
from pathlib import Path
-from typing import Any, List, Union
+from typing import Any, Union
import material
from mkdocs.config.defaults import MkDocsConfig
@lru_cache
-def get_mkdocs_material_langs() -> List[str]:
+def get_mkdocs_material_langs() -> list[str]:
material_path = Path(material.__file__).parent
material_langs_path = material_path / "templates" / "partials" / "languages"
langs = [file.stem for file in material_langs_path.glob("*.html")]
)
-def resolve_files(*, items: List[Any], files: Files, config: MkDocsConfig) -> None:
+def resolve_files(*, items: list[Any], files: Files, config: MkDocsConfig) -> None:
for item in items:
if isinstance(item, str):
resolve_file(item=item, files=files, config=config)
def generate_renamed_section_items(
- items: List[Union[Page, Section, Link]], *, config: MkDocsConfig
-) -> List[Union[Page, Section, Link]]:
- new_items: List[Union[Page, Section, Link]] = []
+ items: list[Union[Page, Section, Link]], *, config: MkDocsConfig
+) -> list[Union[Page, Section, Link]]:
+ new_items: list[Union[Page, Section, Link]] = []
for item in items:
if isinstance(item, Section):
new_title = item.title
import sys
import time
from pathlib import Path
-from typing import Any, Dict, List, Union, cast
+from typing import Any, Union, cast
import httpx
from github import Github
class Comments(BaseModel):
- edges: List[CommentsEdge]
+ edges: list[CommentsEdge]
class CommentsDiscussion(BaseModel):
class AllDiscussionsDiscussionLabels(BaseModel):
- edges: List[AllDiscussionsLabelsEdge]
+ edges: list[AllDiscussionsLabelsEdge]
class AllDiscussionsDiscussionNode(BaseModel):
class AllDiscussionsDiscussions(BaseModel):
- nodes: List[AllDiscussionsDiscussionNode]
+ nodes: list[AllDiscussionsDiscussionNode]
class AllDiscussionsRepository(BaseModel):
discussion_id: Union[str, None] = None,
comment_id: Union[str, None] = None,
body: Union[str, None] = None,
-) -> Dict[str, Any]:
+) -> dict[str, Any]:
headers = {"Authorization": f"token {settings.github_token.get_secret_value()}"}
variables = {
"after": after,
logging.error(data["errors"])
logging.error(response.text)
raise RuntimeError(response.text)
- return cast(Dict[str, Any], data)
+ return cast(dict[str, Any], data)
def get_graphql_translation_discussions(
*, settings: Settings
-) -> List[AllDiscussionsDiscussionNode]:
+) -> list[AllDiscussionsDiscussionNode]:
data = get_graphql_response(
settings=settings,
query=all_discussions_query,
def get_graphql_translation_discussion_comments_edges(
*, settings: Settings, discussion_number: int, after: Union[str, None] = None
-) -> List[CommentsEdge]:
+) -> list[CommentsEdge]:
data = get_graphql_response(
settings=settings,
query=translation_discussion_query,
def get_graphql_translation_discussion_comments(
*, settings: Settings, discussion_number: int
) -> list[Comment]:
- comment_nodes: List[Comment] = []
+ comment_nodes: list[Comment] = []
discussion_edges = get_graphql_translation_discussion_comments_edges(
settings=settings, discussion_number=discussion_number
)
# Generate translation map, lang ID to discussion
discussions = get_graphql_translation_discussions(settings=settings)
- lang_to_discussion_map: Dict[str, AllDiscussionsDiscussionNode] = {}
+ lang_to_discussion_map: dict[str, AllDiscussionsDiscussionNode] = {}
for discussion in discussions:
for edge in discussion.labels.edges:
label = edge.node.name
import subprocess
import time
from collections import Counter
+from collections.abc import Container
from datetime import datetime, timedelta, timezone
from pathlib import Path
-from typing import Any, Container, Union
+from typing import Any, Union
import httpx
import yaml
import http
-from typing import FrozenSet, List, Optional
+from typing import Optional
from fastapi import FastAPI, Path, Query
@app.get("/query/frozenset")
-def get_query_type_frozenset(query: FrozenSet[int] = Query(...)):
+def get_query_type_frozenset(query: frozenset[int] = Query(...)):
return ",".join(map(str, sorted(query)))
@app.get("/query/list")
-def get_query_list(device_ids: List[int] = Query()) -> List[int]:
+def get_query_list(device_ids: list[int] = Query()) -> list[int]:
return device_ids
@app.get("/query/list-default")
-def get_query_list_default(device_ids: List[int] = Query(default=[])) -> List[int]:
+def get_query_list_default(device_ids: list[int] = Query(default=[])) -> list[int]:
return device_ids
-from typing import Dict
-
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
class Items(BaseModel):
- items: Dict[str, int]
+ items: dict[str, int]
@app.post("/foo")
-import typing
-
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
class JsonApiError(BaseModel):
- errors: typing.List[Error]
+ errors: list[Error]
@app.get(
-import typing
-
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
class JsonApiError(BaseModel):
- errors: typing.List[Error]
+ errors: list[Error]
@app.get(
+from typing import Annotated
+
import pytest
from fastapi import Body, FastAPI, Query
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
+from typing import Annotated
+
import pytest
from fastapi import Depends, FastAPI, Path
from fastapi.param_functions import Query
from fastapi.testclient import TestClient
from fastapi.utils import PYDANTIC_V2
-from typing_extensions import Annotated
app = FastAPI()
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict
from fastapi import APIRouter, FastAPI, Query
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
-from typing import List
+from typing import Annotated
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
-from typing_extensions import Annotated
from .utils import needs_pydanticv2
FakeNumpyArrayPydantic = Annotated[
FakeNumpyArray,
- WithJsonSchema(TypeAdapter(List[float]).json_schema()),
+ WithJsonSchema(TypeAdapter(list[float]).json_schema()),
PlainSerializer(lambda v: v.data),
]
FakeNumpyArrayPydantic = Annotated[
FakeNumpyArray,
- WithJsonSchema(TypeAdapter(List[float]).json_schema()),
+ WithJsonSchema(TypeAdapter(list[float]).json_schema()),
PlainSerializer(lambda v: v.data),
]
-from typing import Any, Dict, List, Union
+from typing import Any, Union
from fastapi import FastAPI, UploadFile
from fastapi._compat import (
app = FastAPI()
@app.post("/")
- def foo(foo: Union[str, List[int]]):
+ def foo(foo: Union[str, list[int]]):
return foo
client = TestClient(app)
embedded_model: EmbeddedModel = EmbeddedModel()
@app.post("/")
- def foo(req: Model) -> Dict[str, Union[str, None]]:
+ def foo(req: Model) -> dict[str, Union[str, None]]:
return {
"value": req.value or None,
"embedded_value": req.embedded_model.value or None,
# TODO: in theory this would allow declaring types that could be lists of bytes
# to be read from files and other types, but I'm not even sure it's a good idea
# to support it as a first class "feature"
- assert is_bytes_sequence_annotation(Union[List[str], List[bytes]])
+ assert is_bytes_sequence_annotation(Union[list[str], list[bytes]])
def test_is_uploadfile_sequence_annotation():
# TODO: in theory this would allow declaring types that could be lists of UploadFile
# and other types, but I'm not even sure it's a good idea to support it as a first
# class "feature"
- assert is_uploadfile_sequence_annotation(Union[List[str], List[UploadFile]])
+ assert is_uploadfile_sequence_annotation(Union[list[str], list[UploadFile]])
@needs_pydanticv2
"""Test that serialize_sequence_value handles optional lists correctly."""
from fastapi._compat import v2
- field_info = FieldInfo(annotation=Union[List[str], None])
+ field_info = FieldInfo(annotation=Union[list[str], None])
field = v2.ModelField(name="items", field_info=field_info)
result = v2.serialize_sequence_value(field=field, value=["a", "b", "c"])
assert result == ["a", "b", "c"]
"""Test that serialize_sequence_value handles Union[None, List[...]] correctly."""
from fastapi._compat import v2
- field_info = FieldInfo(annotation=Union[None, List[str]])
+ field_info = FieldInfo(annotation=Union[None, list[str]])
field = v2.ModelField(name="items", field_info=field_info)
result = v2.serialize_sequence_value(field=field, value=["x", "y"])
assert result == ["x", "y"]
# For coverage
class Model(v1.BaseModel):
- foo: Union[str, Dict[str, Any]]
+ foo: Union[str, dict[str, Any]]
fields = v1.get_model_fields(Model)
assert not is_scalar_field(fields[0])
import sys
-from typing import List, Optional
+from typing import Optional
import pytest
if sys.version_info >= (3, 14):
skip_module_if_py_gte_314()
+from typing import Annotated
+
from fastapi import FastAPI
from fastapi._compat.v1 import BaseModel
from fastapi.temp_pydantic_v1_params import (
)
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
-from typing_extensions import Annotated
class Item(BaseModel):
@app.post("/upload-multiple/")
def upload_multiple_files(
- files: Annotated[List[bytes], File()],
+ files: Annotated[list[bytes], File()],
note: Annotated[str, Form()] = "",
):
return {
-from typing import Optional
+from typing import Annotated, Optional
from fastapi import FastAPI
from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient
from pydantic import BaseModel
-from typing_extensions import Annotated
if PYDANTIC_V2:
from pydantic import WithJsonSchema
import io
from pathlib import Path
-from typing import List
import pytest
from fastapi import FastAPI, UploadFile
path.write_bytes(b"<file content>")
app = FastAPI()
- testing_file_store: List[UploadFile] = []
+ testing_file_store: list[UploadFile] = []
@app.post("/uploadfile/")
def create_upload_file(file: UploadFile):
-from typing import Any
+from typing import Annotated, Any
import pytest
from fastapi import Depends, FastAPI, HTTPException
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
class CustomError(Exception):
+from collections.abc import Generator
from contextlib import contextmanager
-from typing import Any, Generator
+from typing import Annotated, Any
import pytest
from fastapi import Depends, FastAPI
from fastapi.responses import StreamingResponse
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
class Session:
+from collections.abc import Generator
from contextlib import contextmanager
-from typing import Any, Generator
+from typing import Annotated, Any
import pytest
from fastapi import Depends, FastAPI, WebSocket
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
class Session:
-from typing import AsyncGenerator, Generator
+from collections.abc import AsyncGenerator, Generator
import pytest
from fastapi import Depends, FastAPI
import json
-from typing import Dict
import pytest
from fastapi import BackgroundTasks, Depends, FastAPI
pass
-async def asyncgen_state(state: Dict[str, str] = Depends(get_state)):
+async def asyncgen_state(state: dict[str, str] = Depends(get_state)):
state["/async"] = "asyncgen started"
yield state["/async"]
state["/async"] = "asyncgen completed"
-def generator_state(state: Dict[str, str] = Depends(get_state)):
+def generator_state(state: dict[str, str] = Depends(get_state)):
state["/sync"] = "generator started"
yield state["/sync"]
state["/sync"] = "generator completed"
-async def asyncgen_state_try(state: Dict[str, str] = Depends(get_state)):
+async def asyncgen_state_try(state: dict[str, str] = Depends(get_state)):
state["/async_raise"] = "asyncgen raise started"
try:
yield state["/async_raise"]
state["/async_raise"] = "asyncgen raise finalized"
-def generator_state_try(state: Dict[str, str] = Depends(get_state)):
+def generator_state_try(state: dict[str, str] = Depends(get_state)):
state["/sync_raise"] = "generator raise started"
try:
yield state["/sync_raise"]
+from collections.abc import Awaitable
from contextvars import ContextVar
-from typing import Any, Awaitable, Callable, Dict, Optional
+from typing import Any, Callable, Optional
from fastapi import Depends, FastAPI, Request, Response
from fastapi.testclient import TestClient
-legacy_request_state_context_var: ContextVar[Optional[Dict[str, Any]]] = ContextVar(
+legacy_request_state_context_var: ContextVar[Optional[dict[str, Any]]] = ContextVar(
"legacy_request_state_context_var", default=None
)
-from typing import List
-
from dirty_equals import IsDict
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
@app.post("/with-duplicates-sub")
async def no_duplicates_sub(
- item: Item, sub_items: List[Item] = Depends(sub_duplicate_dependency)
+ item: Item, sub_items: list[Item] = Depends(sub_duplicate_dependency)
):
return [item, sub_items]
-from typing import Union
+from typing import Annotated, Union
from fastapi import FastAPI, HTTPException, Security
from fastapi.security import (
SecurityScopes,
)
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
+from collections.abc import AsyncGenerator, Generator
from functools import partial
-from typing import AsyncGenerator, Generator
+from typing import Annotated
import pytest
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
-from typing import List, Tuple
-
from fastapi import Depends, FastAPI, Security
from fastapi.security import SecurityScopes
from fastapi.testclient import TestClient
@app.get("/user")
def read_user(
- user_data: Tuple[str, List[str]] = Security(get_user, scopes=["foo", "bar"]),
- data: List[int] = Depends(get_data),
+ user_data: tuple[str, list[str]] = Security(get_user, scopes=["foo", "bar"]),
+ data: list[int] = Depends(get_data),
):
return {"user": user_data[0], "scopes": user_data[1], "data": data}
import inspect
import sys
+from collections.abc import AsyncGenerator, Generator
from functools import wraps
-from typing import AsyncGenerator, Generator
import pytest
from fastapi import Depends, FastAPI
import json
-from typing import Any, Tuple
+from typing import Annotated, Any
import pytest
from fastapi import APIRouter, Depends, FastAPI, HTTPException
from fastapi.exceptions import FastAPIError
from fastapi.responses import StreamingResponse
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
class Session:
named_session.open = False
-NamedSessionsDep = Annotated[Tuple[NamedSession, Session], Depends(get_named_session)]
+NamedSessionsDep = Annotated[tuple[NamedSession, Session], Depends(get_named_session)]
def get_named_func_session(session: SessionFuncDep) -> Any:
BrokenSessionsDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_func_session)
+ tuple[NamedSession, Session], Depends(get_named_func_session)
]
NamedSessionsFuncDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_func_session, scope="function")
+ tuple[NamedSession, Session], Depends(get_named_func_session, scope="function")
]
RegularSessionsDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_regular_func_session)
+ tuple[NamedSession, Session], Depends(get_named_regular_func_session)
]
app = FastAPI()
from contextvars import ContextVar
-from typing import Any, Dict, Tuple
+from typing import Annotated, Any
import pytest
from fastapi import Depends, FastAPI, WebSocket
from fastapi.exceptions import FastAPIError
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
-global_context: ContextVar[Dict[str, Any]] = ContextVar("global_context", default={}) # noqa: B039
+global_context: ContextVar[dict[str, Any]] = ContextVar("global_context", default={}) # noqa: B039
class Session:
global_state["named_session_closed"] = True
-NamedSessionsDep = Annotated[Tuple[NamedSession, Session], Depends(get_named_session)]
+NamedSessionsDep = Annotated[tuple[NamedSession, Session], Depends(get_named_session)]
def get_named_func_session(session: SessionFuncDep) -> Any:
BrokenSessionsDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_func_session)
+ tuple[NamedSession, Session], Depends(get_named_func_session)
]
NamedSessionsFuncDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_func_session, scope="function")
+ tuple[NamedSession, Session], Depends(get_named_func_session, scope="function")
]
RegularSessionsDep = Annotated[
- Tuple[NamedSession, Session], Depends(get_named_regular_func_session)
+ tuple[NamedSession, Session], Depends(get_named_regular_func_session)
]
app = FastAPI()
"""
from pathlib import Path
-from typing import List
+from typing import Annotated
import pytest
from fastapi import FastAPI, File, Form
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
@app.post("/file_list_before_form")
def file_list_before_form(
- files: Annotated[List[bytes], File()],
+ files: Annotated[list[bytes], File()],
city: Annotated[str, Form()],
):
return {"file_contents": files, "city": city}
@app.post("/file_list_after_form")
def file_list_after_form(
city: Annotated[str, Form()],
- files: Annotated[List[bytes], File()],
+ files: Annotated[list[bytes], File()],
):
return {"file_contents": files, "city": city}
-from typing import Optional
+from typing import Annotated, Optional
from fastapi import FastAPI, File, Form
from starlette.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
-from typing import List, Optional
+from typing import Annotated, Optional
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
app = FastAPI()
username: str
lastname: str
age: Optional[int] = None
- tags: List[str] = ["foo", "bar"]
+ tags: list[str] = ["foo", "bar"]
alias_with: str = Field(alias="with", default="nothing")
+from typing import Annotated
+
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
import warnings
-from typing import List
from fastapi import APIRouter, FastAPI
from fastapi.routing import APIRoute
app = FastAPI(generate_unique_id_function=custom_generate_unique_id)
router = APIRouter()
- @app.post("/", response_model=List[Item], responses={404: {"model": List[Message]}})
+ @app.post("/", response_model=list[Item], responses={404: {"model": list[Message]}})
def post_root(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@router.post(
- "/router", response_model=List[Item], responses={404: {"model": List[Message]}}
+ "/router", response_model=list[Item], responses={404: {"model": list[Message]}}
)
def post_router(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
app = FastAPI(generate_unique_id_function=custom_generate_unique_id)
router = APIRouter(generate_unique_id_function=custom_generate_unique_id2)
- @app.post("/", response_model=List[Item], responses={404: {"model": List[Message]}})
+ @app.post("/", response_model=list[Item], responses={404: {"model": list[Message]}})
def post_root(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@router.post(
- "/router", response_model=List[Item], responses={404: {"model": List[Message]}}
+ "/router", response_model=list[Item], responses={404: {"model": list[Message]}}
)
def post_router(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
app = FastAPI(generate_unique_id_function=custom_generate_unique_id)
router = APIRouter(generate_unique_id_function=custom_generate_unique_id2)
- @app.post("/", response_model=List[Item], responses={404: {"model": List[Message]}})
+ @app.post("/", response_model=list[Item], responses={404: {"model": list[Message]}})
def post_root(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@router.post(
- "/router", response_model=List[Item], responses={404: {"model": List[Message]}}
+ "/router", response_model=list[Item], responses={404: {"model": list[Message]}}
)
def post_router(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
router = APIRouter()
sub_router = APIRouter(generate_unique_id_function=custom_generate_unique_id2)
- @app.post("/", response_model=List[Item], responses={404: {"model": List[Message]}})
+ @app.post("/", response_model=list[Item], responses={404: {"model": list[Message]}})
def post_root(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@router.post(
- "/router", response_model=List[Item], responses={404: {"model": List[Message]}}
+ "/router", response_model=list[Item], responses={404: {"model": list[Message]}}
)
def post_router(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@sub_router.post(
"/subrouter",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
)
def post_subrouter(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
app = FastAPI(generate_unique_id_function=custom_generate_unique_id)
router = APIRouter(generate_unique_id_function=custom_generate_unique_id2)
- @app.post("/", response_model=List[Item], responses={404: {"model": List[Message]}})
+ @app.post("/", response_model=list[Item], responses={404: {"model": list[Message]}})
def post_root(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@router.post(
"/router",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
generate_unique_id_function=custom_generate_unique_id3,
)
def post_router(item1: Item, item2: Item):
@app.post(
"/",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
generate_unique_id_function=custom_generate_unique_id3,
)
def post_root(item1: Item, item2: Item):
@router.post(
"/router",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
)
def post_router(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
@callback_router.post(
"/post-callback",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
generate_unique_id_function=custom_generate_unique_id3,
)
def post_callback(item1: Item, item2: Item):
@app.post(
"/",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
generate_unique_id_function=custom_generate_unique_id3,
callbacks=callback_router.routes,
)
@app.post(
"/tocallback",
- response_model=List[Item],
- responses={404: {"model": List[Message]}},
+ response_model=list[Item],
+ responses={404: {"model": list[Message]}},
)
def post_with_callback(item1: Item, item2: Item):
return item1, item2 # pragma: nocover
-from typing import TypeVar
+from typing import Annotated, TypeVar
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
app = FastAPI()
-from typing import Any, Iterator, Set, Type
+from collections.abc import Iterator
+from typing import Any
import fastapi._compat
import fastapi.openapi.utils
Set of Types whose `__iter__()` method yields results sorted by the type names
"""
- def __init__(self, seq: Set[Type[Any]], *, sort_reversed: bool):
+ def __init__(self, seq: set[type[Any]], *, sort_reversed: bool):
super().__init__(seq)
self.sort_reversed = sort_reversed
- def __iter__(self) -> Iterator[Type[Any]]:
+ def __iter__(self) -> Iterator[type[Any]]:
members_sorted = sorted(
super().__iter__(),
key=lambda type_: type_.__name__,
-from typing import Dict, List, Tuple
-
import pytest
from fastapi import FastAPI
from pydantic import BaseModel
title: str
@app.get("/items/{id}")
- def read_items(id: List[Item]):
+ def read_items(id: list[Item]):
pass # pragma: no cover
title: str
@app.get("/items/{id}")
- def read_items(id: Tuple[Item, Item]):
+ def read_items(id: tuple[Item, Item]):
pass # pragma: no cover
title: str
@app.get("/items/{id}")
- def read_items(id: Dict[str, Item]):
+ def read_items(id: dict[str, Item]):
pass # pragma: no cover
-from typing import Dict, List, Optional, Tuple
+from typing import Optional
import pytest
from fastapi import FastAPI, Query
title: str
@app.get("/items/")
- def read_items(q: List[Item] = Query(default=None)):
+ def read_items(q: list[Item] = Query(default=None)):
pass # pragma: no cover
title: str
@app.get("/items/")
- def read_items(q: Tuple[Item, Item] = Query(default=None)):
+ def read_items(q: tuple[Item, Item] = Query(default=None)):
pass # pragma: no cover
title: str
@app.get("/items/")
- def read_items(q: Dict[str, Item] = Query(default=None)):
+ def read_items(q: dict[str, Item] = Query(default=None)):
pass # pragma: no cover
from decimal import Decimal
-from typing import List
from dirty_equals import IsDict, IsOneOf
from fastapi import FastAPI
@app.post("/items/")
-def save_item_no_body(item: List[Item]):
+def save_item_no_body(item: list[Item]):
return {"item": item}
-from typing import List
-
from dirty_equals import IsDict
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
@app.get("/items/")
-def read_items(q: List[int] = Query(default=None)):
+def read_items(q: list[int] = Query(default=None)):
return {"q": q}
# Made an issue in:
# https://github.com/fastapi/fastapi/issues/14247
from enum import Enum
-from typing import List
from fastapi import FastAPI
from fastapi.testclient import TestClient
class MessageOutput(BaseModel):
body: str = ""
- events: List[MessageEvent] = []
+ events: list[MessageEvent] = []
class Message(BaseModel):
-from typing import List, Optional, Union
+from typing import Optional, Union
import pytest
from fastapi.openapi.models import Schema, SchemaType
],
)
def test_allowed_schema_type(
- type_value: Optional[Union[SchemaType, List[SchemaType]]],
+ type_value: Optional[Union[SchemaType, list[SchemaType]]],
) -> None:
"""Test that Schema accepts SchemaType, List[SchemaType] and None for type field."""
schema = Schema(type=type_value)
-from typing import List, Optional
+from typing import Optional
from fastapi import FastAPI
from fastapi.testclient import TestClient
class SubItem(BaseModel):
subname: str
sub_description: Optional[str] = None
- tags: List[str] = []
+ tags: list[str] = []
if PYDANTIC_V2:
model_config = {"json_schema_serialization_defaults_required": True}
return item
@app.post("/items-list/")
- def create_item_list(item: List[Item]):
+ def create_item_list(item: list[Item]):
return item
@app.get("/items/")
- def read_items() -> List[Item]:
+ def read_items() -> list[Item]:
return [
Item(
name="Portal Gun",
-from typing import List, Optional
+from typing import Optional
from fastapi import FastAPI, File
from fastapi.testclient import TestClient
@app.post("/files")
-async def upload_files(files: Optional[List[bytes]] = File(None)):
+async def upload_files(files: Optional[list[bytes]] = File(None)):
if files is None:
return {"files_count": 0}
return {"files_count": len(files), "sizes": [len(f) for f in files]}
-from typing import Any, List
+from typing import Any
from dirty_equals import IsOneOf
from fastapi.params import Body, Cookie, Header, Param, Path, Query
-test_data: List[Any] = ["teststr", None, ..., 1, []]
+test_data: list[Any] = ["teststr", None, ..., 1, []]
def get_user():
import sys
-from typing import Any, List, Union
+from typing import Any, Union
from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
size: int
description: Union[str, None] = None
sub: SubItem
- multi: List[SubItem] = []
+ multi: list[SubItem] = []
app = FastAPI()
import sys
-from typing import Any, List, Union
+from typing import Any, Union
from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
size: int
description: Union[str, None] = None
sub: SubItem
- multi: List[SubItem] = []
+ multi: list[SubItem] = []
app = FastAPI()
@app.post("/item")
-def handle_item(data: Item) -> List[Item]:
+def handle_item(data: Item) -> list[Item]:
return [data, data]
-@app.post("/item-filter", response_model=List[Item])
+@app.post("/item-filter", response_model=list[Item])
def handle_item_filter(data: Item) -> Any:
extended_data = data.dict()
extended_data.update({"secret_data": "classified", "internal_id": 12345})
@app.post("/item-list")
-def handle_item_list(data: List[Item]) -> Item:
+def handle_item_list(data: list[Item]) -> Item:
if data:
return data[0]
return Item(title="", size=0, sub=SubItem(name=""))
@app.post("/item-list-filter", response_model=Item)
-def handle_item_list_filter(data: List[Item]) -> Any:
+def handle_item_list_filter(data: list[Item]) -> Any:
if data:
extended_data = data[0].dict()
extended_data.update({"secret_data": "classified", "internal_id": 12345})
@app.post("/item-list-to-list")
-def handle_item_list_to_list(data: List[Item]) -> List[Item]:
+def handle_item_list_to_list(data: list[Item]) -> list[Item]:
return data
-@app.post("/item-list-to-list-filter", response_model=List[Item])
-def handle_item_list_to_list_filter(data: List[Item]) -> Any:
+@app.post("/item-list-to-list-filter", response_model=list[Item])
+def handle_item_list_to_list_filter(data: list[Item]) -> Any:
if data:
extended_data = data[0].dict()
extended_data.update({"secret_data": "classified", "internal_id": 12345})
import sys
-from typing import Any, List, Union
+from typing import Any, Union
from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
size: int
description: Union[str, None] = None
sub: SubItem
- multi: List[SubItem] = []
+ multi: list[SubItem] = []
class NewSubItem(NewBaseModel):
new_size: int
new_description: Union[str, None] = None
new_sub: NewSubItem
- new_multi: List[NewSubItem] = []
+ new_multi: list[NewSubItem] = []
app = FastAPI()
@app.post("/v1-to-v2/item-to-list")
-def handle_v1_item_to_v2_list(data: Item) -> List[NewItem]:
+def handle_v1_item_to_v2_list(data: Item) -> list[NewItem]:
converted = NewItem(
new_title=data.title,
new_size=data.size,
@app.post("/v1-to-v2/list-to-list")
-def handle_v1_list_to_v2_list(data: List[Item]) -> List[NewItem]:
+def handle_v1_list_to_v2_list(data: list[Item]) -> list[NewItem]:
result = []
for item in data:
result.append(
return result
-@app.post("/v1-to-v2/list-to-list-filter", response_model=List[NewItem])
-def handle_v1_list_to_v2_list_filter(data: List[Item]) -> Any:
+@app.post("/v1-to-v2/list-to-list-filter", response_model=list[NewItem])
+def handle_v1_list_to_v2_list_filter(data: list[Item]) -> Any:
result = []
for item in data:
converted = {
@app.post("/v1-to-v2/list-to-item")
-def handle_v1_list_to_v2_item(data: List[Item]) -> NewItem:
+def handle_v1_list_to_v2_item(data: list[Item]) -> NewItem:
if data:
item = data[0]
return NewItem(
@app.post("/v2-to-v1/item-to-list")
-def handle_v2_item_to_v1_list(data: NewItem) -> List[Item]:
+def handle_v2_item_to_v1_list(data: NewItem) -> list[Item]:
converted = Item(
title=data.new_title,
size=data.new_size,
@app.post("/v2-to-v1/list-to-list")
-def handle_v2_list_to_v1_list(data: List[NewItem]) -> List[Item]:
+def handle_v2_list_to_v1_list(data: list[NewItem]) -> list[Item]:
result = []
for item in data:
result.append(
return result
-@app.post("/v2-to-v1/list-to-list-filter", response_model=List[Item])
-def handle_v2_list_to_v1_list_filter(data: List[NewItem]) -> Any:
+@app.post("/v2-to-v1/list-to-list-filter", response_model=list[Item])
+def handle_v2_list_to_v1_list_filter(data: list[NewItem]) -> Any:
result = []
for item in data:
converted = {
@app.post("/v2-to-v1/list-to-item")
-def handle_v2_list_to_v1_item(data: List[NewItem]) -> Item:
+def handle_v2_list_to_v1_item(data: list[NewItem]) -> Item:
if data:
item = data[0]
return Item(
-from typing import List
-
from fastapi import FastAPI
from . import modelsv1, modelsv2, modelsv2b
@app.post("/v1-to-v2/item-to-list")
-def handle_v1_item_to_v2_list(data: modelsv1.Item) -> List[modelsv2.Item]:
+def handle_v1_item_to_v2_list(data: modelsv1.Item) -> list[modelsv2.Item]:
converted = modelsv2.Item(
new_title=data.title,
new_size=data.size,
@app.post("/v1-to-v2/list-to-list")
-def handle_v1_list_to_v2_list(data: List[modelsv1.Item]) -> List[modelsv2.Item]:
+def handle_v1_list_to_v2_list(data: list[modelsv1.Item]) -> list[modelsv2.Item]:
result = []
for item in data:
result.append(
@app.post("/v1-to-v2/list-to-item")
-def handle_v1_list_to_v2_item(data: List[modelsv1.Item]) -> modelsv2.Item:
+def handle_v1_list_to_v2_item(data: list[modelsv1.Item]) -> modelsv2.Item:
if data:
item = data[0]
return modelsv2.Item(
@app.post("/v2-to-v1/item-to-list")
-def handle_v2_item_to_v1_list(data: modelsv2.Item) -> List[modelsv1.Item]:
+def handle_v2_item_to_v1_list(data: modelsv2.Item) -> list[modelsv1.Item]:
converted = modelsv1.Item(
title=data.new_title,
size=data.new_size,
@app.post("/v2-to-v1/list-to-list")
-def handle_v2_list_to_v1_list(data: List[modelsv2.Item]) -> List[modelsv1.Item]:
+def handle_v2_list_to_v1_list(data: list[modelsv2.Item]) -> list[modelsv1.Item]:
result = []
for item in data:
result.append(
@app.post("/v2-to-v1/list-to-item")
-def handle_v2_list_to_v1_item(data: List[modelsv2.Item]) -> modelsv1.Item:
+def handle_v2_list_to_v1_item(data: list[modelsv2.Item]) -> modelsv1.Item:
if data:
item = data[0]
return modelsv1.Item(
@app.post("/v2-to-v1/list-of-items-to-list-of-items")
def handle_v2_items_in_list_to_v1_item_in_list(
- data1: List[modelsv2.ItemInList], data2: List[modelsv2b.ItemInList]
-) -> List[modelsv1.ItemInList]:
+ data1: list[modelsv2.ItemInList], data2: list[modelsv2b.ItemInList]
+) -> list[modelsv1.ItemInList]:
result = []
item1 = data1[0]
item2 = data2[0]
-from typing import List, Union
+from typing import Union
from fastapi._compat.v1 import BaseModel
size: int
description: Union[str, None] = None
sub: SubItem
- multi: List[SubItem] = []
+ multi: list[SubItem] = []
class ItemInList(BaseModel):
-from typing import List, Union
+from typing import Union
from pydantic import BaseModel
new_size: int
new_description: Union[str, None] = None
new_sub: SubItem
- new_multi: List[SubItem] = []
+ new_multi: list[SubItem] = []
class ItemInList(BaseModel):
-from typing import List, Union
+from typing import Union
from pydantic import BaseModel
dup_size: int
dup_description: Union[str, None] = None
dup_sub: SubItem
- dup_multi: List[SubItem] = []
+ dup_multi: list[SubItem] = []
class ItemInList(BaseModel):
import sys
-from typing import Any, List, Union
+from typing import Any, Union
from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
size: int
description: Union[str, None] = None
sub: SubItem
- multi: List[SubItem] = []
+ multi: list[SubItem] = []
class NewSubItem(NewBaseModel):
new_size: int
new_description: Union[str, None] = None
new_sub: NewSubItem
- new_multi: List[NewSubItem] = []
+ new_multi: list[NewSubItem] = []
app = FastAPI()
import uuid
from dataclasses import dataclass, field
-from typing import List, Union
+from typing import Union
from dirty_equals import IsUUID
from fastapi import FastAPI
id: uuid.UUID
name: str
price: float
- tags: List[str] = field(default_factory=list)
+ tags: list[str] = field(default_factory=list)
description: Union[str, None] = None
tax: Union[float, None] = None
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from .utils import needs_py310
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from .utils import needs_py310
-import typing
-
from fastapi import Body, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
@app.post("/shops")
async def create_shop(
data: Shop = Body(media_type=media_type),
- included: typing.List[Product] = Body(default=[], media_type=media_type),
+ included: list[Product] = Body(default=[], media_type=media_type),
):
pass # pragma: no cover
-from typing import List, Union
+from typing import Annotated, Union
import pytest
from dirty_equals import IsDict, IsOneOf, IsPartialDict
from fastapi import Body, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/required-list-str", operation_id="required_list_str")
-async def read_required_list_str(p: Annotated[List[str], Body(embed=True)]):
+async def read_required_list_str(p: Annotated[list[str], Body(embed=True)]):
return {"p": p}
class BodyModelRequiredListStr(BaseModel):
- p: List[str]
+ p: list[str]
@app.post("/model-required-list-str", operation_id="model_required_list_str")
@app.post("/required-list-alias", operation_id="required_list_alias")
async def read_required_list_alias(
- p: Annotated[List[str], Body(embed=True, alias="p_alias")],
+ p: Annotated[list[str], Body(embed=True, alias="p_alias")],
):
return {"p": p}
class BodyModelRequiredListAlias(BaseModel):
- p: List[str] = Field(alias="p_alias")
+ p: list[str] = Field(alias="p_alias")
@app.post("/model-required-list-alias", operation_id="model_required_list_alias")
"/required-list-validation-alias", operation_id="required_list_validation_alias"
)
def read_required_list_validation_alias(
- p: Annotated[List[str], Body(embed=True, validation_alias="p_val_alias")],
+ p: Annotated[list[str], Body(embed=True, validation_alias="p_val_alias")],
):
return {"p": p}
class BodyModelRequiredListValidationAlias(BaseModel):
- p: List[str] = Field(validation_alias="p_val_alias")
+ p: list[str] = Field(validation_alias="p_val_alias")
@app.post(
)
def read_required_list_alias_and_validation_alias(
p: Annotated[
- List[str], Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
+ list[str], Body(embed=True, alias="p_alias", validation_alias="p_val_alias")
],
):
return {"p": p}
class BodyModelRequiredListAliasAndValidationAlias(BaseModel):
- p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
+ p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post(
-from typing import List, Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import Body, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/optional-list-str", operation_id="optional_list_str")
async def read_optional_list_str(
- p: Annotated[Optional[List[str]], Body(embed=True)] = None,
+ p: Annotated[Optional[list[str]], Body(embed=True)] = None,
):
return {"p": p}
class BodyModelOptionalListStr(BaseModel):
- p: Optional[List[str]] = None
+ p: Optional[list[str]] = None
@app.post("/model-optional-list-str", operation_id="model_optional_list_str")
@app.post("/optional-list-alias", operation_id="optional_list_alias")
async def read_optional_list_alias(
- p: Annotated[Optional[List[str]], Body(embed=True, alias="p_alias")] = None,
+ p: Annotated[Optional[list[str]], Body(embed=True, alias="p_alias")] = None,
):
return {"p": p}
class BodyModelOptionalListAlias(BaseModel):
- p: Optional[List[str]] = Field(None, alias="p_alias")
+ p: Optional[list[str]] = Field(None, alias="p_alias")
@app.post("/model-optional-list-alias", operation_id="model_optional_list_alias")
)
def read_optional_list_validation_alias(
p: Annotated[
- Optional[List[str]], Body(embed=True, validation_alias="p_val_alias")
+ Optional[list[str]], Body(embed=True, validation_alias="p_val_alias")
] = None,
):
return {"p": p}
class BodyModelOptionalListValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(None, validation_alias="p_val_alias")
+ p: Optional[list[str]] = Field(None, validation_alias="p_val_alias")
@app.post(
)
def read_optional_list_alias_and_validation_alias(
p: Annotated[
- Optional[List[str]],
+ Optional[list[str]],
Body(embed=True, alias="p_alias", validation_alias="p_val_alias"),
] = None,
):
class BodyModelOptionalListAliasAndValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(
+ p: Optional[list[str]] = Field(
None, alias="p_alias", validation_alias="p_val_alias"
)
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import Body, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import Any, Dict, Union
+from typing import Annotated, Any, Union
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi import Body, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
"path",
["/required-str", "/model-required-str"],
)
-def test_required_str_missing(path: str, json: Union[Dict[str, Any], None]):
+def test_required_str_missing(path: str, json: Union[dict[str, Any], None]):
client = TestClient(app)
response = client.post(path, json=json)
assert response.status_code == 422
"path",
["/required-alias", "/model-required-alias"],
)
-def test_required_alias_missing(path: str, json: Union[Dict[str, Any], None]):
+def test_required_alias_missing(path: str, json: Union[dict[str, Any], None]):
client = TestClient(app)
response = client.post(path, json=json)
assert response.status_code == 422
],
)
def test_required_validation_alias_missing(
- path: str, json: Union[Dict[str, Any], None]
+ path: str, json: Union[dict[str, Any], None]
):
client = TestClient(app)
response = client.post(path, json=json)
],
)
def test_required_alias_and_validation_alias_missing(
- path: str, json: Union[Dict[str, Any], None]
+ path: str, json: Union[dict[str, Any], None]
):
client = TestClient(app)
response = client.post(path, json=json)
-from typing import Any, Dict
+from typing import Any
-def get_body_model_name(openapi: Dict[str, Any], path: str) -> str:
+def get_body_model_name(openapi: dict[str, Any], path: str) -> str:
body = openapi["paths"][path]["post"]["requestBody"]
body_schema = body["content"]["application/json"]["schema"]
return body_schema.get("$ref", "").split("/")[-1]
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import Cookie, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi import Cookie, FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import List
+from typing import Annotated
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, File, UploadFile
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/list-bytes", operation_id="list_bytes")
-async def read_list_bytes(p: Annotated[List[bytes], File()]):
+async def read_list_bytes(p: Annotated[list[bytes], File()]):
return {"file_size": [len(file) for file in p]}
@app.post("/list-uploadfile", operation_id="list_uploadfile")
-async def read_list_uploadfile(p: Annotated[List[UploadFile], File()]):
+async def read_list_uploadfile(p: Annotated[list[UploadFile], File()]):
return {"file_size": [file.size for file in p]}
@app.post("/list-bytes-alias", operation_id="list_bytes_alias")
-async def read_list_bytes_alias(p: Annotated[List[bytes], File(alias="p_alias")]):
+async def read_list_bytes_alias(p: Annotated[list[bytes], File(alias="p_alias")]):
return {"file_size": [len(file) for file in p]}
@app.post("/list-uploadfile-alias", operation_id="list_uploadfile_alias")
async def read_list_uploadfile_alias(
- p: Annotated[List[UploadFile], File(alias="p_alias")],
+ p: Annotated[list[UploadFile], File(alias="p_alias")],
):
return {"file_size": [file.size for file in p]}
@app.post("/list-bytes-validation-alias", operation_id="list_bytes_validation_alias")
def read_list_bytes_validation_alias(
- p: Annotated[List[bytes], File(validation_alias="p_val_alias")],
+ p: Annotated[list[bytes], File(validation_alias="p_val_alias")],
):
return {"file_size": [len(file) for file in p]}
operation_id="list_uploadfile_validation_alias",
)
def read_list_uploadfile_validation_alias(
- p: Annotated[List[UploadFile], File(validation_alias="p_val_alias")],
+ p: Annotated[list[UploadFile], File(validation_alias="p_val_alias")],
):
return {"file_size": [file.size for file in p]}
operation_id="list_bytes_alias_and_validation_alias",
)
def read_list_bytes_alias_and_validation_alias(
- p: Annotated[List[bytes], File(alias="p_alias", validation_alias="p_val_alias")],
+ p: Annotated[list[bytes], File(alias="p_alias", validation_alias="p_val_alias")],
):
return {"file_size": [len(file) for file in p]}
)
def read_list_uploadfile_alias_and_validation_alias(
p: Annotated[
- List[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
+ list[UploadFile], File(alias="p_alias", validation_alias="p_val_alias")
],
):
return {"file_size": [file.size for file in p]}
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, File, UploadFile
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import List, Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, File, UploadFile
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/optional-list-bytes")
-async def read_optional_list_bytes(p: Annotated[Optional[List[bytes]], File()] = None):
+async def read_optional_list_bytes(p: Annotated[Optional[list[bytes]], File()] = None):
return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile")
async def read_optional_list_uploadfile(
- p: Annotated[Optional[List[UploadFile]], File()] = None,
+ p: Annotated[Optional[list[UploadFile]], File()] = None,
):
return {"file_size": [file.size for file in p] if p else None}
@app.post("/optional-list-bytes-alias")
async def read_optional_list_bytes_alias(
- p: Annotated[Optional[List[bytes]], File(alias="p_alias")] = None,
+ p: Annotated[Optional[list[bytes]], File(alias="p_alias")] = None,
):
return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-alias")
async def read_optional_list_uploadfile_alias(
- p: Annotated[Optional[List[UploadFile]], File(alias="p_alias")] = None,
+ p: Annotated[Optional[list[UploadFile]], File(alias="p_alias")] = None,
):
return {"file_size": [file.size for file in p] if p else None}
@app.post("/optional-list-bytes-validation-alias")
def read_optional_list_bytes_validation_alias(
- p: Annotated[Optional[List[bytes]], File(validation_alias="p_val_alias")] = None,
+ p: Annotated[Optional[list[bytes]], File(validation_alias="p_val_alias")] = None,
):
return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-validation-alias")
def read_optional_list_uploadfile_validation_alias(
p: Annotated[
- Optional[List[UploadFile]], File(validation_alias="p_val_alias")
+ Optional[list[UploadFile]], File(validation_alias="p_val_alias")
] = None,
):
return {"file_size": [file.size for file in p] if p else None}
@app.post("/optional-list-bytes-alias-and-validation-alias")
def read_optional_list_bytes_alias_and_validation_alias(
p: Annotated[
- Optional[List[bytes]], File(alias="p_alias", validation_alias="p_val_alias")
+ Optional[list[bytes]], File(alias="p_alias", validation_alias="p_val_alias")
] = None,
):
return {"file_size": [len(file) for file in p] if p else None}
@app.post("/optional-list-uploadfile-alias-and-validation-alias")
def read_optional_list_uploadfile_alias_and_validation_alias(
p: Annotated[
- Optional[List[UploadFile]],
+ Optional[list[UploadFile]],
File(alias="p_alias", validation_alias="p_val_alias"),
] = None,
):
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, File, UploadFile
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import Any, Dict
+from typing import Any
-def get_body_model_name(openapi: Dict[str, Any], path: str) -> str:
+def get_body_model_name(openapi: dict[str, Any], path: str) -> str:
body = openapi["paths"][path]["post"]["requestBody"]
body_schema = body["content"]["multipart/form-data"]["schema"]
return body_schema.get("$ref", "").split("/")[-1]
-from typing import List
+from typing import Annotated
import pytest
from dirty_equals import IsDict, IsOneOf, IsPartialDict
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/required-list-str", operation_id="required_list_str")
-async def read_required_list_str(p: Annotated[List[str], Form()]):
+async def read_required_list_str(p: Annotated[list[str], Form()]):
return {"p": p}
class FormModelRequiredListStr(BaseModel):
- p: List[str]
+ p: list[str]
@app.post("/model-required-list-str", operation_id="model_required_list_str")
@app.post("/required-list-alias", operation_id="required_list_alias")
-async def read_required_list_alias(p: Annotated[List[str], Form(alias="p_alias")]):
+async def read_required_list_alias(p: Annotated[list[str], Form(alias="p_alias")]):
return {"p": p}
class FormModelRequiredListAlias(BaseModel):
- p: List[str] = Field(alias="p_alias")
+ p: list[str] = Field(alias="p_alias")
@app.post("/model-required-list-alias", operation_id="model_required_list_alias")
"/required-list-validation-alias", operation_id="required_list_validation_alias"
)
def read_required_list_validation_alias(
- p: Annotated[List[str], Form(validation_alias="p_val_alias")],
+ p: Annotated[list[str], Form(validation_alias="p_val_alias")],
):
return {"p": p}
class FormModelRequiredListValidationAlias(BaseModel):
- p: List[str] = Field(validation_alias="p_val_alias")
+ p: list[str] = Field(validation_alias="p_val_alias")
@app.post(
operation_id="required_list_alias_and_validation_alias",
)
def read_required_list_alias_and_validation_alias(
- p: Annotated[List[str], Form(alias="p_alias", validation_alias="p_val_alias")],
+ p: Annotated[list[str], Form(alias="p_alias", validation_alias="p_val_alias")],
):
return {"p": p}
class FormModelRequiredListAliasAndValidationAlias(BaseModel):
- p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
+ p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.post(
-from typing import List, Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.post("/optional-list-str", operation_id="optional_list_str")
async def read_optional_list_str(
- p: Annotated[Optional[List[str]], Form()] = None,
+ p: Annotated[Optional[list[str]], Form()] = None,
):
return {"p": p}
class FormModelOptionalListStr(BaseModel):
- p: Optional[List[str]] = None
+ p: Optional[list[str]] = None
@app.post("/model-optional-list-str", operation_id="model_optional_list_str")
@app.post("/optional-list-alias", operation_id="optional_list_alias")
async def read_optional_list_alias(
- p: Annotated[Optional[List[str]], Form(alias="p_alias")] = None,
+ p: Annotated[Optional[list[str]], Form(alias="p_alias")] = None,
):
return {"p": p}
class FormModelOptionalListAlias(BaseModel):
- p: Optional[List[str]] = Field(None, alias="p_alias")
+ p: Optional[list[str]] = Field(None, alias="p_alias")
@app.post("/model-optional-list-alias", operation_id="model_optional_list_alias")
"/optional-list-validation-alias", operation_id="optional_list_validation_alias"
)
def read_optional_list_validation_alias(
- p: Annotated[Optional[List[str]], Form(validation_alias="p_val_alias")] = None,
+ p: Annotated[Optional[list[str]], Form(validation_alias="p_val_alias")] = None,
):
return {"p": p}
class FormModelOptionalListValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(None, validation_alias="p_val_alias")
+ p: Optional[list[str]] = Field(None, validation_alias="p_val_alias")
@app.post(
)
def read_optional_list_alias_and_validation_alias(
p: Annotated[
- Optional[List[str]], Form(alias="p_alias", validation_alias="p_val_alias")
+ Optional[list[str]], Form(alias="p_alias", validation_alias="p_val_alias")
] = None,
):
return {"p": p}
class FormModelOptionalListAliasAndValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(
+ p: Optional[list[str]] = Field(
None, alias="p_alias", validation_alias="p_val_alias"
)
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import Any, Dict
+from typing import Any
-def get_body_model_name(openapi: Dict[str, Any], path: str) -> str:
+def get_body_model_name(openapi: dict[str, Any], path: str) -> str:
body = openapi["paths"][path]["post"]["requestBody"]
body_schema = body["content"]["application/x-www-form-urlencoded"]["schema"]
return body_schema.get("$ref", "").split("/")[-1]
-from typing import List
+from typing import Annotated
import pytest
from dirty_equals import AnyThing, IsDict, IsOneOf, IsPartialDict
from fastapi import FastAPI, Header
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.get("/required-list-str")
-async def read_required_list_str(p: Annotated[List[str], Header()]):
+async def read_required_list_str(p: Annotated[list[str], Header()]):
return {"p": p}
class HeaderModelRequiredListStr(BaseModel):
- p: List[str]
+ p: list[str]
@app.get("/model-required-list-str")
@app.get("/required-list-alias")
-async def read_required_list_alias(p: Annotated[List[str], Header(alias="p_alias")]):
+async def read_required_list_alias(p: Annotated[list[str], Header(alias="p_alias")]):
return {"p": p}
class HeaderModelRequiredListAlias(BaseModel):
- p: List[str] = Field(alias="p_alias")
+ p: list[str] = Field(alias="p_alias")
@app.get("/model-required-list-alias")
@app.get("/required-list-validation-alias")
def read_required_list_validation_alias(
- p: Annotated[List[str], Header(validation_alias="p_val_alias")],
+ p: Annotated[list[str], Header(validation_alias="p_val_alias")],
):
return {"p": p}
class HeaderModelRequiredListValidationAlias(BaseModel):
- p: List[str] = Field(validation_alias="p_val_alias")
+ p: list[str] = Field(validation_alias="p_val_alias")
@app.get("/model-required-list-validation-alias")
@app.get("/required-list-alias-and-validation-alias")
def read_required_list_alias_and_validation_alias(
- p: Annotated[List[str], Header(alias="p_alias", validation_alias="p_val_alias")],
+ p: Annotated[list[str], Header(alias="p_alias", validation_alias="p_val_alias")],
):
return {"p": p}
class HeaderModelRequiredListAliasAndValidationAlias(BaseModel):
- p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
+ p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-list-alias-and-validation-alias")
-from typing import List, Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Header
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.get("/optional-list-str")
async def read_optional_list_str(
- p: Annotated[Optional[List[str]], Header()] = None,
+ p: Annotated[Optional[list[str]], Header()] = None,
):
return {"p": p}
class HeaderModelOptionalListStr(BaseModel):
- p: Optional[List[str]] = None
+ p: Optional[list[str]] = None
@app.get("/model-optional-list-str")
@app.get("/optional-list-alias")
async def read_optional_list_alias(
- p: Annotated[Optional[List[str]], Header(alias="p_alias")] = None,
+ p: Annotated[Optional[list[str]], Header(alias="p_alias")] = None,
):
return {"p": p}
class HeaderModelOptionalListAlias(BaseModel):
- p: Optional[List[str]] = Field(None, alias="p_alias")
+ p: Optional[list[str]] = Field(None, alias="p_alias")
@app.get("/model-optional-list-alias")
@app.get("/optional-list-validation-alias")
def read_optional_list_validation_alias(
- p: Annotated[Optional[List[str]], Header(validation_alias="p_val_alias")] = None,
+ p: Annotated[Optional[list[str]], Header(validation_alias="p_val_alias")] = None,
):
return {"p": p}
class HeaderModelOptionalListValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(None, validation_alias="p_val_alias")
+ p: Optional[list[str]] = Field(None, validation_alias="p_val_alias")
@app.get("/model-optional-list-validation-alias")
@app.get("/optional-list-alias-and-validation-alias")
def read_optional_list_alias_and_validation_alias(
p: Annotated[
- Optional[List[str]], Header(alias="p_alias", validation_alias="p_val_alias")
+ Optional[list[str]], Header(alias="p_alias", validation_alias="p_val_alias")
] = None,
):
return {"p": p}
class HeaderModelOptionalListAliasAndValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(
+ p: Optional[list[str]] = Field(
None, alias="p_alias", validation_alias="p_val_alias"
)
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Header
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
+from typing import Annotated
+
import pytest
from dirty_equals import AnyThing, IsDict, IsOneOf, IsPartialDict
from fastapi import FastAPI, Header
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
+from typing import Annotated
+
import pytest
from fastapi import FastAPI, Path
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import List
+from typing import Annotated
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.get("/required-list-str")
-async def read_required_list_str(p: Annotated[List[str], Query()]):
+async def read_required_list_str(p: Annotated[list[str], Query()]):
return {"p": p}
class QueryModelRequiredListStr(BaseModel):
- p: List[str]
+ p: list[str]
@app.get("/model-required-list-str")
@app.get("/required-list-alias")
-async def read_required_list_alias(p: Annotated[List[str], Query(alias="p_alias")]):
+async def read_required_list_alias(p: Annotated[list[str], Query(alias="p_alias")]):
return {"p": p}
class QueryModelRequiredListAlias(BaseModel):
- p: List[str] = Field(alias="p_alias")
+ p: list[str] = Field(alias="p_alias")
@app.get("/model-required-list-alias")
@app.get("/required-list-validation-alias")
def read_required_list_validation_alias(
- p: Annotated[List[str], Query(validation_alias="p_val_alias")],
+ p: Annotated[list[str], Query(validation_alias="p_val_alias")],
):
return {"p": p}
class QueryModelRequiredListValidationAlias(BaseModel):
- p: List[str] = Field(validation_alias="p_val_alias")
+ p: list[str] = Field(validation_alias="p_val_alias")
@app.get("/model-required-list-validation-alias")
@app.get("/required-list-alias-and-validation-alias")
def read_required_list_alias_and_validation_alias(
- p: Annotated[List[str], Query(alias="p_alias", validation_alias="p_val_alias")],
+ p: Annotated[list[str], Query(alias="p_alias", validation_alias="p_val_alias")],
):
return {"p": p}
class QueryModelRequiredListAliasAndValidationAlias(BaseModel):
- p: List[str] = Field(alias="p_alias", validation_alias="p_val_alias")
+ p: list[str] = Field(alias="p_alias", validation_alias="p_val_alias")
@app.get("/model-required-list-alias-and-validation-alias")
-from typing import List, Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
@app.get("/optional-list-str")
async def read_optional_list_str(
- p: Annotated[Optional[List[str]], Query()] = None,
+ p: Annotated[Optional[list[str]], Query()] = None,
):
return {"p": p}
class QueryModelOptionalListStr(BaseModel):
- p: Optional[List[str]] = None
+ p: Optional[list[str]] = None
@app.get("/model-optional-list-str")
@app.get("/optional-list-alias")
async def read_optional_list_alias(
- p: Annotated[Optional[List[str]], Query(alias="p_alias")] = None,
+ p: Annotated[Optional[list[str]], Query(alias="p_alias")] = None,
):
return {"p": p}
class QueryModelOptionalListAlias(BaseModel):
- p: Optional[List[str]] = Field(None, alias="p_alias")
+ p: Optional[list[str]] = Field(None, alias="p_alias")
@app.get("/model-optional-list-alias")
@app.get("/optional-list-validation-alias")
def read_optional_list_validation_alias(
- p: Annotated[Optional[List[str]], Query(validation_alias="p_val_alias")] = None,
+ p: Annotated[Optional[list[str]], Query(validation_alias="p_val_alias")] = None,
):
return {"p": p}
class QueryModelOptionalListValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(None, validation_alias="p_val_alias")
+ p: Optional[list[str]] = Field(None, validation_alias="p_val_alias")
@app.get("/model-optional-list-validation-alias")
@app.get("/optional-list-alias-and-validation-alias")
def read_optional_list_alias_and_validation_alias(
p: Annotated[
- Optional[List[str]], Query(alias="p_alias", validation_alias="p_val_alias")
+ Optional[list[str]], Query(alias="p_alias", validation_alias="p_val_alias")
] = None,
):
return {"p": p}
class QueryModelOptionalListAliasAndValidationAlias(BaseModel):
- p: Optional[List[str]] = Field(
+ p: Optional[list[str]] = Field(
None, alias="p_alias", validation_alias="p_val_alias"
)
-from typing import Optional
+from typing import Annotated, Optional
import pytest
from dirty_equals import IsDict
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
+from typing import Annotated
+
import pytest
from dirty_equals import IsDict, IsOneOf
from fastapi import FastAPI, Query
from fastapi.testclient import TestClient
from pydantic import BaseModel, Field
-from typing_extensions import Annotated
from tests.utils import needs_pydanticv2
-from typing import List
-
from fastapi import FastAPI
from fastapi._compat import PYDANTIC_V2
from fastapi.testclient import TestClient
return Model(alias="Foo")
-@app.get("/list", response_model=List[Model], response_model_by_alias=False)
+@app.get("/list", response_model=list[Model], response_model_by_alias=False)
def read_list():
return [{"alias": "Foo"}, {"alias": "Bar"}]
return Model(alias="Foo")
-@app.get("/by-alias/list", response_model=List[Model])
+@app.get("/by-alias/list", response_model=list[Model])
def by_alias_list():
return [{"alias": "Foo"}, {"alias": "Bar"}]
return ModelNoAlias(name="Foo")
-@app.get("/no-alias/list", response_model=List[ModelNoAlias])
+@app.get("/no-alias/list", response_model=list[ModelNoAlias])
def no_alias_list():
return [{"name": "Foo"}, {"name": "Bar"}]
-import typing
-
from fastapi import FastAPI, Response
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
class JsonApiError(BaseModel):
- errors: typing.List[Error]
+ errors: list[Error]
@app.get(
-import typing
-
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
class JsonApiError(BaseModel):
- errors: typing.List[Error]
+ errors: list[Error]
@app.get(
-from typing import List, Union
+from typing import Union
import pytest
from fastapi import FastAPI
return DBUser(name="John", surname="Doe", password_hash="secret")
-@app.get("/response_model_list_of_model-no_annotation", response_model=List[User])
+@app.get("/response_model_list_of_model-no_annotation", response_model=list[User])
def response_model_list_of_model_no_annotation():
return [
DBUser(name="John", surname="Doe", password_hash="secret"),
@app.get("/no_response_model-annotation_list_of_model")
-def no_response_model_annotation_list_of_model() -> List[User]:
+def no_response_model_annotation_list_of_model() -> list[User]:
return [
DBUser(name="John", surname="Doe", password_hash="secret"),
DBUser(name="Jane", surname="Does", password_hash="secret2"),
@app.get("/no_response_model-annotation_forward_ref_list_of_model")
-def no_response_model_annotation_forward_ref_list_of_model() -> "List[User]":
+def no_response_model_annotation_forward_ref_list_of_model() -> "list[User]":
return [
DBUser(name="John", surname="Doe", password_hash="secret"),
DBUser(name="Jane", surname="Does", password_hash="secret2"),
-from typing import List
-
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
return pet
-@app.get("/pets/", response_model=List[PetOut])
+@app.get("/pets/", response_model=list[PetOut])
async def read_pets():
user = UserDB(
email="johndoe@example.com",
-from typing import List
-
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
return pet
-@app.get("/pets/", response_model=List[PetOut])
+@app.get("/pets/", response_model=list[PetOut])
async def read_pets():
user = UserDB(
email="johndoe@example.com",
-from typing import List
-
import pytest
from fastapi import FastAPI
from fastapi.exceptions import FastAPIError
with pytest.raises(FastAPIError):
app = FastAPI()
- @app.get("/", response_model=List[NonPydanticModel])
+ @app.get("/", response_model=list[NonPydanticModel])
def read_root():
pass # pragma: nocover
with pytest.raises(FastAPIError):
app = FastAPI()
- @app.get("/", responses={"500": {"model": List[NonPydanticModel]}})
+ @app.get("/", responses={"500": {"model": list[NonPydanticModel]}})
def read_root():
pass # pragma: nocover
-from typing import List
-
from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel
pass
-@app.get("/valid2", responses={"500": {"model": List[int]}})
+@app.get("/valid2", responses={"500": {"model": list[int]}})
def valid2():
pass
pass
-@app.get("/valid4", responses={"500": {"model": List[Model]}})
+@app.get("/valid4", responses={"500": {"model": list[Model]}})
def valid4():
pass
+from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager
-from typing import AsyncGenerator, Dict, Union
+from typing import Union
import pytest
from fastapi import APIRouter, FastAPI, Request
app = FastAPI()
@app.get("/")
- def main() -> Dict[str, str]:
+ def main() -> dict[str, str]:
return {"message": "Hello World"}
@app.on_event("startup")
app = FastAPI(lifespan=lifespan)
@app.get("/")
- def main() -> Dict[str, str]:
+ def main() -> dict[str, str]:
return {"message": "Hello World"}
assert state.app_startup is False
def test_router_nested_lifespan_state(state: State) -> None:
@asynccontextmanager
- async def lifespan(app: FastAPI) -> AsyncGenerator[Dict[str, bool], None]:
+ async def lifespan(app: FastAPI) -> AsyncGenerator[dict[str, bool], None]:
state.app_startup = True
yield {"app": True}
state.app_shutdown = True
@asynccontextmanager
- async def router_lifespan(app: FastAPI) -> AsyncGenerator[Dict[str, bool], None]:
+ async def router_lifespan(app: FastAPI) -> AsyncGenerator[dict[str, bool], None]:
state.router_startup = True
yield {"router": True}
state.router_shutdown = True
@asynccontextmanager
- async def subrouter_lifespan(app: FastAPI) -> AsyncGenerator[Dict[str, bool], None]:
+ async def subrouter_lifespan(app: FastAPI) -> AsyncGenerator[dict[str, bool], None]:
state.sub_router_startup = True
yield {"sub_router": True}
state.sub_router_shutdown = True
app.include_router(router)
@app.get("/")
- def main(request: Request) -> Dict[str, str]:
+ def main(request: Request) -> dict[str, str]:
assert request.state.app
assert request.state.router
assert request.state.sub_router
@asynccontextmanager
async def lifespan(
app: FastAPI,
- ) -> AsyncGenerator[Dict[str, Union[str, bool]], None]:
+ ) -> AsyncGenerator[dict[str, Union[str, bool]], None]:
yield {
"app_specific": True,
"overridden": "app",
@asynccontextmanager
async def router_lifespan(
app: FastAPI,
- ) -> AsyncGenerator[Dict[str, Union[str, bool]], None]:
+ ) -> AsyncGenerator[dict[str, Union[str, bool]], None]:
yield {
"router_specific": True,
"overridden": "router", # should override parent
yield
@asynccontextmanager
- async def router_lifespan(app: FastAPI) -> AsyncGenerator[Dict[str, bool], None]:
+ async def router_lifespan(app: FastAPI) -> AsyncGenerator[dict[str, bool], None]:
yield {"router": True}
@asynccontextmanager
# Ref: https://github.com/fastapi/fastapi/issues/14454
-from typing import Optional
+from typing import Annotated, Optional
from fastapi import APIRouter, Depends, FastAPI, Security
from fastapi.security import OAuth2AuthorizationCodeBearer
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
-from typing_extensions import Annotated
oauth2_scheme = OAuth2AuthorizationCodeBearer(
authorizationUrl="authorize",
# Ref: https://github.com/fastapi/fastapi/issues/14454
+from typing import Annotated
+
from fastapi import Depends, FastAPI, Security
from fastapi.security import OAuth2AuthorizationCodeBearer
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
-from typing_extensions import Annotated
oauth2_scheme = OAuth2AuthorizationCodeBearer(
authorizationUrl="api/oauth/authorize",
-from typing import Dict
+from typing import Annotated
import pytest
from fastapi import Depends, FastAPI, Security
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
@pytest.fixture(name="call_counter")
@pytest.fixture(name="app")
-def app_fixture(call_counter: Dict[str, int]):
+def app_fixture(call_counter: dict[str, int]):
def get_db():
call_counter["count"] += 1
return f"db_{call_counter['count']}"
def test_security_scopes_dependency_called_once(
- client: TestClient, call_counter: Dict[str, int]
+ client: TestClient, call_counter: dict[str, int]
):
response = client.get("/")
# Ref: https://github.com/tiangolo/fastapi/issues/5623
-from typing import Any, Dict, List
+from typing import Annotated, Any
from fastapi import FastAPI, Security
from fastapi.security import SecurityScopes
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
async def security1(scopes: SecurityScopes):
async def dep3(
- dep1: Annotated[List[str], Security(security1, scopes=["scope1"])],
- dep2: Annotated[List[str], Security(security2, scopes=["scope2"])],
+ dep1: Annotated[list[str], Security(security1, scopes=["scope1"])],
+ dep2: Annotated[list[str], Security(security2, scopes=["scope2"])],
):
return {"dep1": dep1, "dep2": dep2}
@app.get("/scopes")
def get_scopes(
- dep3: Annotated[Dict[str, Any], Security(dep3, scopes=["scope3"])],
+ dep3: Annotated[dict[str, Any], Security(dep3, scopes=["scope3"])],
):
return dep3
# Ref: https://github.com/fastapi/fastapi/discussions/6024#discussioncomment-8541913
-from typing import Dict
+
+from typing import Annotated
import pytest
from fastapi import Depends, FastAPI, Security
from fastapi.security import SecurityScopes
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
@pytest.fixture(name="call_counts")
@pytest.fixture(name="app")
-def app_fixture(call_counts: Dict[str, int]):
+def app_fixture(call_counts: dict[str, int]):
def get_db_session():
call_counts["get_db_session"] += 1
return f"db_session_{call_counts['get_db_session']}"
def test_security_scopes_sub_dependency_caching(
- client: TestClient, call_counts: Dict[str, int]
+ client: TestClient, call_counts: dict[str, int]
):
response = client.get("/")
-from typing import List, Optional
+from typing import Optional
from fastapi import FastAPI
from fastapi.testclient import TestClient
class Item(BaseModel):
name: str
price: Optional[float] = None
- owner_ids: Optional[List[int]] = None
+ owner_ids: Optional[list[int]] = None
@app.get("/items/valid", response_model=Item)
return {"name": "coerce", "price": "1.0"}
-@app.get("/items/validlist", response_model=List[Item])
+@app.get("/items/validlist", response_model=list[Item])
def get_validlist():
return [
{"name": "foo"},
from dataclasses import dataclass
from datetime import datetime
-from typing import List, Optional
+from typing import Optional
from fastapi import FastAPI
from fastapi.testclient import TestClient
name: str
date: datetime
price: Optional[float] = None
- owner_ids: Optional[List[int]] = None
+ owner_ids: Optional[list[int]] = None
@app.get("/items/valid", response_model=Item)
return {"name": "coerce", "date": datetime(2021, 7, 26).isoformat(), "price": "1.0"}
-@app.get("/items/validlist", response_model=List[Item])
+@app.get("/items/validlist", response_model=list[Item])
def get_validlist():
return [
{"name": "foo", "date": datetime(2021, 7, 26)},
]
-@app.get("/items/objectlist", response_model=List[Item])
+@app.get("/items/objectlist", response_model=list[Item])
def get_objectlist():
return [
Item(name="foo", date=datetime(2021, 7, 26)),
-from typing import Dict, List, Optional
+from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(alias="aliased_name")
price: Optional[float] = None
- owner_ids: Optional[List[int]] = None
+ owner_ids: Optional[list[int]] = None
@app.get("/items/valid", response_model=Item)
return Item(aliased_name="coerce", price="1.0")
-@app.get("/items/validlist", response_model=List[Item])
+@app.get("/items/validlist", response_model=list[Item])
def get_validlist():
return [
Item(aliased_name="foo"),
]
-@app.get("/items/validdict", response_model=Dict[str, Item])
+@app.get("/items/validdict", response_model=dict[str, Item])
def get_validdict():
return {
"k1": Item(aliased_name="foo"),
@app.get(
"/items/validlist-exclude-unset",
- response_model=List[Item],
+ response_model=list[Item],
response_model_exclude_unset=True,
)
def get_validlist_exclude_unset():
@app.get(
"/items/validdict-exclude-unset",
- response_model=Dict[str, Item],
+ response_model=dict[str, Item],
response_model_exclude_unset=True,
)
def get_validdict_exclude_unset():
from __future__ import annotations
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Annotated
import pytest
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
-from typing_extensions import Annotated
if TYPE_CHECKING: # pragma: no cover
from collections.abc import AsyncGenerator
from __future__ import annotations
+from typing import Annotated
+
from fastapi import Depends, FastAPI, Request
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
from .utils import needs_py310
-from typing import List, Tuple
-
from dirty_equals import IsDict
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
class ItemGroup(BaseModel):
- items: List[Tuple[str, str]]
+ items: list[tuple[str, str]]
class Coordinate(BaseModel):
@app.post("/tuple-of-models/")
-def post_tuple_of_models(square: Tuple[Coordinate, Coordinate]):
+def post_tuple_of_models(square: tuple[Coordinate, Coordinate]):
return square
@app.post("/tuple-form/")
-def hello(values: Tuple[int, int] = Form()):
+def hello(values: tuple[int, int] = Form()):
return values
def test_websocket_handle_disconnection(client: TestClient):
- with client.websocket_connect("/ws/1234") as connection, client.websocket_connect(
- "/ws/5678"
- ) as connection_two:
+ with (
+ client.websocket_connect("/ws/1234") as connection,
+ client.websocket_connect("/ws/5678") as connection_two,
+ ):
connection.send_text("Hello from 1234")
data1 = connection.receive_text()
assert data1 == "You wrote: Hello from 1234"
-from typing import Any, Dict, Union
+from typing import Annotated, Any, Union
from dirty_equals import IsDict
from fastapi import FastAPI
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
+from typing_extensions import Literal
from .utils import needs_pydanticv2
@app.post("/items/")
def save_union_body_discriminator(
item: Item, q: Annotated[str, Field(description="Query string")]
- ) -> Dict[str, Any]:
+ ) -> dict[str, Any]:
return {"item": item}
client = TestClient(app)
# Ref: https://github.com/fastapi/fastapi/discussions/14495
-from typing import Union
+from typing import Annotated, Union
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from inline_snapshot import snapshot
from pydantic import BaseModel
-from typing_extensions import Annotated
from .utils import needs_pydanticv2
-from typing import Union
+from typing import Annotated, Union
from fastapi import FastAPI, Form
from fastapi.testclient import TestClient
from pydantic import BaseModel
-from typing_extensions import Annotated
app = FastAPI()
-from typing import List, Optional, Union
+from typing import Optional, Union
import pytest
from fastapi import FastAPI
class Item(BaseModel):
name: str
price: Optional[float] = None
- owner_ids: Optional[List[int]] = None
+ owner_ids: Optional[list[int]] = None
@app.get("/items/invalid", response_model=Item)
return {"name": "double invalid", "price": "foo", "owner_ids": ["foo", "bar"]}
-@app.get("/items/invalidlist", response_model=List[Item])
+@app.get("/items/invalidlist", response_model=list[Item])
def get_invalidlist():
return [
{"name": "foo"},
-from typing import List, Optional
+from typing import Optional
import pytest
from fastapi import FastAPI
class Item:
name: str
price: Optional[float] = None
- owner_ids: Optional[List[int]] = None
+ owner_ids: Optional[list[int]] = None
@app.get("/items/invalid", response_model=Item)
return {"name": "double invalid", "price": "foo", "owner_ids": ["foo", "bar"]}
-@app.get("/items/invalidlist", response_model=List[Item])
+@app.get("/items/invalidlist", response_model=list[Item])
def get_invalidlist():
return [
{"name": "foo"},
-from typing import List
-
from fastapi import FastAPI
from fastapi._compat import PYDANTIC_V2
from pydantic import BaseModel
class RecursiveItem(BaseModel):
- sub_items: List["RecursiveItem"] = []
+ sub_items: list["RecursiveItem"] = []
name: str
class RecursiveSubitemInSubmodel(BaseModel):
- sub_items2: List["RecursiveItemViaSubmodel"] = []
+ sub_items2: list["RecursiveItemViaSubmodel"] = []
name: str
class RecursiveItemViaSubmodel(BaseModel):
- sub_items1: List[RecursiveSubitemInSubmodel] = []
+ sub_items1: list[RecursiveSubitemInSubmodel] = []
name: str
from datetime import datetime
+from typing import Annotated
from fastapi import FastAPI, Security
from fastapi.security import HTTPBearer
from fastapi.testclient import TestClient
from pydantic import BaseModel
-from typing_extensions import Annotated
app = FastAPI()
import json
-from typing import List
+from typing import Annotated
from fastapi import APIRouter, Depends, FastAPI, WebSocket
from fastapi.testclient import TestClient
-from typing_extensions import Annotated
-def dependency_list() -> List[str]:
+def dependency_list() -> list[str]:
return []
-DepList = Annotated[List[str], Depends(dependency_list)]
+DepList = Annotated[list[str], Depends(dependency_list)]
def create_dependency(name: str):