about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/fastapi
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/fastapi')
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/__init__.py25
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/__main__.py3
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/_compat.py659
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/applications.py4585
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/background.py59
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/cli.py13
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/concurrency.py39
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/datastructures.py204
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/dependencies/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/dependencies/models.py37
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py980
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/encoders.py343
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/exception_handlers.py34
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/exceptions.py176
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/logger.py3
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/__init__.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/cors.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/gzip.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py3
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/trustedhost.py3
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/middleware/wsgi.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/openapi/__init__.py0
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/openapi/constants.py3
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/openapi/docs.py344
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/openapi/models.py445
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/openapi/utils.py569
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/param_functions.py2360
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/params.py786
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/py.typed0
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/requests.py2
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/responses.py48
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/routing.py4439
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/__init__.py15
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/api_key.py288
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/base.py6
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/http.py423
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/oauth2.py638
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/open_id_connect_url.py84
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/security/utils.py10
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/staticfiles.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/templating.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/testclient.py1
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/types.py10
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/utils.py220
-rw-r--r--.venv/lib/python3.12/site-packages/fastapi/websockets.py3
45 files changed, 17866 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/fastapi/__init__.py b/.venv/lib/python3.12/site-packages/fastapi/__init__.py
new file mode 100644
index 00000000..80eb783d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/__init__.py
@@ -0,0 +1,25 @@
+"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
+
+__version__ = "0.115.12"
+
+from starlette import status as status
+
+from .applications import FastAPI as FastAPI
+from .background import BackgroundTasks as BackgroundTasks
+from .datastructures import UploadFile as UploadFile
+from .exceptions import HTTPException as HTTPException
+from .exceptions import WebSocketException as WebSocketException
+from .param_functions import Body as Body
+from .param_functions import Cookie as Cookie
+from .param_functions import Depends as Depends
+from .param_functions import File as File
+from .param_functions import Form as Form
+from .param_functions import Header as Header
+from .param_functions import Path as Path
+from .param_functions import Query as Query
+from .param_functions import Security as Security
+from .requests import Request as Request
+from .responses import Response as Response
+from .routing import APIRouter as APIRouter
+from .websockets import WebSocket as WebSocket
+from .websockets import WebSocketDisconnect as WebSocketDisconnect
diff --git a/.venv/lib/python3.12/site-packages/fastapi/__main__.py b/.venv/lib/python3.12/site-packages/fastapi/__main__.py
new file mode 100644
index 00000000..fc36465f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/__main__.py
@@ -0,0 +1,3 @@
+from fastapi.cli import main
+
+main()
diff --git a/.venv/lib/python3.12/site-packages/fastapi/_compat.py b/.venv/lib/python3.12/site-packages/fastapi/_compat.py
new file mode 100644
index 00000000..c07e4a3b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/_compat.py
@@ -0,0 +1,659 @@
+from collections import deque
+from copy import copy
+from dataclasses import dataclass, is_dataclass
+from enum import Enum
+from functools import lru_cache
+from typing import (
+    Any,
+    Callable,
+    Deque,
+    Dict,
+    FrozenSet,
+    List,
+    Mapping,
+    Sequence,
+    Set,
+    Tuple,
+    Type,
+    Union,
+)
+
+from fastapi.exceptions import RequestErrorModel
+from fastapi.types import IncEx, ModelNameMap, UnionType
+from pydantic import BaseModel, create_model
+from pydantic.version import VERSION as PYDANTIC_VERSION
+from starlette.datastructures import UploadFile
+from typing_extensions import Annotated, Literal, get_args, get_origin
+
+PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2])
+PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
+
+
+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]
+
+if PYDANTIC_V2:
+    from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
+    from pydantic import TypeAdapter
+    from pydantic import ValidationError as ValidationError
+    from pydantic._internal._schema_generation_shared import (  # type: ignore[attr-defined]
+        GetJsonSchemaHandler as GetJsonSchemaHandler,
+    )
+    from pydantic._internal._typing_extra import eval_type_lenient
+    from pydantic._internal._utils import lenient_issubclass as lenient_issubclass
+    from pydantic.fields import FieldInfo
+    from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema
+    from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
+    from pydantic_core import CoreSchema as CoreSchema
+    from pydantic_core import PydanticUndefined, PydanticUndefinedType
+    from pydantic_core import Url as Url
+
+    try:
+        from pydantic_core.core_schema import (
+            with_info_plain_validator_function as with_info_plain_validator_function,
+        )
+    except ImportError:  # pragma: no cover
+        from pydantic_core.core_schema import (
+            general_plain_validator_function as with_info_plain_validator_function,  # noqa: F401
+        )
+
+    RequiredParam = PydanticUndefined
+    Undefined = PydanticUndefined
+    UndefinedType = PydanticUndefinedType
+    evaluate_forwardref = eval_type_lenient
+    Validator = Any
+
+    class BaseConfig:
+        pass
+
+    class ErrorWrapper(Exception):
+        pass
+
+    @dataclass
+    class ModelField:
+        field_info: FieldInfo
+        name: str
+        mode: Literal["validation", "serialization"] = "validation"
+
+        @property
+        def alias(self) -> str:
+            a = self.field_info.alias
+            return a if a is not None else self.name
+
+        @property
+        def required(self) -> bool:
+            return self.field_info.is_required()
+
+        @property
+        def default(self) -> Any:
+            return self.get_default()
+
+        @property
+        def type_(self) -> Any:
+            return self.field_info.annotation
+
+        def __post_init__(self) -> None:
+            self._type_adapter: TypeAdapter[Any] = TypeAdapter(
+                Annotated[self.field_info.annotation, self.field_info]
+            )
+
+        def get_default(self) -> Any:
+            if self.field_info.is_required():
+                return Undefined
+            return self.field_info.get_default(call_default_factory=True)
+
+        def validate(
+            self,
+            value: Any,
+            values: Dict[str, Any] = {},  # noqa: B006
+            *,
+            loc: Tuple[Union[int, str], ...] = (),
+        ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:
+            try:
+                return (
+                    self._type_adapter.validate_python(value, from_attributes=True),
+                    None,
+                )
+            except ValidationError as exc:
+                return None, _regenerate_error_with_loc(
+                    errors=exc.errors(include_url=False), loc_prefix=loc
+                )
+
+        def serialize(
+            self,
+            value: Any,
+            *,
+            mode: Literal["json", "python"] = "json",
+            include: Union[IncEx, None] = None,
+            exclude: Union[IncEx, None] = None,
+            by_alias: bool = True,
+            exclude_unset: bool = False,
+            exclude_defaults: bool = False,
+            exclude_none: bool = False,
+        ) -> Any:
+            # What calls this code passes a value that already called
+            # self._type_adapter.validate_python(value)
+            return self._type_adapter.dump_python(
+                value,
+                mode=mode,
+                include=include,
+                exclude=exclude,
+                by_alias=by_alias,
+                exclude_unset=exclude_unset,
+                exclude_defaults=exclude_defaults,
+                exclude_none=exclude_none,
+            )
+
+        def __hash__(self) -> int:
+            # Each ModelField is unique for our purposes, to allow making a dict from
+            # ModelField to its JSON Schema.
+            return id(self)
+
+    def get_annotation_from_field_info(
+        annotation: Any, field_info: FieldInfo, field_name: str
+    ) -> Any:
+        return annotation
+
+    def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
+        return errors  # type: ignore[return-value]
+
+    def _model_rebuild(model: Type[BaseModel]) -> None:
+        model.model_rebuild()
+
+    def _model_dump(
+        model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
+    ) -> Any:
+        return model.model_dump(mode=mode, **kwargs)
+
+    def _get_model_config(model: BaseModel) -> Any:
+        return model.model_config
+
+    def get_schema_from_model_field(
+        *,
+        field: ModelField,
+        schema_generator: GenerateJsonSchema,
+        model_name_map: ModelNameMap,
+        field_mapping: Dict[
+            Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+        ],
+        separate_input_output_schemas: bool = True,
+    ) -> Dict[str, Any]:
+        override_mode: Union[Literal["validation"], None] = (
+            None if separate_input_output_schemas else "validation"
+        )
+        # This expects that GenerateJsonSchema was already used to generate the definitions
+        json_schema = field_mapping[(field, override_mode or field.mode)]
+        if "$ref" not in json_schema:
+            # TODO remove when deprecating Pydantic v1
+            # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207
+            json_schema["title"] = (
+                field.field_info.title or field.alias.title().replace("_", " ")
+            )
+        return json_schema
+
+    def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
+        return {}
+
+    def get_definitions(
+        *,
+        fields: List[ModelField],
+        schema_generator: GenerateJsonSchema,
+        model_name_map: ModelNameMap,
+        separate_input_output_schemas: bool = True,
+    ) -> Tuple[
+        Dict[
+            Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+        ],
+        Dict[str, Dict[str, Any]],
+    ]:
+        override_mode: Union[Literal["validation"], None] = (
+            None if separate_input_output_schemas else "validation"
+        )
+        inputs = [
+            (field, override_mode or field.mode, field._type_adapter.core_schema)
+            for field in fields
+        ]
+        field_mapping, definitions = schema_generator.generate_definitions(
+            inputs=inputs
+        )
+        return field_mapping, definitions  # type: ignore[return-value]
+
+    def is_scalar_field(field: ModelField) -> bool:
+        from fastapi import params
+
+        return field_annotation_is_scalar(
+            field.field_info.annotation
+        ) and not isinstance(field.field_info, params.Body)
+
+    def is_sequence_field(field: ModelField) -> bool:
+        return field_annotation_is_sequence(field.field_info.annotation)
+
+    def is_scalar_sequence_field(field: ModelField) -> bool:
+        return field_annotation_is_scalar_sequence(field.field_info.annotation)
+
+    def is_bytes_field(field: ModelField) -> bool:
+        return is_bytes_or_nonable_bytes_annotation(field.type_)
+
+    def is_bytes_sequence_field(field: ModelField) -> bool:
+        return is_bytes_sequence_annotation(field.type_)
+
+    def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
+        cls = type(field_info)
+        merged_field_info = cls.from_annotation(annotation)
+        new_field_info = copy(field_info)
+        new_field_info.metadata = merged_field_info.metadata
+        new_field_info.annotation = merged_field_info.annotation
+        return new_field_info
+
+    def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
+        origin_type = (
+            get_origin(field.field_info.annotation) or field.field_info.annotation
+        )
+        assert issubclass(origin_type, sequence_types)  # type: ignore[arg-type]
+        return sequence_annotation_to_type[origin_type](value)  # type: ignore[no-any-return]
+
+    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]
+        error["input"] = None
+        return error  # type: ignore[return-value]
+
+    def create_body_model(
+        *, fields: Sequence[ModelField], model_name: str
+    ) -> 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]
+        return BodyModel
+
+    def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+        return [
+            ModelField(field_info=field_info, name=name)
+            for name, field_info in model.model_fields.items()
+        ]
+
+else:
+    from fastapi.openapi.constants import REF_PREFIX as REF_PREFIX
+    from pydantic import AnyUrl as Url  # noqa: F401
+    from pydantic import (  # type: ignore[assignment]
+        BaseConfig as BaseConfig,  # noqa: F401
+    )
+    from pydantic import ValidationError as ValidationError  # noqa: F401
+    from pydantic.class_validators import (  # type: ignore[no-redef]
+        Validator as Validator,  # noqa: F401
+    )
+    from pydantic.error_wrappers import (  # type: ignore[no-redef]
+        ErrorWrapper as ErrorWrapper,  # noqa: F401
+    )
+    from pydantic.errors import MissingError
+    from pydantic.fields import (  # type: ignore[attr-defined]
+        SHAPE_FROZENSET,
+        SHAPE_LIST,
+        SHAPE_SEQUENCE,
+        SHAPE_SET,
+        SHAPE_SINGLETON,
+        SHAPE_TUPLE,
+        SHAPE_TUPLE_ELLIPSIS,
+    )
+    from pydantic.fields import FieldInfo as FieldInfo
+    from pydantic.fields import (  # type: ignore[no-redef,attr-defined]
+        ModelField as ModelField,  # noqa: F401
+    )
+
+    # Keeping old "Required" functionality from Pydantic V1, without
+    # shadowing typing.Required.
+    RequiredParam: Any = Ellipsis  # type: ignore[no-redef]
+    from pydantic.fields import (  # type: ignore[no-redef,attr-defined]
+        Undefined as Undefined,
+    )
+    from pydantic.fields import (  # type: ignore[no-redef, attr-defined]
+        UndefinedType as UndefinedType,  # noqa: F401
+    )
+    from pydantic.schema import (
+        field_schema,
+        get_flat_models_from_fields,
+        get_model_name_map,
+        model_process_schema,
+    )
+    from pydantic.schema import (  # type: ignore[no-redef]  # noqa: F401
+        get_annotation_from_field_info as get_annotation_from_field_info,
+    )
+    from pydantic.typing import (  # type: ignore[no-redef]
+        evaluate_forwardref as evaluate_forwardref,  # noqa: F401
+    )
+    from pydantic.utils import (  # type: ignore[no-redef]
+        lenient_issubclass as lenient_issubclass,  # noqa: F401
+    )
+
+    GetJsonSchemaHandler = Any  # type: ignore[assignment,misc]
+    JsonSchemaValue = Dict[str, Any]  # type: ignore[misc]
+    CoreSchema = Any  # type: ignore[assignment,misc]
+
+    sequence_shapes = {
+        SHAPE_LIST,
+        SHAPE_SET,
+        SHAPE_FROZENSET,
+        SHAPE_TUPLE,
+        SHAPE_SEQUENCE,
+        SHAPE_TUPLE_ELLIPSIS,
+    }
+    sequence_shape_to_type = {
+        SHAPE_LIST: list,
+        SHAPE_SET: set,
+        SHAPE_TUPLE: tuple,
+        SHAPE_SEQUENCE: list,
+        SHAPE_TUPLE_ELLIPSIS: list,
+    }
+
+    @dataclass
+    class GenerateJsonSchema:  # type: ignore[no-redef]
+        ref_template: str
+
+    class PydanticSchemaGenerationError(Exception):  # type: ignore[no-redef]
+        pass
+
+    def with_info_plain_validator_function(  # type: ignore[misc]
+        function: Callable[..., Any],
+        *,
+        ref: Union[str, None] = None,
+        metadata: Any = None,
+        serialization: Any = None,
+    ) -> Any:
+        return {}
+
+    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]] = {}
+        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
+            )
+            definitions.update(m_definitions)
+            model_name = model_name_map[model]
+            if "description" in m_schema:
+                m_schema["description"] = m_schema["description"].split("\f")[0]
+            definitions[model_name] = m_schema
+        return definitions
+
+    def is_pv1_scalar_field(field: ModelField) -> bool:
+        from fastapi import params
+
+        field_info = field.field_info
+        if not (
+            field.shape == SHAPE_SINGLETON  # type: ignore[attr-defined]
+            and not lenient_issubclass(field.type_, BaseModel)
+            and not lenient_issubclass(field.type_, dict)
+            and not field_annotation_is_sequence(field.type_)
+            and not is_dataclass(field.type_)
+            and not isinstance(field_info, params.Body)
+        ):
+            return False
+        if field.sub_fields:  # type: ignore[attr-defined]
+            if not all(
+                is_pv1_scalar_field(f)
+                for f in field.sub_fields  # type: ignore[attr-defined]
+            ):
+                return False
+        return True
+
+    def is_pv1_scalar_sequence_field(field: ModelField) -> bool:
+        if (field.shape in sequence_shapes) and not lenient_issubclass(  # type: ignore[attr-defined]
+            field.type_, BaseModel
+        ):
+            if field.sub_fields is not None:  # type: ignore[attr-defined]
+                for sub_field in field.sub_fields:  # type: ignore[attr-defined]
+                    if not is_pv1_scalar_field(sub_field):
+                        return False
+            return True
+        if _annotation_is_sequence(field.type_):
+            return True
+        return False
+
+    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]
+                    errors=[error], model=RequestErrorModel
+                ).errors()
+                use_errors.extend(new_errors)
+            elif isinstance(error, list):
+                use_errors.extend(_normalize_errors(error))
+            else:
+                use_errors.append(error)
+        return use_errors
+
+    def _model_rebuild(model: Type[BaseModel]) -> None:
+        model.update_forward_refs()
+
+    def _model_dump(
+        model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
+    ) -> Any:
+        return model.dict(**kwargs)
+
+    def _get_model_config(model: BaseModel) -> Any:
+        return model.__config__  # type: ignore[attr-defined]
+
+    def get_schema_from_model_field(
+        *,
+        field: ModelField,
+        schema_generator: GenerateJsonSchema,
+        model_name_map: ModelNameMap,
+        field_mapping: Dict[
+            Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+        ],
+        separate_input_output_schemas: bool = True,
+    ) -> Dict[str, Any]:
+        # This expects that GenerateJsonSchema was already used to generate the definitions
+        return field_schema(  # type: ignore[no-any-return]
+            field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
+        )[0]
+
+    def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
+        models = get_flat_models_from_fields(fields, known_models=set())
+        return get_model_name_map(models)  # type: ignore[no-any-return]
+
+    def get_definitions(
+        *,
+        fields: List[ModelField],
+        schema_generator: GenerateJsonSchema,
+        model_name_map: ModelNameMap,
+        separate_input_output_schemas: bool = True,
+    ) -> 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
+        )
+
+    def is_scalar_field(field: ModelField) -> bool:
+        return is_pv1_scalar_field(field)
+
+    def is_sequence_field(field: ModelField) -> bool:
+        return field.shape in sequence_shapes or _annotation_is_sequence(field.type_)  # type: ignore[attr-defined]
+
+    def is_scalar_sequence_field(field: ModelField) -> bool:
+        return is_pv1_scalar_sequence_field(field)
+
+    def is_bytes_field(field: ModelField) -> bool:
+        return lenient_issubclass(field.type_, bytes)
+
+    def is_bytes_sequence_field(field: ModelField) -> bool:
+        return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes)  # type: ignore[attr-defined]
+
+    def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
+        return copy(field_info)
+
+    def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
+        return sequence_shape_to_type[field.shape](value)  # type: ignore[no-any-return,attr-defined]
+
+    def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
+        missing_field_error = ErrorWrapper(MissingError(), loc=loc)  # type: ignore[call-arg]
+        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]:
+        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]:
+        return list(model.__fields__.values())  # type: ignore[attr-defined]
+
+
+def _regenerate_error_with_loc(
+    *, 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)
+    ]
+
+    return updated_loc_errors
+
+
+def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
+    if lenient_issubclass(annotation, (str, bytes)):
+        return False
+    return lenient_issubclass(annotation, sequence_types)
+
+
+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):
+            if field_annotation_is_sequence(arg):
+                return True
+        return False
+    return _annotation_is_sequence(annotation) or _annotation_is_sequence(
+        get_origin(annotation)
+    )
+
+
+def value_is_sequence(value: Any) -> bool:
+    return isinstance(value, sequence_types) and not isinstance(value, (str, bytes))  # type: ignore[arg-type]
+
+
+def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
+    return (
+        lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile))
+        or _annotation_is_sequence(annotation)
+        or is_dataclass(annotation)
+    )
+
+
+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_complex(annotation)
+        or _annotation_is_complex(origin)
+        or hasattr(origin, "__pydantic_core_schema__")
+        or hasattr(origin, "__get_pydantic_core_schema__")
+    )
+
+
+def field_annotation_is_scalar(annotation: Any) -> bool:
+    # handle Ellipsis here to make tuple[int, ...] work nicely
+    return annotation is Ellipsis or not field_annotation_is_complex(annotation)
+
+
+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
+        for arg in get_args(annotation):
+            if field_annotation_is_scalar_sequence(arg):
+                at_least_one_scalar_sequence = True
+                continue
+            elif not field_annotation_is_scalar(arg):
+                return False
+        return at_least_one_scalar_sequence
+    return field_annotation_is_sequence(annotation) and all(
+        field_annotation_is_scalar(sub_annotation)
+        for sub_annotation in get_args(annotation)
+    )
+
+
+def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool:
+    if lenient_issubclass(annotation, bytes):
+        return True
+    origin = get_origin(annotation)
+    if origin is Union or origin is UnionType:
+        for arg in get_args(annotation):
+            if lenient_issubclass(arg, bytes):
+                return True
+    return False
+
+
+def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool:
+    if lenient_issubclass(annotation, UploadFile):
+        return True
+    origin = get_origin(annotation)
+    if origin is Union or origin is UnionType:
+        for arg in get_args(annotation):
+            if lenient_issubclass(arg, UploadFile):
+                return True
+    return False
+
+
+def is_bytes_sequence_annotation(annotation: Any) -> bool:
+    origin = get_origin(annotation)
+    if origin is Union or origin is UnionType:
+        at_least_one = False
+        for arg in get_args(annotation):
+            if is_bytes_sequence_annotation(arg):
+                at_least_one = True
+                continue
+        return at_least_one
+    return field_annotation_is_sequence(annotation) and all(
+        is_bytes_or_nonable_bytes_annotation(sub_annotation)
+        for sub_annotation in get_args(annotation)
+    )
+
+
+def is_uploadfile_sequence_annotation(annotation: Any) -> bool:
+    origin = get_origin(annotation)
+    if origin is Union or origin is UnionType:
+        at_least_one = False
+        for arg in get_args(annotation):
+            if is_uploadfile_sequence_annotation(arg):
+                at_least_one = True
+                continue
+        return at_least_one
+    return field_annotation_is_sequence(annotation) and all(
+        is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation)
+        for sub_annotation in get_args(annotation)
+    )
+
+
+@lru_cache
+def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+    return get_model_fields(model)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/applications.py b/.venv/lib/python3.12/site-packages/fastapi/applications.py
new file mode 100644
index 00000000..6d427cdc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/applications.py
@@ -0,0 +1,4585 @@
+from enum import Enum
+from typing import (
+    Any,
+    Awaitable,
+    Callable,
+    Coroutine,
+    Dict,
+    List,
+    Optional,
+    Sequence,
+    Type,
+    TypeVar,
+    Union,
+)
+
+from fastapi import routing
+from fastapi.datastructures import Default, DefaultPlaceholder
+from fastapi.exception_handlers import (
+    http_exception_handler,
+    request_validation_exception_handler,
+    websocket_request_validation_exception_handler,
+)
+from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
+from fastapi.logger import logger
+from fastapi.openapi.docs import (
+    get_redoc_html,
+    get_swagger_ui_html,
+    get_swagger_ui_oauth2_redirect_html,
+)
+from fastapi.openapi.utils import get_openapi
+from fastapi.params import Depends
+from fastapi.types import DecoratedCallable, IncEx
+from fastapi.utils import generate_unique_id
+from starlette.applications import Starlette
+from starlette.datastructures import State
+from starlette.exceptions import HTTPException
+from starlette.middleware import Middleware
+from starlette.middleware.base import BaseHTTPMiddleware
+from starlette.requests import Request
+from starlette.responses import HTMLResponse, JSONResponse, Response
+from starlette.routing import BaseRoute
+from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
+from typing_extensions import Annotated, Doc, deprecated
+
+AppType = TypeVar("AppType", bound="FastAPI")
+
+
+class FastAPI(Starlette):
+    """
+    `FastAPI` app class, the main entrypoint to use FastAPI.
+
+    Read more in the
+    [FastAPI docs for First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/).
+
+    ## Example
+
+    ```python
+    from fastapi import FastAPI
+
+    app = FastAPI()
+    ```
+    """
+
+    def __init__(
+        self: AppType,
+        *,
+        debug: Annotated[
+            bool,
+            Doc(
+                """
+                Boolean indicating if debug tracebacks should be returned on server
+                errors.
+
+                Read more in the
+                [Starlette docs for Applications](https://www.starlette.io/applications/#instantiating-the-application).
+                """
+            ),
+        ] = False,
+        routes: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                **Note**: you probably shouldn't use this parameter, it is inherited
+                from Starlette and supported for compatibility.
+
+                ---
+
+                A list of routes to serve incoming HTTP and WebSocket requests.
+                """
+            ),
+            deprecated(
+                """
+                You normally wouldn't use this parameter with FastAPI, it is inherited
+                from Starlette and supported for compatibility.
+
+                In FastAPI, you normally would use the *path operation methods*,
+                like `app.get()`, `app.post()`, etc.
+                """
+            ),
+        ] = None,
+        title: Annotated[
+            str,
+            Doc(
+                """
+                The title of the API.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(title="ChimichangApp")
+                ```
+                """
+            ),
+        ] = "FastAPI",
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A short summary of the API.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(summary="Deadpond's favorite app. Nuff said.")
+                ```
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            str,
+            Doc(
+                '''
+                A description of the API. Supports Markdown (using
+                [CommonMark syntax](https://commonmark.org/)).
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(
+                    description="""
+                                ChimichangApp API helps you do awesome stuff. 🚀
+
+                                ## Items
+
+                                You can **read items**.
+
+                                ## Users
+
+                                You will be able to:
+
+                                * **Create users** (_not implemented_).
+                                * **Read users** (_not implemented_).
+
+                                """
+                )
+                ```
+                '''
+            ),
+        ] = "",
+        version: Annotated[
+            str,
+            Doc(
+                """
+                The version of the API.
+
+                **Note** This is the version of your application, not the version of
+                the OpenAPI specification nor the version of FastAPI being used.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(version="0.0.1")
+                ```
+                """
+            ),
+        ] = "0.1.0",
+        openapi_url: Annotated[
+            Optional[str],
+            Doc(
+                """
+                The URL where the OpenAPI schema will be served from.
+
+                If you set it to `None`, no OpenAPI schema will be served publicly, and
+                the default automatic endpoints `/docs` and `/redoc` will also be
+                disabled.
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#openapi-url).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(openapi_url="/api/v1/openapi.json")
+                ```
+                """
+            ),
+        ] = "/openapi.json",
+        openapi_tags: Annotated[
+            Optional[List[Dict[str, Any]]],
+            Doc(
+                """
+                A list of tags used by OpenAPI, these are the same `tags` you can set
+                in the *path operations*, like:
+
+                * `@app.get("/users/", tags=["users"])`
+                * `@app.get("/items/", tags=["items"])`
+
+                The order of the tags can be used to specify the order shown in
+                tools like Swagger UI, used in the automatic path `/docs`.
+
+                It's not required to specify all the tags used.
+
+                The tags that are not declared MAY be organized randomly or based
+                on the tools' logic. Each tag name in the list MUST be unique.
+
+                The value of each item is a `dict` containing:
+
+                * `name`: The name of the tag.
+                * `description`: A short description of the tag.
+                    [CommonMark syntax](https://commonmark.org/) MAY be used for rich
+                    text representation.
+                * `externalDocs`: Additional external documentation for this tag. If
+                    provided, it would contain a `dict` with:
+                    * `description`: A short description of the target documentation.
+                        [CommonMark syntax](https://commonmark.org/) MAY be used for
+                        rich text representation.
+                    * `url`: The URL for the target documentation. Value MUST be in
+                        the form of a URL.
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                tags_metadata = [
+                    {
+                        "name": "users",
+                        "description": "Operations with users. The **login** logic is also here.",
+                    },
+                    {
+                        "name": "items",
+                        "description": "Manage items. So _fancy_ they have their own docs.",
+                        "externalDocs": {
+                            "description": "Items external docs",
+                            "url": "https://fastapi.tiangolo.com/",
+                        },
+                    },
+                ]
+
+                app = FastAPI(openapi_tags=tags_metadata)
+                ```
+                """
+            ),
+        ] = None,
+        servers: Annotated[
+            Optional[List[Dict[str, Union[str, Any]]]],
+            Doc(
+                """
+                A `list` of `dict`s with connectivity information to a target server.
+
+                You would use it, for example, if your application is served from
+                different domains and you want to use the same Swagger UI in the
+                browser to interact with each of them (instead of having multiple
+                browser tabs open). Or if you want to leave fixed the possible URLs.
+
+                If the servers `list` is not provided, or is an empty `list`, the
+                default value would be a `dict` with a `url` value of `/`.
+
+                Each item in the `list` is a `dict` containing:
+
+                * `url`: A URL to the target host. This URL supports Server Variables
+                and MAY be relative, to indicate that the host location is relative
+                to the location where the OpenAPI document is being served. Variable
+                substitutions will be made when a variable is named in `{`brackets`}`.
+                * `description`: An optional string describing the host designated by
+                the URL. [CommonMark syntax](https://commonmark.org/) MAY be used for
+                rich text representation.
+                * `variables`: A `dict` between a variable name and its value. The value
+                    is used for substitution in the server's URL template.
+
+                Read more in the
+                [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(
+                    servers=[
+                        {"url": "https://stag.example.com", "description": "Staging environment"},
+                        {"url": "https://prod.example.com", "description": "Production environment"},
+                    ]
+                )
+                ```
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of global dependencies, they will be applied to each
+                *path operation*, including in sub-routers.
+
+                Read more about it in the
+                [FastAPI docs for Global Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/).
+
+                **Example**
+
+                ```python
+                from fastapi import Depends, FastAPI
+
+                from .dependencies import func_dep_1, func_dep_2
+
+                app = FastAPI(dependencies=[Depends(func_dep_1), Depends(func_dep_2)])
+                ```
+                """
+            ),
+        ] = None,
+        default_response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                The default response class to be used.
+
+                Read more in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+                from fastapi.responses import ORJSONResponse
+
+                app = FastAPI(default_response_class=ORJSONResponse)
+                ```
+                """
+            ),
+        ] = Default(JSONResponse),
+        redirect_slashes: Annotated[
+            bool,
+            Doc(
+                """
+                Whether to detect and redirect slashes in URLs when the client doesn't
+                use the same format.
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(redirect_slashes=True)  # the default
+
+                @app.get("/items/")
+                async def read_items():
+                    return [{"item_id": "Foo"}]
+                ```
+
+                With this app, if a client goes to `/items` (without a trailing slash),
+                they will be automatically redirected with an HTTP status code of 307
+                to `/items/`.
+                """
+            ),
+        ] = True,
+        docs_url: Annotated[
+            Optional[str],
+            Doc(
+                """
+                The path to the automatic interactive API documentation.
+                It is handled in the browser by Swagger UI.
+
+                The default URL is `/docs`. You can disable it by setting it to `None`.
+
+                If `openapi_url` is set to `None`, this will be automatically disabled.
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(docs_url="/documentation", redoc_url=None)
+                ```
+                """
+            ),
+        ] = "/docs",
+        redoc_url: Annotated[
+            Optional[str],
+            Doc(
+                """
+                The path to the alternative automatic interactive API documentation
+                provided by ReDoc.
+
+                The default URL is `/redoc`. You can disable it by setting it to `None`.
+
+                If `openapi_url` is set to `None`, this will be automatically disabled.
+
+                Read more in the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(docs_url="/documentation", redoc_url="redocumentation")
+                ```
+                """
+            ),
+        ] = "/redoc",
+        swagger_ui_oauth2_redirect_url: Annotated[
+            Optional[str],
+            Doc(
+                """
+                The OAuth2 redirect endpoint for the Swagger UI.
+
+                By default it is `/docs/oauth2-redirect`.
+
+                This is only used if you use OAuth2 (with the "Authorize" button)
+                with Swagger UI.
+                """
+            ),
+        ] = "/docs/oauth2-redirect",
+        swagger_ui_init_oauth: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                OAuth2 configuration for the Swagger UI, by default shown at `/docs`.
+
+                Read more about the available configuration options in the
+                [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/).
+                """
+            ),
+        ] = None,
+        middleware: Annotated[
+            Optional[Sequence[Middleware]],
+            Doc(
+                """
+                List of middleware to be added when creating the application.
+
+                In FastAPI you would normally do this with `app.add_middleware()`
+                instead.
+
+                Read more in the
+                [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+                """
+            ),
+        ] = None,
+        exception_handlers: Annotated[
+            Optional[
+                Dict[
+                    Union[int, Type[Exception]],
+                    Callable[[Request, Any], Coroutine[Any, Any, Response]],
+                ]
+            ],
+            Doc(
+                """
+                A dictionary with handlers for exceptions.
+
+                In FastAPI, you would normally use the decorator
+                `@app.exception_handler()`.
+
+                Read more in the
+                [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+                """
+            ),
+        ] = None,
+        on_startup: Annotated[
+            Optional[Sequence[Callable[[], Any]]],
+            Doc(
+                """
+                A list of startup event handler functions.
+
+                You should instead use the `lifespan` handlers.
+
+                Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        on_shutdown: Annotated[
+            Optional[Sequence[Callable[[], Any]]],
+            Doc(
+                """
+                A list of shutdown event handler functions.
+
+                You should instead use the `lifespan` handlers.
+
+                Read more in the
+                [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        lifespan: Annotated[
+            Optional[Lifespan[AppType]],
+            Doc(
+                """
+                A `Lifespan` context manager handler. This replaces `startup` and
+                `shutdown` functions with a single context manager.
+
+                Read more in the
+                [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        terms_of_service: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A URL to the Terms of Service for your API.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more at the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                app = FastAPI(terms_of_service="http://example.com/terms/")
+                ```
+                """
+            ),
+        ] = None,
+        contact: Annotated[
+            Optional[Dict[str, Union[str, Any]]],
+            Doc(
+                """
+                A dictionary with the contact information for the exposed API.
+
+                It can contain several fields.
+
+                * `name`: (`str`) The name of the contact person/organization.
+                * `url`: (`str`) A URL pointing to the contact information. MUST be in
+                    the format of a URL.
+                * `email`: (`str`) The email address of the contact person/organization.
+                    MUST be in the format of an email address.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more at the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                app = FastAPI(
+                    contact={
+                        "name": "Deadpoolio the Amazing",
+                        "url": "http://x-force.example.com/contact/",
+                        "email": "dp@x-force.example.com",
+                    }
+                )
+                ```
+                """
+            ),
+        ] = None,
+        license_info: Annotated[
+            Optional[Dict[str, Union[str, Any]]],
+            Doc(
+                """
+                A dictionary with the license information for the exposed API.
+
+                It can contain several fields.
+
+                * `name`: (`str`) **REQUIRED** (if a `license_info` is set). The
+                    license name used for the API.
+                * `identifier`: (`str`) An [SPDX](https://spdx.dev/) license expression
+                    for the API. The `identifier` field is mutually exclusive of the `url`
+                    field. Available since OpenAPI 3.1.0, FastAPI 0.99.0.
+                * `url`: (`str`) A URL to the license used for the API. This MUST be
+                    the format of a URL.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more at the
+                [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+                **Example**
+
+                ```python
+                app = FastAPI(
+                    license_info={
+                        "name": "Apache 2.0",
+                        "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+                    }
+                )
+                ```
+                """
+            ),
+        ] = None,
+        openapi_prefix: Annotated[
+            str,
+            Doc(
+                """
+                A URL prefix for the OpenAPI URL.
+                """
+            ),
+            deprecated(
+                """
+                "openapi_prefix" has been deprecated in favor of "root_path", which
+                follows more closely the ASGI standard, is simpler, and more
+                automatic.
+                """
+            ),
+        ] = "",
+        root_path: Annotated[
+            str,
+            Doc(
+                """
+                A path prefix handled by a proxy that is not seen by the application
+                but is seen by external clients, which affects things like Swagger UI.
+
+                Read more about it at the
+                [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(root_path="/api/v1")
+                ```
+                """
+            ),
+        ] = "",
+        root_path_in_servers: Annotated[
+            bool,
+            Doc(
+                """
+                To disable automatically generating the URLs in the `servers` field
+                in the autogenerated OpenAPI using the `root_path`.
+
+                Read more about it in the
+                [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root_path).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI(root_path_in_servers=False)
+                ```
+                """
+            ),
+        ] = True,
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses to be shown in OpenAPI.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+                And in the
+                [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                OpenAPI callbacks that should apply to all *path operations*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        webhooks: Annotated[
+            Optional[routing.APIRouter],
+            Doc(
+                """
+                Add OpenAPI webhooks. This is similar to `callbacks` but it doesn't
+                depend on specific *path operations*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                **Note**: This is available since OpenAPI 3.1.0, FastAPI 0.99.0.
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark all *path operations* as deprecated. You probably don't need it,
+                but it's available.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                To include (or not) all the *path operations* in the generated OpenAPI.
+                You probably don't need it, but it's available.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        swagger_ui_parameters: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Parameters to configure Swagger UI, the autogenerated interactive API
+                documentation (by default at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+        separate_input_output_schemas: Annotated[
+            bool,
+            Doc(
+                """
+                Whether to generate separate OpenAPI schemas for request body and
+                response body when the results would be more precise.
+
+                This is particularly useful when automatically generating clients.
+
+                For example, if you have a model like:
+
+                ```python
+                from pydantic import BaseModel
+
+                class Item(BaseModel):
+                    name: str
+                    tags: list[str] = []
+                ```
+
+                When `Item` is used for input, a request body, `tags` is not required,
+                the client doesn't have to provide it.
+
+                But when using `Item` for output, for a response body, `tags` is always
+                available because it has a default value, even if it's just an empty
+                list. So, the client should be able to always expect it.
+
+                In this case, there would be two different schemas, one for input and
+                another one for output.
+                """
+            ),
+        ] = True,
+        **extra: Annotated[
+            Any,
+            Doc(
+                """
+                Extra keyword arguments to be stored in the app, not used by FastAPI
+                anywhere.
+                """
+            ),
+        ],
+    ) -> None:
+        self.debug = debug
+        self.title = title
+        self.summary = summary
+        self.description = description
+        self.version = version
+        self.terms_of_service = terms_of_service
+        self.contact = contact
+        self.license_info = license_info
+        self.openapi_url = openapi_url
+        self.openapi_tags = openapi_tags
+        self.root_path_in_servers = root_path_in_servers
+        self.docs_url = docs_url
+        self.redoc_url = redoc_url
+        self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url
+        self.swagger_ui_init_oauth = swagger_ui_init_oauth
+        self.swagger_ui_parameters = swagger_ui_parameters
+        self.servers = servers or []
+        self.separate_input_output_schemas = separate_input_output_schemas
+        self.extra = extra
+        self.openapi_version: Annotated[
+            str,
+            Doc(
+                """
+                The version string of OpenAPI.
+
+                FastAPI will generate OpenAPI version 3.1.0, and will output that as
+                the OpenAPI version. But some tools, even though they might be
+                compatible with OpenAPI 3.1.0, might not recognize it as a valid.
+
+                So you could override this value to trick those tools into using
+                the generated OpenAPI. Have in mind that this is a hack. But if you
+                avoid using features added in OpenAPI 3.1.0, it might work for your
+                use case.
+
+                This is not passed as a parameter to the `FastAPI` class to avoid
+                giving the false idea that FastAPI would generate a different OpenAPI
+                schema. It is only available as an attribute.
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                app = FastAPI()
+
+                app.openapi_version = "3.0.2"
+                ```
+                """
+            ),
+        ] = "3.1.0"
+        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'"
+        # TODO: remove when discarding the openapi_prefix parameter
+        if openapi_prefix:
+            logger.warning(
+                '"openapi_prefix" has been deprecated in favor of "root_path", which '
+                "follows more closely the ASGI standard, is simpler, and more "
+                "automatic. Check the docs at "
+                "https://fastapi.tiangolo.com/advanced/sub-applications/"
+            )
+        self.webhooks: Annotated[
+            routing.APIRouter,
+            Doc(
+                """
+                The `app.webhooks` attribute is an `APIRouter` with the *path
+                operations* that will be used just for documentation of webhooks.
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+                """
+            ),
+        ] = webhooks or routing.APIRouter()
+        self.root_path = root_path or openapi_prefix
+        self.state: Annotated[
+            State,
+            Doc(
+                """
+                A state object for the application. This is the same object for the
+                entire application, it doesn't change from request to request.
+
+                You normally wouldn't use this in FastAPI, for most of the cases you
+                would instead use FastAPI dependencies.
+
+                This is simply inherited from Starlette.
+
+                Read more about it in the
+                [Starlette docs for Applications](https://www.starlette.io/applications/#storing-state-on-the-app-instance).
+                """
+            ),
+        ] = State()
+        self.dependency_overrides: Annotated[
+            Dict[Callable[..., Any], Callable[..., Any]],
+            Doc(
+                """
+                A dictionary with overrides for the dependencies.
+
+                Each key is the original dependency callable, and the value is the
+                actual dependency that should be called.
+
+                This is for testing, to replace expensive dependencies with testing
+                versions.
+
+                Read more about it in the
+                [FastAPI docs for Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/).
+                """
+            ),
+        ] = {}
+        self.router: routing.APIRouter = routing.APIRouter(
+            routes=routes,
+            redirect_slashes=redirect_slashes,
+            dependency_overrides_provider=self,
+            on_startup=on_startup,
+            on_shutdown=on_shutdown,
+            lifespan=lifespan,
+            default_response_class=default_response_class,
+            dependencies=dependencies,
+            callbacks=callbacks,
+            deprecated=deprecated,
+            include_in_schema=include_in_schema,
+            responses=responses,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+        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)
+        self.exception_handlers.setdefault(
+            RequestValidationError, request_validation_exception_handler
+        )
+        self.exception_handlers.setdefault(
+            WebSocketRequestValidationError,
+            # Starlette still has incorrect type specification for the handlers
+            websocket_request_validation_exception_handler,  # type: ignore
+        )
+
+        self.user_middleware: List[Middleware] = (
+            [] if middleware is None else list(middleware)
+        )
+        self.middleware_stack: Union[ASGIApp, None] = None
+        self.setup()
+
+    def openapi(self) -> Dict[str, Any]:
+        """
+        Generate the OpenAPI schema of the application. This is called by FastAPI
+        internally.
+
+        The first time it is called it stores the result in the attribute
+        `app.openapi_schema`, and next times it is called, it just returns that same
+        result. To avoid the cost of generating the schema every time.
+
+        If you need to modify the generated OpenAPI schema, you could modify it.
+
+        Read more in the
+        [FastAPI docs for OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/).
+        """
+        if not self.openapi_schema:
+            self.openapi_schema = get_openapi(
+                title=self.title,
+                version=self.version,
+                openapi_version=self.openapi_version,
+                summary=self.summary,
+                description=self.description,
+                terms_of_service=self.terms_of_service,
+                contact=self.contact,
+                license_info=self.license_info,
+                routes=self.routes,
+                webhooks=self.webhooks.routes,
+                tags=self.openapi_tags,
+                servers=self.servers,
+                separate_input_output_schemas=self.separate_input_output_schemas,
+            )
+        return self.openapi_schema
+
+    def setup(self) -> None:
+        if self.openapi_url:
+            urls = (server_data.get("url") for server_data in self.servers)
+            server_urls = {url for url in urls if url}
+
+            async def openapi(req: Request) -> JSONResponse:
+                root_path = req.scope.get("root_path", "").rstrip("/")
+                if root_path not in server_urls:
+                    if root_path and self.root_path_in_servers:
+                        self.servers.insert(0, {"url": root_path})
+                        server_urls.add(root_path)
+                return JSONResponse(self.openapi())
+
+            self.add_route(self.openapi_url, openapi, include_in_schema=False)
+        if self.openapi_url and self.docs_url:
+
+            async def swagger_ui_html(req: Request) -> HTMLResponse:
+                root_path = req.scope.get("root_path", "").rstrip("/")
+                openapi_url = root_path + self.openapi_url
+                oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url
+                if oauth2_redirect_url:
+                    oauth2_redirect_url = root_path + oauth2_redirect_url
+                return get_swagger_ui_html(
+                    openapi_url=openapi_url,
+                    title=f"{self.title} - Swagger UI",
+                    oauth2_redirect_url=oauth2_redirect_url,
+                    init_oauth=self.swagger_ui_init_oauth,
+                    swagger_ui_parameters=self.swagger_ui_parameters,
+                )
+
+            self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False)
+
+            if self.swagger_ui_oauth2_redirect_url:
+
+                async def swagger_ui_redirect(req: Request) -> HTMLResponse:
+                    return get_swagger_ui_oauth2_redirect_html()
+
+                self.add_route(
+                    self.swagger_ui_oauth2_redirect_url,
+                    swagger_ui_redirect,
+                    include_in_schema=False,
+                )
+        if self.openapi_url and self.redoc_url:
+
+            async def redoc_html(req: Request) -> HTMLResponse:
+                root_path = req.scope.get("root_path", "").rstrip("/")
+                openapi_url = root_path + self.openapi_url
+                return get_redoc_html(
+                    openapi_url=openapi_url, title=f"{self.title} - ReDoc"
+                )
+
+            self.add_route(self.redoc_url, redoc_html, include_in_schema=False)
+
+    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+        if self.root_path:
+            scope["root_path"] = self.root_path
+        await super().__call__(scope, receive, send)
+
+    def add_api_route(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        *,
+        response_model: Any = Default(None),
+        status_code: Optional[int] = 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,
+        deprecated: Optional[bool] = 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_by_alias: bool = True,
+        response_model_exclude_unset: bool = False,
+        response_model_exclude_defaults: bool = False,
+        response_model_exclude_none: bool = False,
+        include_in_schema: bool = True,
+        response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+            JSONResponse
+        ),
+        name: Optional[str] = None,
+        openapi_extra: Optional[Dict[str, Any]] = None,
+        generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
+            generate_unique_id
+        ),
+    ) -> None:
+        self.router.add_api_route(
+            path,
+            endpoint=endpoint,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=methods,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def api_route(
+        self,
+        path: str,
+        *,
+        response_model: Any = Default(None),
+        status_code: Optional[int] = 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,
+        deprecated: Optional[bool] = 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_by_alias: bool = True,
+        response_model_exclude_unset: bool = False,
+        response_model_exclude_defaults: bool = False,
+        response_model_exclude_none: bool = False,
+        include_in_schema: bool = True,
+        response_class: Type[Response] = Default(JSONResponse),
+        name: Optional[str] = None,
+        openapi_extra: Optional[Dict[str, Any]] = None,
+        generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
+            generate_unique_id
+        ),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.router.add_api_route(
+                path,
+                func,
+                response_model=response_model,
+                status_code=status_code,
+                tags=tags,
+                dependencies=dependencies,
+                summary=summary,
+                description=description,
+                response_description=response_description,
+                responses=responses,
+                deprecated=deprecated,
+                methods=methods,
+                operation_id=operation_id,
+                response_model_include=response_model_include,
+                response_model_exclude=response_model_exclude,
+                response_model_by_alias=response_model_by_alias,
+                response_model_exclude_unset=response_model_exclude_unset,
+                response_model_exclude_defaults=response_model_exclude_defaults,
+                response_model_exclude_none=response_model_exclude_none,
+                include_in_schema=include_in_schema,
+                response_class=response_class,
+                name=name,
+                openapi_extra=openapi_extra,
+                generate_unique_id_function=generate_unique_id_function,
+            )
+            return func
+
+        return decorator
+
+    def add_api_websocket_route(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        name: Optional[str] = None,
+        *,
+        dependencies: Optional[Sequence[Depends]] = None,
+    ) -> None:
+        self.router.add_api_websocket_route(
+            path,
+            endpoint,
+            name=name,
+            dependencies=dependencies,
+        )
+
+    def websocket(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                WebSocket path.
+                """
+            ),
+        ],
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A name for the WebSocket. Only used internally.
+                """
+            ),
+        ] = None,
+        *,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be used for this
+                WebSocket.
+
+                Read more about it in the
+                [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+                """
+            ),
+        ] = None,
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Decorate a WebSocket function.
+
+        Read more about it in the
+        [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+        **Example**
+
+        ```python
+        from fastapi import FastAPI, WebSocket
+
+        app = FastAPI()
+
+        @app.websocket("/ws")
+        async def websocket_endpoint(websocket: WebSocket):
+            await websocket.accept()
+            while True:
+                data = await websocket.receive_text()
+                await websocket.send_text(f"Message text was: {data}")
+        ```
+        """
+
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_api_websocket_route(
+                path,
+                func,
+                name=name,
+                dependencies=dependencies,
+            )
+            return func
+
+        return decorator
+
+    def include_router(
+        self,
+        router: Annotated[routing.APIRouter, Doc("The `APIRouter` to include.")],
+        *,
+        prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to all the *path operations* in this
+                router.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to all the
+                *path operations* in this router.
+
+                Read more about it in the
+                [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+
+                **Example**
+
+                ```python
+                from fastapi import Depends, FastAPI
+
+                from .dependencies import get_token_header
+                from .internal import admin
+
+                app = FastAPI()
+
+                app.include_router(
+                    admin.router,
+                    dependencies=[Depends(get_token_header)],
+                )
+                ```
+                """
+            ),
+        ] = None,
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses to be shown in OpenAPI.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+                And in the
+                [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark all the *path operations* in this router as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                from .internal import old_api
+
+                app = FastAPI()
+
+                app.include_router(
+                    old_api.router,
+                    deprecated=True,
+                )
+                ```
+                """
+            ),
+        ] = None,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include (or not) all the *path operations* in this router in the
+                generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+
+                from .internal import old_api
+
+                app = FastAPI()
+
+                app.include_router(
+                    old_api.router,
+                    include_in_schema=False,
+                )
+                ```
+                """
+            ),
+        ] = True,
+        default_response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Default response class to be used for the *path operations* in this
+                router.
+
+                Read more in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+                **Example**
+
+                ```python
+                from fastapi import FastAPI
+                from fastapi.responses import ORJSONResponse
+
+                from .internal import old_api
+
+                app = FastAPI()
+
+                app.include_router(
+                    old_api.router,
+                    default_response_class=ORJSONResponse,
+                )
+                ```
+                """
+            ),
+        ] = Default(JSONResponse),
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> None:
+        """
+        Include an `APIRouter` in the same app.
+
+        Read more about it in the
+        [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+
+        from .users import users_router
+
+        app = FastAPI()
+
+        app.include_router(users_router)
+        ```
+        """
+        self.router.include_router(
+            router,
+            prefix=prefix,
+            tags=tags,
+            dependencies=dependencies,
+            responses=responses,
+            deprecated=deprecated,
+            include_in_schema=include_in_schema,
+            default_response_class=default_response_class,
+            callbacks=callbacks,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def get(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP GET operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+
+        app = FastAPI()
+
+        @app.get("/items/")
+        def read_items():
+            return [{"name": "Empanada"}, {"name": "Arepa"}]
+        ```
+        """
+        return self.router.get(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def put(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP PUT operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+
+        @app.put("/items/{item_id}")
+        def replace_item(item_id: str, item: Item):
+            return {"message": "Item replaced", "id": item_id}
+        ```
+        """
+        return self.router.put(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def post(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP POST operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+
+        @app.post("/items/")
+        def create_item(item: Item):
+            return {"message": "Item created"}
+        ```
+        """
+        return self.router.post(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def delete(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP DELETE operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+
+        app = FastAPI()
+
+        @app.delete("/items/{item_id}")
+        def delete_item(item_id: str):
+            return {"message": "Item deleted"}
+        ```
+        """
+        return self.router.delete(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def options(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP OPTIONS operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+
+        app = FastAPI()
+
+        @app.options("/items/")
+        def get_item_options():
+            return {"additions": ["Aji", "Guacamole"]}
+        ```
+        """
+        return self.router.options(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def head(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP HEAD operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI, Response
+
+        app = FastAPI()
+
+        @app.head("/items/", status_code=204)
+        def get_items_headers(response: Response):
+            response.headers["X-Cat-Dog"] = "Alone in the world"
+        ```
+        """
+        return self.router.head(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def patch(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP PATCH operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+
+        @app.patch("/items/")
+        def update_item(item: Item):
+            return {"message": "Item updated in place"}
+        ```
+        """
+        return self.router.patch(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def trace(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[routing.APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP TRACE operation.
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI
+
+        app = FastAPI()
+
+        @app.put("/items/{item_id}")
+        def trace_item(item_id: str):
+            return None
+        ```
+        """
+        return self.router.trace(
+            path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def websocket_route(
+        self, path: str, name: Union[str, None] = None
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.router.add_websocket_route(path, func, name=name)
+            return func
+
+        return decorator
+
+    @deprecated(
+        """
+        on_event is deprecated, use lifespan event handlers instead.
+
+        Read more about it in the
+        [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+        """
+    )
+    def on_event(
+        self,
+        event_type: Annotated[
+            str,
+            Doc(
+                """
+                The type of event. `startup` or `shutdown`.
+                """
+            ),
+        ],
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add an event handler for the application.
+
+        `on_event` is deprecated, use `lifespan` event handlers instead.
+
+        Read more about it in the
+        [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+        """
+        return self.router.on_event(event_type)
+
+    def middleware(
+        self,
+        middleware_type: Annotated[
+            str,
+            Doc(
+                """
+                The type of middleware. Currently only supports `http`.
+                """
+            ),
+        ],
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a middleware to the application.
+
+        Read more about it in the
+        [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+
+        ## Example
+
+        ```python
+        import time
+
+        from fastapi import FastAPI, Request
+
+        app = FastAPI()
+
+
+        @app.middleware("http")
+        async def add_process_time_header(request: Request, call_next):
+            start_time = time.time()
+            response = await call_next(request)
+            process_time = time.time() - start_time
+            response.headers["X-Process-Time"] = str(process_time)
+            return response
+        ```
+        """
+
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_middleware(BaseHTTPMiddleware, dispatch=func)
+            return func
+
+        return decorator
+
+    def exception_handler(
+        self,
+        exc_class_or_status_code: Annotated[
+            Union[int, Type[Exception]],
+            Doc(
+                """
+                The Exception class this would handle, or a status code.
+                """
+            ),
+        ],
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add an exception handler to the app.
+
+        Read more about it in the
+        [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+        ## Example
+
+        ```python
+        from fastapi import FastAPI, Request
+        from fastapi.responses import JSONResponse
+
+
+        class UnicornException(Exception):
+            def __init__(self, name: str):
+                self.name = name
+
+
+        app = FastAPI()
+
+
+        @app.exception_handler(UnicornException)
+        async def unicorn_exception_handler(request: Request, exc: UnicornException):
+            return JSONResponse(
+                status_code=418,
+                content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
+            )
+        ```
+        """
+
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_exception_handler(exc_class_or_status_code, func)
+            return func
+
+        return decorator
diff --git a/.venv/lib/python3.12/site-packages/fastapi/background.py b/.venv/lib/python3.12/site-packages/fastapi/background.py
new file mode 100644
index 00000000..203578a4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/background.py
@@ -0,0 +1,59 @@
+from typing import Any, Callable
+
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
+from typing_extensions import Annotated, Doc, ParamSpec
+
+P = ParamSpec("P")
+
+
+class BackgroundTasks(StarletteBackgroundTasks):
+    """
+    A collection of background tasks that will be called after a response has been
+    sent to the client.
+
+    Read more about it in the
+    [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+
+    ## Example
+
+    ```python
+    from fastapi import BackgroundTasks, FastAPI
+
+    app = FastAPI()
+
+
+    def write_notification(email: str, message=""):
+        with open("log.txt", mode="w") as email_file:
+            content = f"notification for {email}: {message}"
+            email_file.write(content)
+
+
+    @app.post("/send-notification/{email}")
+    async def send_notification(email: str, background_tasks: BackgroundTasks):
+        background_tasks.add_task(write_notification, email, message="some notification")
+        return {"message": "Notification sent in the background"}
+    ```
+    """
+
+    def add_task(
+        self,
+        func: Annotated[
+            Callable[P, Any],
+            Doc(
+                """
+                The function to call after the response is sent.
+
+                It can be a regular `def` function or an `async def` function.
+                """
+            ),
+        ],
+        *args: P.args,
+        **kwargs: P.kwargs,
+    ) -> None:
+        """
+        Add a function to be called in the background after the response is sent.
+
+        Read more about it in the
+        [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+        """
+        return super().add_task(func, *args, **kwargs)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/cli.py b/.venv/lib/python3.12/site-packages/fastapi/cli.py
new file mode 100644
index 00000000..8d3301e9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/cli.py
@@ -0,0 +1,13 @@
+try:
+    from fastapi_cli.cli import main as cli_main
+
+except ImportError:  # pragma: no cover
+    cli_main = None  # type: ignore
+
+
+def main() -> None:
+    if not cli_main:  # type: ignore[truthy-function]
+        message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
+        print(message)
+        raise RuntimeError(message)  # noqa: B904
+    cli_main()
diff --git a/.venv/lib/python3.12/site-packages/fastapi/concurrency.py b/.venv/lib/python3.12/site-packages/fastapi/concurrency.py
new file mode 100644
index 00000000..3202c707
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/concurrency.py
@@ -0,0 +1,39 @@
+from contextlib import asynccontextmanager as asynccontextmanager
+from typing import AsyncGenerator, ContextManager, TypeVar
+
+import anyio.to_thread
+from anyio import CapacityLimiter
+from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool  # noqa
+from starlette.concurrency import run_in_threadpool as run_in_threadpool  # noqa
+from starlette.concurrency import (  # noqa
+    run_until_first_complete as run_until_first_complete,
+)
+
+_T = TypeVar("_T")
+
+
+@asynccontextmanager
+async def contextmanager_in_threadpool(
+    cm: ContextManager[_T],
+) -> AsyncGenerator[_T, None]:
+    # blocking __exit__ from running waiting on a free thread
+    # can create race conditions/deadlocks if the context manager itself
+    # has its own internal pool (e.g. a database connection pool)
+    # to avoid this we let __exit__ run without a capacity limit
+    # since we're creating a new limiter for each call, any non-zero limit
+    # works (1 is arbitrary)
+    exit_limiter = CapacityLimiter(1)
+    try:
+        yield await run_in_threadpool(cm.__enter__)
+    except Exception as e:
+        ok = bool(
+            await anyio.to_thread.run_sync(
+                cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter
+            )
+        )
+        if not ok:
+            raise e
+    else:
+        await anyio.to_thread.run_sync(
+            cm.__exit__, None, None, None, limiter=exit_limiter
+        )
diff --git a/.venv/lib/python3.12/site-packages/fastapi/datastructures.py b/.venv/lib/python3.12/site-packages/fastapi/datastructures.py
new file mode 100644
index 00000000..cf8406b0
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/datastructures.py
@@ -0,0 +1,204 @@
+from typing import (
+    Any,
+    BinaryIO,
+    Callable,
+    Dict,
+    Iterable,
+    Optional,
+    Type,
+    TypeVar,
+    cast,
+)
+
+from fastapi._compat import (
+    PYDANTIC_V2,
+    CoreSchema,
+    GetJsonSchemaHandler,
+    JsonSchemaValue,
+    with_info_plain_validator_function,
+)
+from starlette.datastructures import URL as URL  # noqa: F401
+from starlette.datastructures import Address as Address  # noqa: F401
+from starlette.datastructures import FormData as FormData  # noqa: F401
+from starlette.datastructures import Headers as Headers  # noqa: F401
+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, Doc
+
+
+class UploadFile(StarletteUploadFile):
+    """
+    A file uploaded in a request.
+
+    Define it as a *path operation function* (or dependency) parameter.
+
+    If you are using a regular `def` function, you can use the `upload_file.file`
+    attribute to access the raw standard Python file (blocking, not async), useful and
+    needed for non-async code.
+
+    Read more about it in the
+    [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/).
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import FastAPI, File, UploadFile
+
+    app = FastAPI()
+
+
+    @app.post("/files/")
+    async def create_file(file: Annotated[bytes, File()]):
+        return {"file_size": len(file)}
+
+
+    @app.post("/uploadfile/")
+    async def create_upload_file(file: UploadFile):
+        return {"filename": file.filename}
+    ```
+    """
+
+    file: Annotated[
+        BinaryIO,
+        Doc("The standard Python file object (non-async)."),
+    ]
+    filename: Annotated[Optional[str], Doc("The original file name.")]
+    size: Annotated[Optional[int], Doc("The size of the file in bytes.")]
+    headers: Annotated[Headers, Doc("The headers of the request.")]
+    content_type: Annotated[
+        Optional[str], Doc("The content type of the request, from the headers.")
+    ]
+
+    async def write(
+        self,
+        data: Annotated[
+            bytes,
+            Doc(
+                """
+                The bytes to write to the file.
+                """
+            ),
+        ],
+    ) -> None:
+        """
+        Write some bytes to the file.
+
+        You normally wouldn't use this from a file you read in a request.
+
+        To be awaitable, compatible with async, this is run in threadpool.
+        """
+        return await super().write(data)
+
+    async def read(
+        self,
+        size: Annotated[
+            int,
+            Doc(
+                """
+                The number of bytes to read from the file.
+                """
+            ),
+        ] = -1,
+    ) -> bytes:
+        """
+        Read some bytes from the file.
+
+        To be awaitable, compatible with async, this is run in threadpool.
+        """
+        return await super().read(size)
+
+    async def seek(
+        self,
+        offset: Annotated[
+            int,
+            Doc(
+                """
+                The position in bytes to seek to in the file.
+                """
+            ),
+        ],
+    ) -> None:
+        """
+        Move to a position in the file.
+
+        Any next read or write will be done from that position.
+
+        To be awaitable, compatible with async, this is run in threadpool.
+        """
+        return await super().seek(offset)
+
+    async def close(self) -> None:
+        """
+        Close the file.
+
+        To be awaitable, compatible with async, this is run in threadpool.
+        """
+        return await super().close()
+
+    @classmethod
+    def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
+        yield cls.validate
+
+    @classmethod
+    def validate(cls: Type["UploadFile"], v: Any) -> Any:
+        if not isinstance(v, StarletteUploadFile):
+            raise ValueError(f"Expected UploadFile, received: {type(v)}")
+        return v
+
+    @classmethod
+    def _validate(cls, __input_value: Any, _: Any) -> "UploadFile":
+        if not isinstance(__input_value, StarletteUploadFile):
+            raise ValueError(f"Expected UploadFile, received: {type(__input_value)}")
+        return cast(UploadFile, __input_value)
+
+    if not PYDANTIC_V2:
+
+        @classmethod
+        def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
+            field_schema.update({"type": "string", "format": "binary"})
+
+    @classmethod
+    def __get_pydantic_json_schema__(
+        cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
+    ) -> JsonSchemaValue:
+        return {"type": "string", "format": "binary"}
+
+    @classmethod
+    def __get_pydantic_core_schema__(
+        cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+    ) -> CoreSchema:
+        return with_info_plain_validator_function(cls._validate)
+
+
+class DefaultPlaceholder:
+    """
+    You shouldn't use this class directly.
+
+    It's used internally to recognize when a default value has been overwritten, even
+    if the overridden default value was truthy.
+    """
+
+    def __init__(self, value: Any):
+        self.value = value
+
+    def __bool__(self) -> bool:
+        return bool(self.value)
+
+    def __eq__(self, o: object) -> bool:
+        return isinstance(o, DefaultPlaceholder) and o.value == self.value
+
+
+DefaultType = TypeVar("DefaultType")
+
+
+def Default(value: DefaultType) -> DefaultType:
+    """
+    You shouldn't use this function directly.
+
+    It's used internally to recognize when a default value has been overwritten, even
+    if the overridden default value was truthy.
+    """
+    return DefaultPlaceholder(value)  # type: ignore
diff --git a/.venv/lib/python3.12/site-packages/fastapi/dependencies/__init__.py b/.venv/lib/python3.12/site-packages/fastapi/dependencies/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/dependencies/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/fastapi/dependencies/models.py b/.venv/lib/python3.12/site-packages/fastapi/dependencies/models.py
new file mode 100644
index 00000000..418c1172
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/dependencies/models.py
@@ -0,0 +1,37 @@
+from dataclasses import dataclass, field
+from typing import Any, Callable, List, Optional, Sequence, Tuple
+
+from fastapi._compat import ModelField
+from fastapi.security.base import SecurityBase
+
+
+@dataclass
+class SecurityRequirement:
+    security_scheme: SecurityBase
+    scopes: Optional[Sequence[str]] = None
+
+
+@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)
+    security_requirements: List[SecurityRequirement] = field(default_factory=list)
+    name: Optional[str] = None
+    call: Optional[Callable[..., Any]] = None
+    request_param_name: Optional[str] = None
+    websocket_param_name: Optional[str] = None
+    http_connection_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
+    security_scopes: Optional[List[str]] = None
+    use_cache: bool = True
+    path: Optional[str] = None
+    cache_key: Tuple[Optional[Callable[..., Any]], Tuple[str, ...]] = field(init=False)
+
+    def __post_init__(self) -> None:
+        self.cache_key = (self.call, tuple(sorted(set(self.security_scopes or []))))
diff --git a/.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py b/.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py
new file mode 100644
index 00000000..84dfa4d0
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/dependencies/utils.py
@@ -0,0 +1,980 @@
+import inspect
+from contextlib import AsyncExitStack, contextmanager
+from copy import copy, deepcopy
+from dataclasses import dataclass
+from typing import (
+    Any,
+    Callable,
+    Coroutine,
+    Dict,
+    ForwardRef,
+    List,
+    Mapping,
+    Optional,
+    Sequence,
+    Tuple,
+    Type,
+    Union,
+    cast,
+)
+
+import anyio
+from fastapi import params
+from fastapi._compat import (
+    PYDANTIC_V2,
+    ErrorWrapper,
+    ModelField,
+    RequiredParam,
+    Undefined,
+    _regenerate_error_with_loc,
+    copy_field_info,
+    create_body_model,
+    evaluate_forwardref,
+    field_annotation_is_scalar,
+    get_annotation_from_field_info,
+    get_cached_model_fields,
+    get_missing_field_error,
+    is_bytes_field,
+    is_bytes_sequence_field,
+    is_scalar_field,
+    is_scalar_sequence_field,
+    is_sequence_field,
+    is_uploadfile_or_nonable_uploadfile_annotation,
+    is_uploadfile_sequence_annotation,
+    lenient_issubclass,
+    sequence_types,
+    serialize_sequence_value,
+    value_is_sequence,
+)
+from fastapi.background import BackgroundTasks
+from fastapi.concurrency import (
+    asynccontextmanager,
+    contextmanager_in_threadpool,
+)
+from fastapi.dependencies.models import Dependant, SecurityRequirement
+from fastapi.logger import logger
+from fastapi.security.base import SecurityBase
+from fastapi.security.oauth2 import OAuth2, SecurityScopes
+from fastapi.security.open_id_connect_url import OpenIdConnect
+from fastapi.utils import create_model_field, get_path_param_names
+from pydantic import BaseModel
+from pydantic.fields import FieldInfo
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
+from starlette.concurrency import run_in_threadpool
+from starlette.datastructures import (
+    FormData,
+    Headers,
+    ImmutableMultiDict,
+    QueryParams,
+    UploadFile,
+)
+from starlette.requests import HTTPConnection, Request
+from starlette.responses import Response
+from starlette.websockets import WebSocket
+from typing_extensions import Annotated, get_args, get_origin
+
+multipart_not_installed_error = (
+    'Form data requires "python-multipart" to be installed. \n'
+    'You can install "python-multipart" with: \n\n'
+    "pip install python-multipart\n"
+)
+multipart_incorrect_install_error = (
+    'Form data requires "python-multipart" to be installed. '
+    'It seems you installed "multipart" instead. \n'
+    'You can remove "multipart" with: \n\n'
+    "pip uninstall multipart\n\n"
+    'And then install "python-multipart" with: \n\n'
+    "pip install python-multipart\n"
+)
+
+
+def ensure_multipart_is_installed() -> None:
+    try:
+        from python_multipart import __version__
+
+        # Import an attribute that can be mocked/deleted in testing
+        assert __version__ > "0.0.12"
+    except (ImportError, AssertionError):
+        try:
+            # __version__ is available in both multiparts, and can be mocked
+            from multipart import __version__  # type: ignore[no-redef,import-untyped]
+
+            assert __version__
+            try:
+                # parse_options_header is only available in the right multipart
+                from multipart.multipart import (  # type: ignore[import-untyped]
+                    parse_options_header,
+                )
+
+                assert parse_options_header
+            except ImportError:
+                logger.error(multipart_incorrect_install_error)
+                raise RuntimeError(multipart_incorrect_install_error) from None
+        except ImportError:
+            logger.error(multipart_not_installed_error)
+            raise RuntimeError(multipart_not_installed_error) from None
+
+
+def get_param_sub_dependant(
+    *,
+    param_name: str,
+    depends: params.Depends,
+    path: str,
+    security_scopes: Optional[List[str]] = None,
+) -> Dependant:
+    assert depends.dependency
+    return get_sub_dependant(
+        depends=depends,
+        dependency=depends.dependency,
+        path=path,
+        name=param_name,
+        security_scopes=security_scopes,
+    )
+
+
+def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant:
+    assert callable(depends.dependency), (
+        "A parameter-less dependency must have a callable dependency"
+    )
+    return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path)
+
+
+def get_sub_dependant(
+    *,
+    depends: params.Depends,
+    dependency: Callable[..., Any],
+    path: str,
+    name: Optional[str] = None,
+    security_scopes: Optional[List[str]] = None,
+) -> Dependant:
+    security_requirement = None
+    security_scopes = security_scopes or []
+    if isinstance(depends, params.Security):
+        dependency_scopes = depends.scopes
+        security_scopes.extend(dependency_scopes)
+    if isinstance(dependency, SecurityBase):
+        use_scopes: List[str] = []
+        if isinstance(dependency, (OAuth2, OpenIdConnect)):
+            use_scopes = security_scopes
+        security_requirement = SecurityRequirement(
+            security_scheme=dependency, scopes=use_scopes
+        )
+    sub_dependant = get_dependant(
+        path=path,
+        call=dependency,
+        name=name,
+        security_scopes=security_scopes,
+        use_cache=depends.use_cache,
+    )
+    if security_requirement:
+        sub_dependant.security_requirements.append(security_requirement)
+    return sub_dependant
+
+
+CacheKey = Tuple[Optional[Callable[..., Any]], Tuple[str, ...]]
+
+
+def get_flat_dependant(
+    dependant: Dependant,
+    *,
+    skip_repeats: bool = False,
+    visited: Optional[List[CacheKey]] = None,
+) -> Dependant:
+    if visited is None:
+        visited = []
+    visited.append(dependant.cache_key)
+
+    flat_dependant = Dependant(
+        path_params=dependant.path_params.copy(),
+        query_params=dependant.query_params.copy(),
+        header_params=dependant.header_params.copy(),
+        cookie_params=dependant.cookie_params.copy(),
+        body_params=dependant.body_params.copy(),
+        security_requirements=dependant.security_requirements.copy(),
+        use_cache=dependant.use_cache,
+        path=dependant.path,
+    )
+    for sub_dependant in dependant.dependencies:
+        if skip_repeats and sub_dependant.cache_key in visited:
+            continue
+        flat_sub = get_flat_dependant(
+            sub_dependant, skip_repeats=skip_repeats, visited=visited
+        )
+        flat_dependant.path_params.extend(flat_sub.path_params)
+        flat_dependant.query_params.extend(flat_sub.query_params)
+        flat_dependant.header_params.extend(flat_sub.header_params)
+        flat_dependant.cookie_params.extend(flat_sub.cookie_params)
+        flat_dependant.body_params.extend(flat_sub.body_params)
+        flat_dependant.security_requirements.extend(flat_sub.security_requirements)
+    return flat_dependant
+
+
+def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
+    if not fields:
+        return fields
+    first_field = fields[0]
+    if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
+        fields_to_extract = get_cached_model_fields(first_field.type_)
+        return fields_to_extract
+    return fields
+
+
+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)
+    header_params = _get_flat_fields_from_params(flat_dependant.header_params)
+    cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
+    return path_params + query_params + header_params + cookie_params
+
+
+def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
+    signature = inspect.signature(call)
+    globalns = getattr(call, "__globals__", {})
+    typed_params = [
+        inspect.Parameter(
+            name=param.name,
+            kind=param.kind,
+            default=param.default,
+            annotation=get_typed_annotation(param.annotation, globalns),
+        )
+        for param in signature.parameters.values()
+    ]
+    typed_signature = inspect.Signature(typed_params)
+    return typed_signature
+
+
+def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any:
+    if isinstance(annotation, str):
+        annotation = ForwardRef(annotation)
+        annotation = evaluate_forwardref(annotation, globalns, globalns)
+    return annotation
+
+
+def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
+    signature = inspect.signature(call)
+    annotation = signature.return_annotation
+
+    if annotation is inspect.Signature.empty:
+        return None
+
+    globalns = getattr(call, "__globals__", {})
+    return get_typed_annotation(annotation, globalns)
+
+
+def get_dependant(
+    *,
+    path: str,
+    call: Callable[..., Any],
+    name: Optional[str] = None,
+    security_scopes: Optional[List[str]] = None,
+    use_cache: bool = True,
+) -> Dependant:
+    path_param_names = get_path_param_names(path)
+    endpoint_signature = get_typed_signature(call)
+    signature_params = endpoint_signature.parameters
+    dependant = Dependant(
+        call=call,
+        name=name,
+        path=path,
+        security_scopes=security_scopes,
+        use_cache=use_cache,
+    )
+    for param_name, param in signature_params.items():
+        is_path_param = param_name in path_param_names
+        param_details = analyze_param(
+            param_name=param_name,
+            annotation=param.annotation,
+            value=param.default,
+            is_path_param=is_path_param,
+        )
+        if param_details.depends is not None:
+            sub_dependant = get_param_sub_dependant(
+                param_name=param_name,
+                depends=param_details.depends,
+                path=path,
+                security_scopes=security_scopes,
+            )
+            dependant.dependencies.append(sub_dependant)
+            continue
+        if add_non_field_param_to_dependency(
+            param_name=param_name,
+            type_annotation=param_details.type_annotation,
+            dependant=dependant,
+        ):
+            assert param_details.field is None, (
+                f"Cannot specify multiple FastAPI annotations for {param_name!r}"
+            )
+            continue
+        assert param_details.field is not None
+        if isinstance(param_details.field.field_info, params.Body):
+            dependant.body_params.append(param_details.field)
+        else:
+            add_param_to_fields(field=param_details.field, dependant=dependant)
+    return dependant
+
+
+def add_non_field_param_to_dependency(
+    *, param_name: str, type_annotation: Any, dependant: Dependant
+) -> Optional[bool]:
+    if lenient_issubclass(type_annotation, Request):
+        dependant.request_param_name = param_name
+        return True
+    elif lenient_issubclass(type_annotation, WebSocket):
+        dependant.websocket_param_name = param_name
+        return True
+    elif lenient_issubclass(type_annotation, HTTPConnection):
+        dependant.http_connection_param_name = param_name
+        return True
+    elif lenient_issubclass(type_annotation, Response):
+        dependant.response_param_name = param_name
+        return True
+    elif lenient_issubclass(type_annotation, StarletteBackgroundTasks):
+        dependant.background_tasks_param_name = param_name
+        return True
+    elif lenient_issubclass(type_annotation, SecurityScopes):
+        dependant.security_scopes_param_name = param_name
+        return True
+    return None
+
+
+@dataclass
+class ParamDetails:
+    type_annotation: Any
+    depends: Optional[params.Depends]
+    field: Optional[ModelField]
+
+
+def analyze_param(
+    *,
+    param_name: str,
+    annotation: Any,
+    value: Any,
+    is_path_param: bool,
+) -> ParamDetails:
+    field_info = None
+    depends = None
+    type_annotation: Any = Any
+    use_annotation: Any = Any
+    if annotation is not inspect.Signature.empty:
+        use_annotation = annotation
+        type_annotation = annotation
+    # Extract Annotated info
+    if get_origin(use_annotation) is Annotated:
+        annotated_args = get_args(annotation)
+        type_annotation = annotated_args[0]
+        fastapi_annotations = [
+            arg
+            for arg in annotated_args[1:]
+            if isinstance(arg, (FieldInfo, params.Depends))
+        ]
+        fastapi_specific_annotations = [
+            arg
+            for arg in fastapi_annotations
+            if isinstance(arg, (params.Param, params.Body, params.Depends))
+        ]
+        if fastapi_specific_annotations:
+            fastapi_annotation: Union[FieldInfo, params.Depends, None] = (
+                fastapi_specific_annotations[-1]
+            )
+        else:
+            fastapi_annotation = None
+        # Set default for Annotated FieldInfo
+        if isinstance(fastapi_annotation, FieldInfo):
+            # Copy `field_info` because we mutate `field_info.default` below.
+            field_info = copy_field_info(
+                field_info=fastapi_annotation, annotation=use_annotation
+            )
+            assert (
+                field_info.default is Undefined or field_info.default is RequiredParam
+            ), (
+                f"`{field_info.__class__.__name__}` default value cannot be set in"
+                f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
+            )
+            if value is not inspect.Signature.empty:
+                assert not is_path_param, "Path parameters cannot have default values"
+                field_info.default = value
+            else:
+                field_info.default = RequiredParam
+        # Get Annotated Depends
+        elif isinstance(fastapi_annotation, params.Depends):
+            depends = fastapi_annotation
+    # Get Depends from default value
+    if isinstance(value, params.Depends):
+        assert depends is None, (
+            "Cannot specify `Depends` in `Annotated` and default value"
+            f" together for {param_name!r}"
+        )
+        assert field_info is None, (
+            "Cannot specify a FastAPI annotation in `Annotated` and `Depends` as a"
+            f" default value together for {param_name!r}"
+        )
+        depends = value
+    # Get FieldInfo from default value
+    elif isinstance(value, FieldInfo):
+        assert field_info is None, (
+            "Cannot specify FastAPI annotations in `Annotated` and default value"
+            f" together for {param_name!r}"
+        )
+        field_info = value
+        if PYDANTIC_V2:
+            field_info.annotation = type_annotation
+
+    # Get Depends from type annotation
+    if depends is not None and depends.dependency is None:
+        # Copy `depends` before mutating it
+        depends = copy(depends)
+        depends.dependency = type_annotation
+
+    # Handle non-param type annotations like Request
+    if lenient_issubclass(
+        type_annotation,
+        (
+            Request,
+            WebSocket,
+            HTTPConnection,
+            Response,
+            StarletteBackgroundTasks,
+            SecurityScopes,
+        ),
+    ):
+        assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
+        assert field_info is None, (
+            f"Cannot specify FastAPI annotation for type {type_annotation!r}"
+        )
+    # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
+    elif field_info is None and depends is None:
+        default_value = value if value is not inspect.Signature.empty else RequiredParam
+        if is_path_param:
+            # We might check here that `default_value is RequiredParam`, but the fact is that the same
+            # parameter might sometimes be a path parameter and sometimes not. See
+            # `tests/test_infer_param_optionality.py` for an example.
+            field_info = params.Path(annotation=use_annotation)
+        elif is_uploadfile_or_nonable_uploadfile_annotation(
+            type_annotation
+        ) or is_uploadfile_sequence_annotation(type_annotation):
+            field_info = params.File(annotation=use_annotation, default=default_value)
+        elif not field_annotation_is_scalar(annotation=type_annotation):
+            field_info = params.Body(annotation=use_annotation, default=default_value)
+        else:
+            field_info = params.Query(annotation=use_annotation, default=default_value)
+
+    field = None
+    # It's a field_info, not a dependency
+    if field_info is not None:
+        # Handle field_info.in_
+        if is_path_param:
+            assert isinstance(field_info, params.Path), (
+                f"Cannot use `{field_info.__class__.__name__}` for path param"
+                f" {param_name!r}"
+            )
+        elif (
+            isinstance(field_info, params.Param)
+            and getattr(field_info, "in_", None) is None
+        ):
+            field_info.in_ = params.ParamTypes.query
+        use_annotation_from_field_info = get_annotation_from_field_info(
+            use_annotation,
+            field_info,
+            param_name,
+        )
+        if isinstance(field_info, params.Form):
+            ensure_multipart_is_installed()
+        if not field_info.alias and getattr(field_info, "convert_underscores", None):
+            alias = param_name.replace("_", "-")
+        else:
+            alias = field_info.alias or param_name
+        field_info.alias = alias
+        field = create_model_field(
+            name=param_name,
+            type_=use_annotation_from_field_info,
+            default=field_info.default,
+            alias=alias,
+            required=field_info.default in (RequiredParam, Undefined),
+            field_info=field_info,
+        )
+        if is_path_param:
+            assert is_scalar_field(field=field), (
+                "Path params must be of one of the supported types"
+            )
+        elif isinstance(field_info, params.Query):
+            assert (
+                is_scalar_field(field)
+                or is_scalar_sequence_field(field)
+                or (
+                    lenient_issubclass(field.type_, BaseModel)
+                    # For Pydantic v1
+                    and getattr(field, "shape", 1) == 1
+                )
+            )
+
+    return ParamDetails(type_annotation=type_annotation, depends=depends, field=field)
+
+
+def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
+    field_info = field.field_info
+    field_info_in = getattr(field_info, "in_", None)
+    if field_info_in == params.ParamTypes.path:
+        dependant.path_params.append(field)
+    elif field_info_in == params.ParamTypes.query:
+        dependant.query_params.append(field)
+    elif field_info_in == params.ParamTypes.header:
+        dependant.header_params.append(field)
+    else:
+        assert field_info_in == params.ParamTypes.cookie, (
+            f"non-body parameters must be in path, query, header or cookie: {field.name}"
+        )
+        dependant.cookie_params.append(field)
+
+
+def is_coroutine_callable(call: Callable[..., Any]) -> bool:
+    if inspect.isroutine(call):
+        return inspect.iscoroutinefunction(call)
+    if inspect.isclass(call):
+        return False
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
+    return inspect.iscoroutinefunction(dunder_call)
+
+
+def is_async_gen_callable(call: Callable[..., Any]) -> bool:
+    if inspect.isasyncgenfunction(call):
+        return True
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
+    return inspect.isasyncgenfunction(dunder_call)
+
+
+def is_gen_callable(call: Callable[..., Any]) -> bool:
+    if inspect.isgeneratorfunction(call):
+        return True
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
+    return inspect.isgeneratorfunction(dunder_call)
+
+
+async def solve_generator(
+    *, call: Callable[..., Any], stack: AsyncExitStack, sub_values: Dict[str, Any]
+) -> Any:
+    if is_gen_callable(call):
+        cm = contextmanager_in_threadpool(contextmanager(call)(**sub_values))
+    elif is_async_gen_callable(call):
+        cm = asynccontextmanager(call)(**sub_values)
+    return await stack.enter_async_context(cm)
+
+
+@dataclass
+class SolvedDependency:
+    values: Dict[str, Any]
+    errors: List[Any]
+    background_tasks: Optional[StarletteBackgroundTasks]
+    response: Response
+    dependency_cache: Dict[Tuple[Callable[..., Any], Tuple[str]], Any]
+
+
+async def solve_dependencies(
+    *,
+    request: Union[Request, WebSocket],
+    dependant: Dependant,
+    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[Tuple[Callable[..., Any], Tuple[str]], Any]] = None,
+    async_exit_stack: AsyncExitStack,
+    embed_body_fields: bool,
+) -> SolvedDependency:
+    values: Dict[str, Any] = {}
+    errors: List[Any] = []
+    if response is None:
+        response = Response()
+        del response.headers["content-length"]
+        response.status_code = None  # type: ignore
+    dependency_cache = dependency_cache or {}
+    sub_dependant: Dependant
+    for sub_dependant in dependant.dependencies:
+        sub_dependant.call = cast(Callable[..., Any], sub_dependant.call)
+        sub_dependant.cache_key = cast(
+            Tuple[Callable[..., Any], Tuple[str]], sub_dependant.cache_key
+        )
+        call = sub_dependant.call
+        use_sub_dependant = sub_dependant
+        if (
+            dependency_overrides_provider
+            and dependency_overrides_provider.dependency_overrides
+        ):
+            original_call = sub_dependant.call
+            call = getattr(
+                dependency_overrides_provider, "dependency_overrides", {}
+            ).get(original_call, original_call)
+            use_path: str = sub_dependant.path  # type: ignore
+            use_sub_dependant = get_dependant(
+                path=use_path,
+                call=call,
+                name=sub_dependant.name,
+                security_scopes=sub_dependant.security_scopes,
+            )
+
+        solved_result = await solve_dependencies(
+            request=request,
+            dependant=use_sub_dependant,
+            body=body,
+            background_tasks=background_tasks,
+            response=response,
+            dependency_overrides_provider=dependency_overrides_provider,
+            dependency_cache=dependency_cache,
+            async_exit_stack=async_exit_stack,
+            embed_body_fields=embed_body_fields,
+        )
+        background_tasks = solved_result.background_tasks
+        dependency_cache.update(solved_result.dependency_cache)
+        if solved_result.errors:
+            errors.extend(solved_result.errors)
+            continue
+        if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache:
+            solved = dependency_cache[sub_dependant.cache_key]
+        elif is_gen_callable(call) or is_async_gen_callable(call):
+            solved = await solve_generator(
+                call=call, stack=async_exit_stack, sub_values=solved_result.values
+            )
+        elif is_coroutine_callable(call):
+            solved = await call(**solved_result.values)
+        else:
+            solved = await run_in_threadpool(call, **solved_result.values)
+        if sub_dependant.name is not None:
+            values[sub_dependant.name] = solved
+        if sub_dependant.cache_key not in dependency_cache:
+            dependency_cache[sub_dependant.cache_key] = solved
+    path_values, path_errors = request_params_to_args(
+        dependant.path_params, request.path_params
+    )
+    query_values, query_errors = request_params_to_args(
+        dependant.query_params, request.query_params
+    )
+    header_values, header_errors = request_params_to_args(
+        dependant.header_params, request.headers
+    )
+    cookie_values, cookie_errors = request_params_to_args(
+        dependant.cookie_params, request.cookies
+    )
+    values.update(path_values)
+    values.update(query_values)
+    values.update(header_values)
+    values.update(cookie_values)
+    errors += path_errors + query_errors + header_errors + cookie_errors
+    if dependant.body_params:
+        (
+            body_values,
+            body_errors,
+        ) = await request_body_to_args(  # body_params checked above
+            body_fields=dependant.body_params,
+            received_body=body,
+            embed_body_fields=embed_body_fields,
+        )
+        values.update(body_values)
+        errors.extend(body_errors)
+    if dependant.http_connection_param_name:
+        values[dependant.http_connection_param_name] = request
+    if dependant.request_param_name and isinstance(request, Request):
+        values[dependant.request_param_name] = request
+    elif dependant.websocket_param_name and isinstance(request, WebSocket):
+        values[dependant.websocket_param_name] = request
+    if dependant.background_tasks_param_name:
+        if background_tasks is None:
+            background_tasks = BackgroundTasks()
+        values[dependant.background_tasks_param_name] = background_tasks
+    if dependant.response_param_name:
+        values[dependant.response_param_name] = response
+    if dependant.security_scopes_param_name:
+        values[dependant.security_scopes_param_name] = SecurityScopes(
+            scopes=dependant.security_scopes
+        )
+    return SolvedDependency(
+        values=values,
+        errors=errors,
+        background_tasks=background_tasks,
+        response=response,
+        dependency_cache=dependency_cache,
+    )
+
+
+def _validate_value_with_model_field(
+    *, 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)]
+        else:
+            return deepcopy(field.default), []
+    v_, errors_ = field.validate(value, values, loc=loc)
+    if isinstance(errors_, ErrorWrapper):
+        return None, [errors_]
+    elif isinstance(errors_, list):
+        new_errors = _regenerate_error_with_loc(errors=errors_, loc_prefix=())
+        return None, new_errors
+    else:
+        return v_, []
+
+
+def _get_multidict_value(
+    field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None
+) -> Any:
+    alias = alias or field.alias
+    if is_sequence_field(field) and isinstance(values, (ImmutableMultiDict, Headers)):
+        value = values.getlist(alias)
+    else:
+        value = values.get(alias, None)
+    if (
+        value is None
+        or (
+            isinstance(field.field_info, params.Form)
+            and isinstance(value, str)  # For type checks
+            and value == ""
+        )
+        or (is_sequence_field(field) and len(value) == 0)
+    ):
+        if field.required:
+            return
+        else:
+            return deepcopy(field.default)
+    return value
+
+
+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]] = []
+
+    if not fields:
+        return values, errors
+
+    first_field = fields[0]
+    fields_to_extract = fields
+    single_not_embedded_field = False
+    default_convert_underscores = True
+    if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
+        fields_to_extract = get_cached_model_fields(first_field.type_)
+        single_not_embedded_field = True
+        # If headers are in a Pydantic model, the way to disable convert_underscores
+        # would be with Header(convert_underscores=False) at the Pydantic model level
+        default_convert_underscores = getattr(
+            first_field.field_info, "convert_underscores", True
+        )
+
+    params_to_process: Dict[str, Any] = {}
+
+    processed_keys = set()
+
+    for field in fields_to_extract:
+        alias = None
+        if isinstance(received_params, Headers):
+            # Handle fields extracted from a Pydantic Model for a header, each field
+            # doesn't have a FieldInfo of type Header with the default convert_underscores=True
+            convert_underscores = getattr(
+                field.field_info, "convert_underscores", default_convert_underscores
+            )
+            if convert_underscores:
+                alias = (
+                    field.alias
+                    if field.alias != field.name
+                    else field.name.replace("_", "-")
+                )
+        value = _get_multidict_value(field, received_params, alias=alias)
+        if value is not None:
+            params_to_process[field.name] = value
+        processed_keys.add(alias or field.alias)
+        processed_keys.add(field.name)
+
+    for key, value in received_params.items():
+        if key not in processed_keys:
+            params_to_process[key] = value
+
+    if single_not_embedded_field:
+        field_info = first_field.field_info
+        assert isinstance(field_info, params.Param), (
+            "Params must be subclasses of Param"
+        )
+        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 {first_field.name: v_}, errors_
+
+    for field in fields:
+        value = _get_multidict_value(field, received_params)
+        field_info = field.field_info
+        assert isinstance(field_info, params.Param), (
+            "Params must be subclasses of Param"
+        )
+        loc = (field_info.in_.value, field.alias)
+        v_, errors_ = _validate_value_with_model_field(
+            field=field, value=value, values=values, loc=loc
+        )
+        if errors_:
+            errors.extend(errors_)
+        else:
+            values[field.name] = v_
+    return values, errors
+
+
+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
+    # fields but it's the same one, so count them by name
+    body_param_names_set = {field.name for field in fields}
+    # A top level field has to be a single field, not multiple
+    if len(body_param_names_set) > 1:
+        return True
+    first_field = fields[0]
+    # If it explicitly specifies it is embedded, it has to be embedded
+    if getattr(first_field.field_info, "embed", None):
+        return True
+    # If it's a Form (or File) field, it has to be a BaseModel to be top level
+    # otherwise it has to be embedded, so that the key value pair can be extracted
+    if isinstance(first_field.field_info, params.Form) and not lenient_issubclass(
+        first_field.type_, BaseModel
+    ):
+        return True
+    return False
+
+
+async def _extract_form_body(
+    body_fields: List[ModelField],
+    received_body: FormData,
+) -> Dict[str, Any]:
+    values = {}
+    first_field = body_fields[0]
+    first_field_info = first_field.field_info
+
+    for field in body_fields:
+        value = _get_multidict_value(field, received_body)
+        if (
+            isinstance(first_field_info, params.File)
+            and is_bytes_field(field)
+            and isinstance(value, UploadFile)
+        ):
+            value = await value.read()
+        elif (
+            is_bytes_sequence_field(field)
+            and isinstance(first_field_info, params.File)
+            and value_is_sequence(value)
+        ):
+            # For types
+            assert isinstance(value, sequence_types)  # type: ignore[arg-type]
+            results: List[Union[bytes, str]] = []
+
+            async def process_fn(
+                fn: Callable[[], Coroutine[Any, Any, Any]],
+            ) -> None:
+                result = await fn()
+                results.append(result)  # noqa: B023
+
+            async with anyio.create_task_group() as tg:
+                for sub_value in value:
+                    tg.start_soon(process_fn, sub_value.read)
+            value = serialize_sequence_value(field=field, value=results)
+        if value is not None:
+            values[field.alias] = value
+    for key, value in received_body.items():
+        if key not in values:
+            values[key] = value
+    return values
+
+
+async def request_body_to_args(
+    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]] = []
+    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
+
+    if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel):
+        fields_to_extract = get_cached_model_fields(first_field.type_)
+
+    if isinstance(received_body, FormData):
+        body_to_process = await _extract_form_body(fields_to_extract, received_body)
+
+    if single_not_embedded_field:
+        loc: Tuple[str, ...] = ("body",)
+        v_, errors_ = _validate_value_with_model_field(
+            field=first_field, value=body_to_process, values=values, loc=loc
+        )
+        return {first_field.name: v_}, errors_
+    for field in body_fields:
+        loc = ("body", field.alias)
+        value: Optional[Any] = None
+        if body_to_process is not None:
+            try:
+                value = body_to_process.get(field.alias)
+            # If the received body is a list, not a dict
+            except AttributeError:
+                errors.append(get_missing_field_error(loc))
+                continue
+        v_, errors_ = _validate_value_with_model_field(
+            field=field, value=value, values=values, loc=loc
+        )
+        if errors_:
+            errors.extend(errors_)
+        else:
+            values[field.name] = v_
+    return values, errors
+
+
+def get_body_field(
+    *, flat_dependant: Dependant, name: str, embed_body_fields: bool
+) -> Optional[ModelField]:
+    """
+    Get a ModelField representing the request body for a path operation, combining
+    all body parameters into a single field if necessary.
+
+    Used to check if it's form data (with `isinstance(body_field, params.Form)`)
+    or JSON and to generate the JSON Schema for a request body.
+
+    This is **not** used to validate/parse the request body, that's done with each
+    individual body parameter.
+    """
+    if not flat_dependant.body_params:
+        return None
+    first_param = flat_dependant.body_params[0]
+    if not embed_body_fields:
+        return first_param
+    model_name = "Body_" + name
+    BodyModel = create_body_model(
+        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] = {
+        "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
+    elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
+        BodyFieldInfo = params.Form
+    else:
+        BodyFieldInfo = params.Body
+
+        body_param_media_types = [
+            f.field_info.media_type
+            for f in flat_dependant.body_params
+            if isinstance(f.field_info, params.Body)
+        ]
+        if len(set(body_param_media_types)) == 1:
+            BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0]
+    final_field = create_model_field(
+        name="body",
+        type_=BodyModel,
+        required=required,
+        alias="body",
+        field_info=BodyFieldInfo(**BodyFieldInfo_kwargs),
+    )
+    return final_field
diff --git a/.venv/lib/python3.12/site-packages/fastapi/encoders.py b/.venv/lib/python3.12/site-packages/fastapi/encoders.py
new file mode 100644
index 00000000..451ea076
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/encoders.py
@@ -0,0 +1,343 @@
+import dataclasses
+import datetime
+from collections import defaultdict, deque
+from decimal import Decimal
+from enum import Enum
+from ipaddress import (
+    IPv4Address,
+    IPv4Interface,
+    IPv4Network,
+    IPv6Address,
+    IPv6Interface,
+    IPv6Network,
+)
+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 uuid import UUID
+
+from fastapi.types import IncEx
+from pydantic import BaseModel
+from pydantic.color import Color
+from pydantic.networks import AnyUrl, NameEmail
+from pydantic.types import SecretBytes, SecretStr
+from typing_extensions import Annotated, Doc
+
+from ._compat import PYDANTIC_V2, UndefinedType, Url, _model_dump
+
+
+# Taken from Pydantic v1 as is
+def isoformat(o: Union[datetime.date, datetime.time]) -> str:
+    return o.isoformat()
+
+
+# Taken from Pydantic v1 as is
+# TODO: pv2 should this return strings instead?
+def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
+    """
+    Encodes a Decimal as int of there's no exponent, otherwise float
+
+    This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
+    where a integer (but not int typed) is used. Encoding this as a float
+    results in failed round-tripping between encode and parse.
+    Our Id type is a prime example of this.
+
+    >>> decimal_encoder(Decimal("1.0"))
+    1.0
+
+    >>> decimal_encoder(Decimal("1"))
+    1
+    """
+    if dec_value.as_tuple().exponent >= 0:  # type: ignore[operator]
+        return int(dec_value)
+    else:
+        return float(dec_value)
+
+
+ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
+    bytes: lambda o: o.decode(),
+    Color: str,
+    datetime.date: isoformat,
+    datetime.datetime: isoformat,
+    datetime.time: isoformat,
+    datetime.timedelta: lambda td: td.total_seconds(),
+    Decimal: decimal_encoder,
+    Enum: lambda o: o.value,
+    frozenset: list,
+    deque: list,
+    GeneratorType: list,
+    IPv4Address: str,
+    IPv4Interface: str,
+    IPv4Network: str,
+    IPv6Address: str,
+    IPv6Interface: str,
+    IPv6Network: str,
+    NameEmail: str,
+    Path: str,
+    Pattern: lambda o: o.pattern,
+    SecretBytes: str,
+    SecretStr: str,
+    set: list,
+    UUID: str,
+    Url: str,
+    AnyUrl: 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(
+        tuple
+    )
+    for type_, encoder in type_encoder_map.items():
+        encoders_by_class_tuples[encoder] += (type_,)
+    return encoders_by_class_tuples
+
+
+encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
+
+
+def jsonable_encoder(
+    obj: Annotated[
+        Any,
+        Doc(
+            """
+            The input object to convert to JSON.
+            """
+        ),
+    ],
+    include: Annotated[
+        Optional[IncEx],
+        Doc(
+            """
+            Pydantic's `include` parameter, passed to Pydantic models to set the
+            fields to include.
+            """
+        ),
+    ] = None,
+    exclude: Annotated[
+        Optional[IncEx],
+        Doc(
+            """
+            Pydantic's `exclude` parameter, passed to Pydantic models to set the
+            fields to exclude.
+            """
+        ),
+    ] = None,
+    by_alias: Annotated[
+        bool,
+        Doc(
+            """
+            Pydantic's `by_alias` parameter, passed to Pydantic models to define if
+            the output should use the alias names (when provided) or the Python
+            attribute names. In an API, if you set an alias, it's probably because you
+            want to use it in the result, so you probably want to leave this set to
+            `True`.
+            """
+        ),
+    ] = True,
+    exclude_unset: Annotated[
+        bool,
+        Doc(
+            """
+            Pydantic's `exclude_unset` parameter, passed to Pydantic models to define
+            if it should exclude from the output the fields that were not explicitly
+            set (and that only had their default values).
+            """
+        ),
+    ] = False,
+    exclude_defaults: Annotated[
+        bool,
+        Doc(
+            """
+            Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define
+            if it should exclude from the output the fields that had the same default
+            value, even when they were explicitly set.
+            """
+        ),
+    ] = False,
+    exclude_none: Annotated[
+        bool,
+        Doc(
+            """
+            Pydantic's `exclude_none` parameter, passed to Pydantic models to define
+            if it should exclude from the output any fields that have a `None` value.
+            """
+        ),
+    ] = False,
+    custom_encoder: Annotated[
+        Optional[Dict[Any, Callable[[Any], Any]]],
+        Doc(
+            """
+            Pydantic's `custom_encoder` parameter, passed to Pydantic models to define
+            a custom encoder.
+            """
+        ),
+    ] = None,
+    sqlalchemy_safe: Annotated[
+        bool,
+        Doc(
+            """
+            Exclude from the output any fields that start with the name `_sa`.
+
+            This is mainly a hack for compatibility with SQLAlchemy objects, they
+            store internal SQLAlchemy-specific state in attributes named with `_sa`,
+            and those objects can't (and shouldn't be) serialized to JSON.
+            """
+        ),
+    ] = True,
+) -> Any:
+    """
+    Convert any object to something that can be encoded in JSON.
+
+    This is used internally by FastAPI to make sure anything you return can be
+    encoded as JSON before it is sent to the client.
+
+    You can also use it yourself, for example to convert objects before saving them
+    in a database that supports only JSON.
+
+    Read more about it in the
+    [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/).
+    """
+    custom_encoder = custom_encoder or {}
+    if custom_encoder:
+        if type(obj) in custom_encoder:
+            return custom_encoder[type(obj)](obj)
+        else:
+            for encoder_type, encoder_instance in custom_encoder.items():
+                if isinstance(obj, encoder_type):
+                    return encoder_instance(obj)
+    if include is not None and not isinstance(include, (set, dict)):
+        include = set(include)
+    if exclude is not None and not isinstance(exclude, (set, dict)):
+        exclude = set(exclude)
+    if isinstance(obj, BaseModel):
+        # TODO: remove when deprecating Pydantic v1
+        encoders: Dict[Any, Any] = {}
+        if not PYDANTIC_V2:
+            encoders = getattr(obj.__config__, "json_encoders", {})  # type: ignore[attr-defined]
+            if custom_encoder:
+                encoders.update(custom_encoder)
+        obj_dict = _model_dump(
+            obj,
+            mode="json",
+            include=include,
+            exclude=exclude,
+            by_alias=by_alias,
+            exclude_unset=exclude_unset,
+            exclude_none=exclude_none,
+            exclude_defaults=exclude_defaults,
+        )
+        if "__root__" in obj_dict:
+            obj_dict = obj_dict["__root__"]
+        return jsonable_encoder(
+            obj_dict,
+            exclude_none=exclude_none,
+            exclude_defaults=exclude_defaults,
+            # TODO: remove when deprecating Pydantic v1
+            custom_encoder=encoders,
+            sqlalchemy_safe=sqlalchemy_safe,
+        )
+    if dataclasses.is_dataclass(obj):
+        obj_dict = dataclasses.asdict(obj)
+        return jsonable_encoder(
+            obj_dict,
+            include=include,
+            exclude=exclude,
+            by_alias=by_alias,
+            exclude_unset=exclude_unset,
+            exclude_defaults=exclude_defaults,
+            exclude_none=exclude_none,
+            custom_encoder=custom_encoder,
+            sqlalchemy_safe=sqlalchemy_safe,
+        )
+    if isinstance(obj, Enum):
+        return obj.value
+    if isinstance(obj, PurePath):
+        return str(obj)
+    if isinstance(obj, (str, int, float, type(None))):
+        return obj
+    if isinstance(obj, UndefinedType):
+        return None
+    if isinstance(obj, dict):
+        encoded_dict = {}
+        allowed_keys = set(obj.keys())
+        if include is not None:
+            allowed_keys &= set(include)
+        if exclude is not None:
+            allowed_keys -= set(exclude)
+        for key, value in obj.items():
+            if (
+                (
+                    not sqlalchemy_safe
+                    or (not isinstance(key, str))
+                    or (not key.startswith("_sa"))
+                )
+                and (value is not None or not exclude_none)
+                and key in allowed_keys
+            ):
+                encoded_key = jsonable_encoder(
+                    key,
+                    by_alias=by_alias,
+                    exclude_unset=exclude_unset,
+                    exclude_none=exclude_none,
+                    custom_encoder=custom_encoder,
+                    sqlalchemy_safe=sqlalchemy_safe,
+                )
+                encoded_value = jsonable_encoder(
+                    value,
+                    by_alias=by_alias,
+                    exclude_unset=exclude_unset,
+                    exclude_none=exclude_none,
+                    custom_encoder=custom_encoder,
+                    sqlalchemy_safe=sqlalchemy_safe,
+                )
+                encoded_dict[encoded_key] = encoded_value
+        return encoded_dict
+    if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
+        encoded_list = []
+        for item in obj:
+            encoded_list.append(
+                jsonable_encoder(
+                    item,
+                    include=include,
+                    exclude=exclude,
+                    by_alias=by_alias,
+                    exclude_unset=exclude_unset,
+                    exclude_defaults=exclude_defaults,
+                    exclude_none=exclude_none,
+                    custom_encoder=custom_encoder,
+                    sqlalchemy_safe=sqlalchemy_safe,
+                )
+            )
+        return encoded_list
+
+    if type(obj) in ENCODERS_BY_TYPE:
+        return ENCODERS_BY_TYPE[type(obj)](obj)
+    for encoder, classes_tuple in encoders_by_class_tuples.items():
+        if isinstance(obj, classes_tuple):
+            return encoder(obj)
+
+    try:
+        data = dict(obj)
+    except Exception as e:
+        errors: List[Exception] = []
+        errors.append(e)
+        try:
+            data = vars(obj)
+        except Exception as e:
+            errors.append(e)
+            raise ValueError(errors) from e
+    return jsonable_encoder(
+        data,
+        include=include,
+        exclude=exclude,
+        by_alias=by_alias,
+        exclude_unset=exclude_unset,
+        exclude_defaults=exclude_defaults,
+        exclude_none=exclude_none,
+        custom_encoder=custom_encoder,
+        sqlalchemy_safe=sqlalchemy_safe,
+    )
diff --git a/.venv/lib/python3.12/site-packages/fastapi/exception_handlers.py b/.venv/lib/python3.12/site-packages/fastapi/exception_handlers.py
new file mode 100644
index 00000000..6c2ba7fe
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/exception_handlers.py
@@ -0,0 +1,34 @@
+from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
+from fastapi.utils import is_body_allowed_for_status_code
+from fastapi.websockets import WebSocket
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.responses import JSONResponse, Response
+from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION
+
+
+async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
+    headers = getattr(exc, "headers", None)
+    if not is_body_allowed_for_status_code(exc.status_code):
+        return Response(status_code=exc.status_code, headers=headers)
+    return JSONResponse(
+        {"detail": exc.detail}, status_code=exc.status_code, headers=headers
+    )
+
+
+async def request_validation_exception_handler(
+    request: Request, exc: RequestValidationError
+) -> JSONResponse:
+    return JSONResponse(
+        status_code=HTTP_422_UNPROCESSABLE_ENTITY,
+        content={"detail": jsonable_encoder(exc.errors())},
+    )
+
+
+async def websocket_request_validation_exception_handler(
+    websocket: WebSocket, exc: WebSocketRequestValidationError
+) -> None:
+    await websocket.close(
+        code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
+    )
diff --git a/.venv/lib/python3.12/site-packages/fastapi/exceptions.py b/.venv/lib/python3.12/site-packages/fastapi/exceptions.py
new file mode 100644
index 00000000..44d4ada8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/exceptions.py
@@ -0,0 +1,176 @@
+from typing import Any, Dict, Optional, Sequence, Type, Union
+
+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, Doc
+
+
+class HTTPException(StarletteHTTPException):
+    """
+    An HTTP exception you can raise in your own code to show errors to the client.
+
+    This is for client errors, invalid authentication, invalid data, etc. Not for server
+    errors in your code.
+
+    Read more about it in the
+    [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+    ## Example
+
+    ```python
+    from fastapi import FastAPI, HTTPException
+
+    app = FastAPI()
+
+    items = {"foo": "The Foo Wrestlers"}
+
+
+    @app.get("/items/{item_id}")
+    async def read_item(item_id: str):
+        if item_id not in items:
+            raise HTTPException(status_code=404, detail="Item not found")
+        return {"item": items[item_id]}
+    ```
+    """
+
+    def __init__(
+        self,
+        status_code: Annotated[
+            int,
+            Doc(
+                """
+                HTTP status code to send to the client.
+                """
+            ),
+        ],
+        detail: Annotated[
+            Any,
+            Doc(
+                """
+                Any data to be sent to the client in the `detail` key of the JSON
+                response.
+                """
+            ),
+        ] = None,
+        headers: Annotated[
+            Optional[Dict[str, str]],
+            Doc(
+                """
+                Any headers to send to the client in the response.
+                """
+            ),
+        ] = None,
+    ) -> None:
+        super().__init__(status_code=status_code, detail=detail, headers=headers)
+
+
+class WebSocketException(StarletteWebSocketException):
+    """
+    A WebSocket exception you can raise in your own code to show errors to the client.
+
+    This is for client errors, invalid authentication, invalid data, etc. Not for server
+    errors in your code.
+
+    Read more about it in the
+    [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import (
+        Cookie,
+        FastAPI,
+        WebSocket,
+        WebSocketException,
+        status,
+    )
+
+    app = FastAPI()
+
+    @app.websocket("/items/{item_id}/ws")
+    async def websocket_endpoint(
+        *,
+        websocket: WebSocket,
+        session: Annotated[str | None, Cookie()] = None,
+        item_id: str,
+    ):
+        if session is None:
+            raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
+        await websocket.accept()
+        while True:
+            data = await websocket.receive_text()
+            await websocket.send_text(f"Session cookie is: {session}")
+            await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
+    ```
+    """
+
+    def __init__(
+        self,
+        code: Annotated[
+            int,
+            Doc(
+                """
+                A closing code from the
+                [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1).
+                """
+            ),
+        ],
+        reason: Annotated[
+            Union[str, None],
+            Doc(
+                """
+                The reason to close the WebSocket connection.
+
+                It is UTF-8-encoded data. The interpretation of the reason is up to the
+                application, it is not specified by the WebSocket specification.
+
+                It could contain text that could be human-readable or interpretable
+                by the client code, etc.
+                """
+            ),
+        ] = None,
+    ) -> None:
+        super().__init__(code=code, reason=reason)
+
+
+RequestErrorModel: Type[BaseModel] = create_model("Request")
+WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
+
+
+class FastAPIError(RuntimeError):
+    """
+    A generic, FastAPI-specific error.
+    """
+
+
+class ValidationException(Exception):
+    def __init__(self, errors: Sequence[Any]) -> None:
+        self._errors = errors
+
+    def errors(self) -> Sequence[Any]:
+        return self._errors
+
+
+class RequestValidationError(ValidationException):
+    def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
+        super().__init__(errors)
+        self.body = body
+
+
+class WebSocketRequestValidationError(ValidationException):
+    pass
+
+
+class ResponseValidationError(ValidationException):
+    def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
+        super().__init__(errors)
+        self.body = body
+
+    def __str__(self) -> str:
+        message = f"{len(self._errors)} validation errors:\n"
+        for err in self._errors:
+            message += f"  {err}\n"
+        return message
diff --git a/.venv/lib/python3.12/site-packages/fastapi/logger.py b/.venv/lib/python3.12/site-packages/fastapi/logger.py
new file mode 100644
index 00000000..5b2c4ad5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/logger.py
@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger("fastapi")
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/__init__.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/__init__.py
new file mode 100644
index 00000000..620296d5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/__init__.py
@@ -0,0 +1 @@
+from starlette.middleware import Middleware as Middleware
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/cors.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/cors.py
new file mode 100644
index 00000000..8dfaad0d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/cors.py
@@ -0,0 +1 @@
+from starlette.middleware.cors import CORSMiddleware as CORSMiddleware  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/gzip.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/gzip.py
new file mode 100644
index 00000000..bbeb2cc7
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/gzip.py
@@ -0,0 +1 @@
+from starlette.middleware.gzip import GZipMiddleware as GZipMiddleware  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py
new file mode 100644
index 00000000..b7a3d8e0
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py
@@ -0,0 +1,3 @@
+from starlette.middleware.httpsredirect import (  # noqa
+    HTTPSRedirectMiddleware as HTTPSRedirectMiddleware,
+)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/trustedhost.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/trustedhost.py
new file mode 100644
index 00000000..08d7e035
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/trustedhost.py
@@ -0,0 +1,3 @@
+from starlette.middleware.trustedhost import (  # noqa
+    TrustedHostMiddleware as TrustedHostMiddleware,
+)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/middleware/wsgi.py b/.venv/lib/python3.12/site-packages/fastapi/middleware/wsgi.py
new file mode 100644
index 00000000..c4c6a797
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/middleware/wsgi.py
@@ -0,0 +1 @@
+from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/openapi/__init__.py b/.venv/lib/python3.12/site-packages/fastapi/openapi/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/openapi/__init__.py
diff --git a/.venv/lib/python3.12/site-packages/fastapi/openapi/constants.py b/.venv/lib/python3.12/site-packages/fastapi/openapi/constants.py
new file mode 100644
index 00000000..d724ee3c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/openapi/constants.py
@@ -0,0 +1,3 @@
+METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}
+REF_PREFIX = "#/components/schemas/"
+REF_TEMPLATE = "#/components/schemas/{model}"
diff --git a/.venv/lib/python3.12/site-packages/fastapi/openapi/docs.py b/.venv/lib/python3.12/site-packages/fastapi/openapi/docs.py
new file mode 100644
index 00000000..c2ec358d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/openapi/docs.py
@@ -0,0 +1,344 @@
+import json
+from typing import Any, Dict, Optional
+
+from fastapi.encoders import jsonable_encoder
+from starlette.responses import HTMLResponse
+from typing_extensions import Annotated, Doc
+
+swagger_ui_default_parameters: Annotated[
+    Dict[str, Any],
+    Doc(
+        """
+        Default configurations for Swagger UI.
+
+        You can use it as a template to add any other configurations needed.
+        """
+    ),
+] = {
+    "dom_id": "#swagger-ui",
+    "layout": "BaseLayout",
+    "deepLinking": True,
+    "showExtensions": True,
+    "showCommonExtensions": True,
+}
+
+
+def get_swagger_ui_html(
+    *,
+    openapi_url: Annotated[
+        str,
+        Doc(
+            """
+            The OpenAPI URL that Swagger UI should load and use.
+
+            This is normally done automatically by FastAPI using the default URL
+            `/openapi.json`.
+            """
+        ),
+    ],
+    title: Annotated[
+        str,
+        Doc(
+            """
+            The HTML `<title>` content, normally shown in the browser tab.
+            """
+        ),
+    ],
+    swagger_js_url: Annotated[
+        str,
+        Doc(
+            """
+            The URL to use to load the Swagger UI JavaScript.
+
+            It is normally set to a CDN URL.
+            """
+        ),
+    ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
+    swagger_css_url: Annotated[
+        str,
+        Doc(
+            """
+            The URL to use to load the Swagger UI CSS.
+
+            It is normally set to a CDN URL.
+            """
+        ),
+    ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
+    swagger_favicon_url: Annotated[
+        str,
+        Doc(
+            """
+            The URL of the favicon to use. It is normally shown in the browser tab.
+            """
+        ),
+    ] = "https://fastapi.tiangolo.com/img/favicon.png",
+    oauth2_redirect_url: Annotated[
+        Optional[str],
+        Doc(
+            """
+            The OAuth2 redirect URL, it is normally automatically handled by FastAPI.
+            """
+        ),
+    ] = None,
+    init_oauth: Annotated[
+        Optional[Dict[str, Any]],
+        Doc(
+            """
+            A dictionary with Swagger UI OAuth2 initialization configurations.
+            """
+        ),
+    ] = None,
+    swagger_ui_parameters: Annotated[
+        Optional[Dict[str, Any]],
+        Doc(
+            """
+            Configuration parameters for Swagger UI.
+
+            It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters].
+            """
+        ),
+    ] = None,
+) -> HTMLResponse:
+    """
+    Generate and return the HTML  that loads Swagger UI for the interactive
+    API docs (normally served at `/docs`).
+
+    You would only call this function yourself if you needed to override some parts,
+    for example the URLs to use to load Swagger UI's JavaScript and CSS.
+
+    Read more about it in the
+    [FastAPI docs for Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/)
+    and the [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+    """
+    current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
+    if swagger_ui_parameters:
+        current_swagger_ui_parameters.update(swagger_ui_parameters)
+
+    html = f"""
+    <!DOCTYPE html>
+    <html>
+    <head>
+    <link type="text/css" rel="stylesheet" href="{swagger_css_url}">
+    <link rel="shortcut icon" href="{swagger_favicon_url}">
+    <title>{title}</title>
+    </head>
+    <body>
+    <div id="swagger-ui">
+    </div>
+    <script src="{swagger_js_url}"></script>
+    <!-- `SwaggerUIBundle` is now available on the page -->
+    <script>
+    const ui = SwaggerUIBundle({{
+        url: '{openapi_url}',
+    """
+
+    for key, value in current_swagger_ui_parameters.items():
+        html += f"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\n"
+
+    if oauth2_redirect_url:
+        html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
+
+    html += """
+    presets: [
+        SwaggerUIBundle.presets.apis,
+        SwaggerUIBundle.SwaggerUIStandalonePreset
+        ],
+    })"""
+
+    if init_oauth:
+        html += f"""
+        ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})
+        """
+
+    html += """
+    </script>
+    </body>
+    </html>
+    """
+    return HTMLResponse(html)
+
+
+def get_redoc_html(
+    *,
+    openapi_url: Annotated[
+        str,
+        Doc(
+            """
+            The OpenAPI URL that ReDoc should load and use.
+
+            This is normally done automatically by FastAPI using the default URL
+            `/openapi.json`.
+            """
+        ),
+    ],
+    title: Annotated[
+        str,
+        Doc(
+            """
+            The HTML `<title>` content, normally shown in the browser tab.
+            """
+        ),
+    ],
+    redoc_js_url: Annotated[
+        str,
+        Doc(
+            """
+            The URL to use to load the ReDoc JavaScript.
+
+            It is normally set to a CDN URL.
+            """
+        ),
+    ] = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js",
+    redoc_favicon_url: Annotated[
+        str,
+        Doc(
+            """
+            The URL of the favicon to use. It is normally shown in the browser tab.
+            """
+        ),
+    ] = "https://fastapi.tiangolo.com/img/favicon.png",
+    with_google_fonts: Annotated[
+        bool,
+        Doc(
+            """
+            Load and use Google Fonts.
+            """
+        ),
+    ] = True,
+) -> HTMLResponse:
+    """
+    Generate and return the HTML response that loads ReDoc for the alternative
+    API docs (normally served at `/redoc`).
+
+    You would only call this function yourself if you needed to override some parts,
+    for example the URLs to use to load ReDoc's JavaScript and CSS.
+
+    Read more about it in the
+    [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+    """
+    html = f"""
+    <!DOCTYPE html>
+    <html>
+    <head>
+    <title>{title}</title>
+    <!-- needed for adaptive design -->
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    """
+    if with_google_fonts:
+        html += """
+    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
+    """
+    html += f"""
+    <link rel="shortcut icon" href="{redoc_favicon_url}">
+    <!--
+    ReDoc doesn't change outer page styles
+    -->
+    <style>
+      body {{
+        margin: 0;
+        padding: 0;
+      }}
+    </style>
+    </head>
+    <body>
+    <noscript>
+        ReDoc requires Javascript to function. Please enable it to browse the documentation.
+    </noscript>
+    <redoc spec-url="{openapi_url}"></redoc>
+    <script src="{redoc_js_url}"> </script>
+    </body>
+    </html>
+    """
+    return HTMLResponse(html)
+
+
+def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
+    """
+    Generate the HTML response with the OAuth2 redirection for Swagger UI.
+
+    You normally don't need to use or change this.
+    """
+    # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
+    html = """
+    <!doctype html>
+    <html lang="en-US">
+    <head>
+        <title>Swagger UI: OAuth2 Redirect</title>
+    </head>
+    <body>
+    <script>
+        'use strict';
+        function run () {
+            var oauth2 = window.opener.swaggerUIRedirectOauth2;
+            var sentState = oauth2.state;
+            var redirectUrl = oauth2.redirectUrl;
+            var isValid, qp, arr;
+
+            if (/code|token|error/.test(window.location.hash)) {
+                qp = window.location.hash.substring(1).replace('?', '&');
+            } else {
+                qp = location.search.substring(1);
+            }
+
+            arr = qp.split("&");
+            arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
+            qp = qp ? JSON.parse('{' + arr.join() + '}',
+                    function (key, value) {
+                        return key === "" ? value : decodeURIComponent(value);
+                    }
+            ) : {};
+
+            isValid = qp.state === sentState;
+
+            if ((
+              oauth2.auth.schema.get("flow") === "accessCode" ||
+              oauth2.auth.schema.get("flow") === "authorizationCode" ||
+              oauth2.auth.schema.get("flow") === "authorization_code"
+            ) && !oauth2.auth.code) {
+                if (!isValid) {
+                    oauth2.errCb({
+                        authId: oauth2.auth.name,
+                        source: "auth",
+                        level: "warning",
+                        message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
+                    });
+                }
+
+                if (qp.code) {
+                    delete oauth2.state;
+                    oauth2.auth.code = qp.code;
+                    oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
+                } else {
+                    let oauthErrorMsg;
+                    if (qp.error) {
+                        oauthErrorMsg = "["+qp.error+"]: " +
+                            (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
+                            (qp.error_uri ? "More info: "+qp.error_uri : "");
+                    }
+
+                    oauth2.errCb({
+                        authId: oauth2.auth.name,
+                        source: "auth",
+                        level: "error",
+                        message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
+                    });
+                }
+            } else {
+                oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
+            }
+            window.close();
+        }
+
+        if (document.readyState !== 'loading') {
+            run();
+        } else {
+            document.addEventListener('DOMContentLoaded', function () {
+                run();
+            });
+        }
+    </script>
+    </body>
+    </html>
+        """
+    return HTMLResponse(content=html)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/openapi/models.py b/.venv/lib/python3.12/site-packages/fastapi/openapi/models.py
new file mode 100644
index 00000000..ed07b40f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/openapi/models.py
@@ -0,0 +1,445 @@
+from enum import Enum
+from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union
+
+from fastapi._compat import (
+    PYDANTIC_V2,
+    CoreSchema,
+    GetJsonSchemaHandler,
+    JsonSchemaValue,
+    _model_rebuild,
+    with_info_plain_validator_function,
+)
+from fastapi.logger import logger
+from pydantic import AnyUrl, BaseModel, Field
+from typing_extensions import Annotated, Literal, TypedDict
+from typing_extensions import deprecated as typing_deprecated
+
+try:
+    import email_validator
+
+    assert email_validator  # make autoflake ignore the unused import
+    from pydantic import EmailStr
+except ImportError:  # pragma: no cover
+
+    class EmailStr(str):  # type: ignore
+        @classmethod
+        def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
+            yield cls.validate
+
+        @classmethod
+        def validate(cls, v: Any) -> str:
+            logger.warning(
+                "email-validator not installed, email fields will be treated as str.\n"
+                "To install, run: pip install email-validator"
+            )
+            return str(v)
+
+        @classmethod
+        def _validate(cls, __input_value: Any, _: Any) -> str:
+            logger.warning(
+                "email-validator not installed, email fields will be treated as str.\n"
+                "To install, run: pip install email-validator"
+            )
+            return str(__input_value)
+
+        @classmethod
+        def __get_pydantic_json_schema__(
+            cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
+        ) -> JsonSchemaValue:
+            return {"type": "string", "format": "email"}
+
+        @classmethod
+        def __get_pydantic_core_schema__(
+            cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+        ) -> CoreSchema:
+            return with_info_plain_validator_function(cls._validate)
+
+
+class BaseModelWithConfig(BaseModel):
+    if PYDANTIC_V2:
+        model_config = {"extra": "allow"}
+
+    else:
+
+        class Config:
+            extra = "allow"
+
+
+class Contact(BaseModelWithConfig):
+    name: Optional[str] = None
+    url: Optional[AnyUrl] = None
+    email: Optional[EmailStr] = None
+
+
+class License(BaseModelWithConfig):
+    name: str
+    identifier: Optional[str] = None
+    url: Optional[AnyUrl] = None
+
+
+class Info(BaseModelWithConfig):
+    title: str
+    summary: Optional[str] = None
+    description: Optional[str] = None
+    termsOfService: Optional[str] = None
+    contact: Optional[Contact] = None
+    license: Optional[License] = None
+    version: str
+
+
+class ServerVariable(BaseModelWithConfig):
+    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
+
+
+class Reference(BaseModel):
+    ref: str = Field(alias="$ref")
+
+
+class Discriminator(BaseModel):
+    propertyName: str
+    mapping: Optional[Dict[str, str]] = None
+
+
+class XML(BaseModelWithConfig):
+    name: Optional[str] = None
+    namespace: Optional[str] = None
+    prefix: Optional[str] = None
+    attribute: Optional[bool] = None
+    wrapped: Optional[bool] = None
+
+
+class ExternalDocumentation(BaseModelWithConfig):
+    description: Optional[str] = None
+    url: AnyUrl
+
+
+class Schema(BaseModelWithConfig):
+    # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-json-schema-core-vocabu
+    # Core Vocabulary
+    schema_: Optional[str] = Field(default=None, alias="$schema")
+    vocabulary: Optional[str] = Field(default=None, alias="$vocabulary")
+    id: Optional[str] = Field(default=None, alias="$id")
+    anchor: Optional[str] = Field(default=None, alias="$anchor")
+    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")
+    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
+    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
+    # TODO: uncomment and remove below when deprecating Pydantic v1
+    # It generales a list of schemas for tuples, before prefixItems was available
+    # items: Optional["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
+    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[str] = None
+    enum: Optional[List[Any]] = None
+    const: Optional[Any] = None
+    multipleOf: Optional[float] = Field(default=None, gt=0)
+    maximum: Optional[float] = None
+    exclusiveMaximum: Optional[float] = None
+    minimum: Optional[float] = None
+    exclusiveMinimum: Optional[float] = None
+    maxLength: Optional[int] = Field(default=None, ge=0)
+    minLength: Optional[int] = Field(default=None, ge=0)
+    pattern: Optional[str] = None
+    maxItems: Optional[int] = Field(default=None, ge=0)
+    minItems: Optional[int] = Field(default=None, ge=0)
+    uniqueItems: Optional[bool] = None
+    maxContains: Optional[int] = Field(default=None, ge=0)
+    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
+    # 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
+    # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-the-conten
+    # A Vocabulary for the Contents of String-Encoded Data
+    contentEncoding: Optional[str] = None
+    contentMediaType: Optional[str] = None
+    contentSchema: Optional["SchemaOrBool"] = None
+    # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-basic-meta
+    # A Vocabulary for Basic Meta-Data Annotations
+    title: Optional[str] = None
+    description: Optional[str] = None
+    default: Optional[Any] = None
+    deprecated: Optional[bool] = None
+    readOnly: Optional[bool] = None
+    writeOnly: Optional[bool] = 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
+    xml: Optional[XML] = None
+    externalDocs: Optional[ExternalDocumentation] = None
+    example: Annotated[
+        Optional[Any],
+        typing_deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = None
+
+
+# Ref: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-documents
+# A JSON Schema MUST be an object or a boolean.
+SchemaOrBool = Union[Schema, bool]
+
+
+class Example(TypedDict, total=False):
+    summary: Optional[str]
+    description: Optional[str]
+    value: Optional[Any]
+    externalValue: Optional[AnyUrl]
+
+    if PYDANTIC_V2:  # type: ignore [misc]
+        __pydantic_config__ = {"extra": "allow"}
+
+    else:
+
+        class Config:
+            extra = "allow"
+
+
+class ParameterInType(Enum):
+    query = "query"
+    header = "header"
+    path = "path"
+    cookie = "cookie"
+
+
+class Encoding(BaseModelWithConfig):
+    contentType: Optional[str] = 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
+
+
+class ParameterBase(BaseModelWithConfig):
+    description: Optional[str] = None
+    required: Optional[bool] = None
+    deprecated: Optional[bool] = None
+    # Serialization rules for simple scenarios
+    style: Optional[str] = None
+    explode: Optional[bool] = None
+    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
+    # Serialization rules for more complex scenarios
+    content: Optional[Dict[str, MediaType]] = None
+
+
+class Parameter(ParameterBase):
+    name: str
+    in_: ParameterInType = Field(alias="in")
+
+
+class Header(ParameterBase):
+    pass
+
+
+class RequestBody(BaseModelWithConfig):
+    description: Optional[str] = None
+    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
+    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
+
+
+class Operation(BaseModelWithConfig):
+    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
+    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
+    deprecated: Optional[bool] = None
+    security: Optional[List[Dict[str, List[str]]]] = None
+    servers: Optional[List[Server]] = None
+
+
+class PathItem(BaseModelWithConfig):
+    ref: Optional[str] = Field(default=None, alias="$ref")
+    summary: Optional[str] = None
+    description: Optional[str] = None
+    get: Optional[Operation] = None
+    put: Optional[Operation] = None
+    post: Optional[Operation] = None
+    delete: Optional[Operation] = None
+    options: Optional[Operation] = None
+    head: Optional[Operation] = None
+    patch: Optional[Operation] = None
+    trace: Optional[Operation] = None
+    servers: Optional[List[Server]] = None
+    parameters: Optional[List[Union[Parameter, Reference]]] = None
+
+
+class SecuritySchemeType(Enum):
+    apiKey = "apiKey"
+    http = "http"
+    oauth2 = "oauth2"
+    openIdConnect = "openIdConnect"
+
+
+class SecurityBase(BaseModelWithConfig):
+    type_: SecuritySchemeType = Field(alias="type")
+    description: Optional[str] = None
+
+
+class APIKeyIn(Enum):
+    query = "query"
+    header = "header"
+    cookie = "cookie"
+
+
+class APIKey(SecurityBase):
+    type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type")
+    in_: APIKeyIn = Field(alias="in")
+    name: str
+
+
+class HTTPBase(SecurityBase):
+    type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type")
+    scheme: str
+
+
+class HTTPBearer(HTTPBase):
+    scheme: Literal["bearer"] = "bearer"
+    bearerFormat: Optional[str] = None
+
+
+class OAuthFlow(BaseModelWithConfig):
+    refreshUrl: Optional[str] = None
+    scopes: Dict[str, str] = {}
+
+
+class OAuthFlowImplicit(OAuthFlow):
+    authorizationUrl: str
+
+
+class OAuthFlowPassword(OAuthFlow):
+    tokenUrl: str
+
+
+class OAuthFlowClientCredentials(OAuthFlow):
+    tokenUrl: str
+
+
+class OAuthFlowAuthorizationCode(OAuthFlow):
+    authorizationUrl: str
+    tokenUrl: str
+
+
+class OAuthFlows(BaseModelWithConfig):
+    implicit: Optional[OAuthFlowImplicit] = None
+    password: Optional[OAuthFlowPassword] = None
+    clientCredentials: Optional[OAuthFlowClientCredentials] = None
+    authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
+
+
+class OAuth2(SecurityBase):
+    type_: SecuritySchemeType = Field(default=SecuritySchemeType.oauth2, alias="type")
+    flows: OAuthFlows
+
+
+class OpenIdConnect(SecurityBase):
+    type_: SecuritySchemeType = Field(
+        default=SecuritySchemeType.openIdConnect, alias="type"
+    )
+    openIdConnectUrl: str
+
+
+SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer]
+
+
+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
+    # Using Any for Specification Extensions
+    callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
+    pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
+
+
+class Tag(BaseModelWithConfig):
+    name: str
+    description: Optional[str] = None
+    externalDocs: Optional[ExternalDocumentation] = None
+
+
+class OpenAPI(BaseModelWithConfig):
+    openapi: str
+    info: Info
+    jsonSchemaDialect: Optional[str] = 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
+    components: Optional[Components] = None
+    security: Optional[List[Dict[str, List[str]]]] = None
+    tags: Optional[List[Tag]] = None
+    externalDocs: Optional[ExternalDocumentation] = None
+
+
+_model_rebuild(Schema)
+_model_rebuild(Operation)
+_model_rebuild(Encoding)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/openapi/utils.py b/.venv/lib/python3.12/site-packages/fastapi/openapi/utils.py
new file mode 100644
index 00000000..808646cc
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/openapi/utils.py
@@ -0,0 +1,569 @@
+import http.client
+import inspect
+import warnings
+from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast
+
+from fastapi import routing
+from fastapi._compat import (
+    GenerateJsonSchema,
+    JsonSchemaValue,
+    ModelField,
+    Undefined,
+    get_compat_model_name_map,
+    get_definitions,
+    get_schema_from_model_field,
+    lenient_issubclass,
+)
+from fastapi.datastructures import DefaultPlaceholder
+from fastapi.dependencies.models import Dependant
+from fastapi.dependencies.utils import (
+    _get_flat_fields_from_params,
+    get_flat_dependant,
+    get_flat_params,
+)
+from fastapi.encoders import jsonable_encoder
+from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
+from fastapi.openapi.models import OpenAPI
+from fastapi.params import Body, ParamTypes
+from fastapi.responses import Response
+from fastapi.types import ModelNameMap
+from fastapi.utils import (
+    deep_dict_update,
+    generate_operation_id_for_path,
+    is_body_allowed_for_status_code,
+)
+from pydantic import BaseModel
+from starlette.responses import JSONResponse
+from starlette.routing import BaseRoute
+from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
+from typing_extensions import Literal
+
+validation_error_definition = {
+    "title": "ValidationError",
+    "type": "object",
+    "properties": {
+        "loc": {
+            "title": "Location",
+            "type": "array",
+            "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
+        },
+        "msg": {"title": "Message", "type": "string"},
+        "type": {"title": "Error Type", "type": "string"},
+    },
+    "required": ["loc", "msg", "type"],
+}
+
+validation_error_response_definition = {
+    "title": "HTTPValidationError",
+    "type": "object",
+    "properties": {
+        "detail": {
+            "title": "Detail",
+            "type": "array",
+            "items": {"$ref": REF_PREFIX + "ValidationError"},
+        }
+    },
+}
+
+status_code_ranges: Dict[str, str] = {
+    "1XX": "Information",
+    "2XX": "Success",
+    "3XX": "Redirection",
+    "4XX": "Client Error",
+    "5XX": "Server Error",
+    "DEFAULT": "Default Response",
+}
+
+
+def get_openapi_security_definitions(
+    flat_dependant: Dependant,
+) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+    security_definitions = {}
+    operation_security = []
+    for security_requirement in flat_dependant.security_requirements:
+        security_definition = jsonable_encoder(
+            security_requirement.security_scheme.model,
+            by_alias=True,
+            exclude_none=True,
+        )
+        security_name = security_requirement.security_scheme.scheme_name
+        security_definitions[security_name] = security_definition
+        operation_security.append({security_name: security_requirement.scopes})
+    return security_definitions, operation_security
+
+
+def _get_openapi_operation_parameters(
+    *,
+    dependant: Dependant,
+    schema_generator: GenerateJsonSchema,
+    model_name_map: ModelNameMap,
+    field_mapping: Dict[
+        Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+    ],
+    separate_input_output_schemas: bool = True,
+) -> 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)
+    query_params = _get_flat_fields_from_params(flat_dependant.query_params)
+    header_params = _get_flat_fields_from_params(flat_dependant.header_params)
+    cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
+    parameter_groups = [
+        (ParamTypes.path, path_params),
+        (ParamTypes.query, query_params),
+        (ParamTypes.header, header_params),
+        (ParamTypes.cookie, cookie_params),
+    ]
+    default_convert_underscores = True
+    if len(flat_dependant.header_params) == 1:
+        first_field = flat_dependant.header_params[0]
+        if lenient_issubclass(first_field.type_, BaseModel):
+            default_convert_underscores = getattr(
+                first_field.field_info, "convert_underscores", True
+            )
+    for param_type, param_group in parameter_groups:
+        for param in param_group:
+            field_info = param.field_info
+            # field_info = cast(Param, field_info)
+            if not getattr(field_info, "include_in_schema", True):
+                continue
+            param_schema = get_schema_from_model_field(
+                field=param,
+                schema_generator=schema_generator,
+                model_name_map=model_name_map,
+                field_mapping=field_mapping,
+                separate_input_output_schemas=separate_input_output_schemas,
+            )
+            name = param.alias
+            convert_underscores = getattr(
+                param.field_info,
+                "convert_underscores",
+                default_convert_underscores,
+            )
+            if (
+                param_type == ParamTypes.header
+                and param.alias == param.name
+                and convert_underscores
+            ):
+                name = param.name.replace("_", "-")
+
+            parameter = {
+                "name": name,
+                "in": param_type.value,
+                "required": param.required,
+                "schema": param_schema,
+            }
+            if field_info.description:
+                parameter["description"] = field_info.description
+            openapi_examples = getattr(field_info, "openapi_examples", None)
+            example = getattr(field_info, "example", None)
+            if openapi_examples:
+                parameter["examples"] = jsonable_encoder(openapi_examples)
+            elif example != Undefined:
+                parameter["example"] = jsonable_encoder(example)
+            if getattr(field_info, "deprecated", None):
+                parameter["deprecated"] = True
+            parameters.append(parameter)
+    return parameters
+
+
+def get_openapi_operation_request_body(
+    *,
+    body_field: Optional[ModelField],
+    schema_generator: GenerateJsonSchema,
+    model_name_map: ModelNameMap,
+    field_mapping: Dict[
+        Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+    ],
+    separate_input_output_schemas: bool = True,
+) -> Optional[Dict[str, Any]]:
+    if not body_field:
+        return None
+    assert isinstance(body_field, ModelField)
+    body_schema = get_schema_from_model_field(
+        field=body_field,
+        schema_generator=schema_generator,
+        model_name_map=model_name_map,
+        field_mapping=field_mapping,
+        separate_input_output_schemas=separate_input_output_schemas,
+    )
+    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] = {}
+    if required:
+        request_body_oai["required"] = required
+    request_media_content: Dict[str, Any] = {"schema": body_schema}
+    if field_info.openapi_examples:
+        request_media_content["examples"] = jsonable_encoder(
+            field_info.openapi_examples
+        )
+    elif field_info.example != Undefined:
+        request_media_content["example"] = jsonable_encoder(field_info.example)
+    request_body_oai["content"] = {request_media_type: request_media_content}
+    return request_body_oai
+
+
+def generate_operation_id(
+    *, route: routing.APIRoute, method: str
+) -> str:  # pragma: nocover
+    warnings.warn(
+        "fastapi.openapi.utils.generate_operation_id() was deprecated, "
+        "it is not used internally, and will be removed soon",
+        DeprecationWarning,
+        stacklevel=2,
+    )
+    if route.operation_id:
+        return route.operation_id
+    path: str = route.path_format
+    return generate_operation_id_for_path(name=route.name, path=path, method=method)
+
+
+def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str:
+    if route.summary:
+        return route.summary
+    return route.name.replace("_", " ").title()
+
+
+def get_openapi_operation_metadata(
+    *, 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)
+    if route.description:
+        operation["description"] = route.description
+    operation_id = route.operation_id or route.unique_id
+    if operation_id in operation_ids:
+        message = (
+            f"Duplicate Operation ID {operation_id} for function "
+            + f"{route.endpoint.__name__}"
+        )
+        file_name = getattr(route.endpoint, "__globals__", {}).get("__file__")
+        if file_name:
+            message += f" at {file_name}"
+        warnings.warn(message, stacklevel=1)
+    operation_ids.add(operation_id)
+    operation["operationId"] = operation_id
+    if route.deprecated:
+        operation["deprecated"] = route.deprecated
+    return operation
+
+
+def get_openapi_path(
+    *,
+    route: routing.APIRoute,
+    operation_ids: Set[str],
+    schema_generator: GenerateJsonSchema,
+    model_name_map: ModelNameMap,
+    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]]:
+    path = {}
+    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
+    else:
+        current_response_class = route.response_class
+    assert current_response_class, "A response class is needed to generate OpenAPI"
+    route_response_media_type: Optional[str] = current_response_class.media_type
+    if route.include_in_schema:
+        for method in route.methods:
+            operation = get_openapi_operation_metadata(
+                route=route, method=method, operation_ids=operation_ids
+            )
+            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
+            )
+            if operation_security:
+                operation.setdefault("security", []).extend(operation_security)
+            if security_definitions:
+                security_schemes.update(security_definitions)
+            operation_parameters = _get_openapi_operation_parameters(
+                dependant=route.dependant,
+                schema_generator=schema_generator,
+                model_name_map=model_name_map,
+                field_mapping=field_mapping,
+                separate_input_output_schemas=separate_input_output_schemas,
+            )
+            parameters.extend(operation_parameters)
+            if parameters:
+                all_parameters = {
+                    (param["in"], param["name"]): param for param in parameters
+                }
+                required_parameters = {
+                    (param["in"], param["name"]): param
+                    for param in parameters
+                    if param.get("required")
+                }
+                # Make sure required definitions of the same parameter take precedence
+                # over non-required definitions
+                all_parameters.update(required_parameters)
+                operation["parameters"] = list(all_parameters.values())
+            if method in METHODS_WITH_BODY:
+                request_body_oai = get_openapi_operation_request_body(
+                    body_field=route.body_field,
+                    schema_generator=schema_generator,
+                    model_name_map=model_name_map,
+                    field_mapping=field_mapping,
+                    separate_input_output_schemas=separate_input_output_schemas,
+                )
+                if request_body_oai:
+                    operation["requestBody"] = request_body_oai
+            if route.callbacks:
+                callbacks = {}
+                for callback in route.callbacks:
+                    if isinstance(callback, routing.APIRoute):
+                        (
+                            cb_path,
+                            cb_security_schemes,
+                            cb_definitions,
+                        ) = get_openapi_path(
+                            route=callback,
+                            operation_ids=operation_ids,
+                            schema_generator=schema_generator,
+                            model_name_map=model_name_map,
+                            field_mapping=field_mapping,
+                            separate_input_output_schemas=separate_input_output_schemas,
+                        )
+                        callbacks[callback.name] = {callback.path: cb_path}
+                operation["callbacks"] = callbacks
+            if route.status_code is not None:
+                status_code = str(route.status_code)
+            else:
+                # It would probably make more sense for all response classes to have an
+                # explicit default status_code, and to extract it from them, instead of
+                # doing this inspection tricks, that would probably be in the future
+                # TODO: probably make status_code a default class attribute for all
+                # responses in Starlette
+                response_signature = inspect.signature(current_response_class.__init__)
+                status_code_param = response_signature.parameters.get("status_code")
+                if status_code_param is not None:
+                    if isinstance(status_code_param.default, int):
+                        status_code = str(status_code_param.default)
+            operation.setdefault("responses", {}).setdefault(status_code, {})[
+                "description"
+            ] = route.response_description
+            if route_response_media_type and is_body_allowed_for_status_code(
+                route.status_code
+            ):
+                response_schema = {"type": "string"}
+                if lenient_issubclass(current_response_class, JSONResponse):
+                    if route.response_field:
+                        response_schema = get_schema_from_model_field(
+                            field=route.response_field,
+                            schema_generator=schema_generator,
+                            model_name_map=model_name_map,
+                            field_mapping=field_mapping,
+                            separate_input_output_schemas=separate_input_output_schemas,
+                        )
+                    else:
+                        response_schema = {}
+                operation.setdefault("responses", {}).setdefault(
+                    status_code, {}
+                ).setdefault("content", {}).setdefault(route_response_media_type, {})[
+                    "schema"
+                ] = response_schema
+            if route.responses:
+                operation_responses = operation.setdefault("responses", {})
+                for (
+                    additional_status_code,
+                    additional_response,
+                ) in route.responses.items():
+                    process_response = additional_response.copy()
+                    process_response.pop("model", None)
+                    status_code_key = str(additional_status_code).upper()
+                    if status_code_key == "DEFAULT":
+                        status_code_key = "default"
+                    openapi_response = operation_responses.setdefault(
+                        status_code_key, {}
+                    )
+                    assert isinstance(process_response, dict), (
+                        "An additional response must be a dict"
+                    )
+                    field = route.response_fields.get(additional_status_code)
+                    additional_field_schema: Optional[Dict[str, Any]] = None
+                    if field:
+                        additional_field_schema = get_schema_from_model_field(
+                            field=field,
+                            schema_generator=schema_generator,
+                            model_name_map=model_name_map,
+                            field_mapping=field_mapping,
+                            separate_input_output_schemas=separate_input_output_schemas,
+                        )
+                        media_type = route_response_media_type or "application/json"
+                        additional_schema = (
+                            process_response.setdefault("content", {})
+                            .setdefault(media_type, {})
+                            .setdefault("schema", {})
+                        )
+                        deep_dict_update(additional_schema, additional_field_schema)
+                    status_text: Optional[str] = status_code_ranges.get(
+                        str(additional_status_code).upper()
+                    ) or http.client.responses.get(int(additional_status_code))
+                    description = (
+                        process_response.get("description")
+                        or openapi_response.get("description")
+                        or status_text
+                        or "Additional Response"
+                    )
+                    deep_dict_update(openapi_response, process_response)
+                    openapi_response["description"] = description
+            http422 = str(HTTP_422_UNPROCESSABLE_ENTITY)
+            all_route_params = get_flat_params(route.dependant)
+            if (all_route_params or route.body_field) and not any(
+                status in operation["responses"]
+                for status in [http422, "4XX", "default"]
+            ):
+                operation["responses"][http422] = {
+                    "description": "Validation Error",
+                    "content": {
+                        "application/json": {
+                            "schema": {"$ref": REF_PREFIX + "HTTPValidationError"}
+                        }
+                    },
+                }
+                if "ValidationError" not in definitions:
+                    definitions.update(
+                        {
+                            "ValidationError": validation_error_definition,
+                            "HTTPValidationError": validation_error_response_definition,
+                        }
+                    )
+            if route.openapi_extra:
+                deep_dict_update(operation, route.openapi_extra)
+            path[method.lower()] = operation
+    return path, security_schemes, definitions
+
+
+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] = []
+    for route in routes:
+        if getattr(route, "include_in_schema", None) and isinstance(
+            route, routing.APIRoute
+        ):
+            if route.body_field:
+                assert isinstance(route.body_field, ModelField), (
+                    "A request body must be a Pydantic Field"
+                )
+                body_fields_from_routes.append(route.body_field)
+            if route.response_field:
+                responses_from_routes.append(route.response_field)
+            if route.response_fields:
+                responses_from_routes.extend(route.response_fields.values())
+            if route.callbacks:
+                callback_flat_models.extend(get_fields_from_routes(route.callbacks))
+            params = get_flat_params(route.dependant)
+            request_fields_from_routes.extend(params)
+
+    flat_models = callback_flat_models + list(
+        body_fields_from_routes + responses_from_routes + request_fields_from_routes
+    )
+    return flat_models
+
+
+def get_openapi(
+    *,
+    title: str,
+    version: str,
+    openapi_version: str = "3.1.0",
+    summary: Optional[str] = None,
+    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,
+    terms_of_service: Optional[str] = None,
+    contact: Optional[Dict[str, Union[str, Any]]] = None,
+    license_info: Optional[Dict[str, Union[str, Any]]] = None,
+    separate_input_output_schemas: bool = True,
+) -> Dict[str, Any]:
+    info: Dict[str, Any] = {"title": title, "version": version}
+    if summary:
+        info["summary"] = summary
+    if description:
+        info["description"] = description
+    if terms_of_service:
+        info["termsOfService"] = terms_of_service
+    if contact:
+        info["contact"] = contact
+    if license_info:
+        info["license"] = license_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()
+    all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
+    model_name_map = get_compat_model_name_map(all_fields)
+    schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE)
+    field_mapping, definitions = get_definitions(
+        fields=all_fields,
+        schema_generator=schema_generator,
+        model_name_map=model_name_map,
+        separate_input_output_schemas=separate_input_output_schemas,
+    )
+    for route in routes or []:
+        if isinstance(route, routing.APIRoute):
+            result = get_openapi_path(
+                route=route,
+                operation_ids=operation_ids,
+                schema_generator=schema_generator,
+                model_name_map=model_name_map,
+                field_mapping=field_mapping,
+                separate_input_output_schemas=separate_input_output_schemas,
+            )
+            if result:
+                path, security_schemes, path_definitions = result
+                if path:
+                    paths.setdefault(route.path_format, {}).update(path)
+                if security_schemes:
+                    components.setdefault("securitySchemes", {}).update(
+                        security_schemes
+                    )
+                if path_definitions:
+                    definitions.update(path_definitions)
+    for webhook in webhooks or []:
+        if isinstance(webhook, routing.APIRoute):
+            result = get_openapi_path(
+                route=webhook,
+                operation_ids=operation_ids,
+                schema_generator=schema_generator,
+                model_name_map=model_name_map,
+                field_mapping=field_mapping,
+                separate_input_output_schemas=separate_input_output_schemas,
+            )
+            if result:
+                path, security_schemes, path_definitions = result
+                if path:
+                    webhook_paths.setdefault(webhook.path_format, {}).update(path)
+                if security_schemes:
+                    components.setdefault("securitySchemes", {}).update(
+                        security_schemes
+                    )
+                if path_definitions:
+                    definitions.update(path_definitions)
+    if definitions:
+        components["schemas"] = {k: definitions[k] for k in sorted(definitions)}
+    if components:
+        output["components"] = components
+    output["paths"] = paths
+    if webhook_paths:
+        output["webhooks"] = webhook_paths
+    if tags:
+        output["tags"] = tags
+    return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True)  # type: ignore
diff --git a/.venv/lib/python3.12/site-packages/fastapi/param_functions.py b/.venv/lib/python3.12/site-packages/fastapi/param_functions.py
new file mode 100644
index 00000000..b3621626
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/param_functions.py
@@ -0,0 +1,2360 @@
+from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+
+from fastapi import params
+from fastapi._compat import Undefined
+from fastapi.openapi.models import Example
+from typing_extensions import Annotated, Doc, deprecated
+
+_Unset: Any = Undefined
+
+
+def Path(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = ...,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    """
+    Declare a path parameter for a *path operation*.
+
+    Read more about it in the
+    [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/).
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import FastAPI, Path
+
+    app = FastAPI()
+
+
+    @app.get("/items/{item_id}")
+    async def read_items(
+        item_id: Annotated[int, Path(title="The ID of the item to get")],
+    ):
+        return {"item_id": item_id}
+    ```
+    """
+    return params.Path(
+        default=default,
+        default_factory=default_factory,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Query(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.Query(
+        default=default,
+        default_factory=default_factory,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Header(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    convert_underscores: Annotated[
+        bool,
+        Doc(
+            """
+            Automatically convert underscores to hyphens in the parameter field name.
+
+            Read more about it in the
+            [FastAPI docs for Header Parameters](https://fastapi.tiangolo.com/tutorial/header-params/#automatic-conversion)
+            """
+        ),
+    ] = True,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.Header(
+        default=default,
+        default_factory=default_factory,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        convert_underscores=convert_underscores,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Cookie(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.Cookie(
+        default=default,
+        default_factory=default_factory,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Body(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    embed: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            When `embed` is `True`, the parameter will be expected in a JSON body as a
+            key instead of being the JSON body itself.
+
+            This happens automatically when more than one `Body` parameter is declared.
+
+            Read more about it in the
+            [FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter).
+            """
+        ),
+    ] = None,
+    media_type: Annotated[
+        str,
+        Doc(
+            """
+            The media type of this parameter field. Changing it would affect the
+            generated OpenAPI, but currently it doesn't affect the parsing of the data.
+            """
+        ),
+    ] = "application/json",
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.Body(
+        default=default,
+        default_factory=default_factory,
+        embed=embed,
+        media_type=media_type,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Form(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    media_type: Annotated[
+        str,
+        Doc(
+            """
+            The media type of this parameter field. Changing it would affect the
+            generated OpenAPI, but currently it doesn't affect the parsing of the data.
+            """
+        ),
+    ] = "application/x-www-form-urlencoded",
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.Form(
+        default=default,
+        default_factory=default_factory,
+        media_type=media_type,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def File(  # noqa: N802
+    default: Annotated[
+        Any,
+        Doc(
+            """
+            Default value if the parameter field is not set.
+            """
+        ),
+    ] = Undefined,
+    *,
+    default_factory: Annotated[
+        Union[Callable[[], Any], None],
+        Doc(
+            """
+            A callable to generate the default value.
+
+            This doesn't affect `Path` parameters as the value is always required.
+            The parameter is available only for compatibility.
+            """
+        ),
+    ] = _Unset,
+    media_type: Annotated[
+        str,
+        Doc(
+            """
+            The media type of this parameter field. Changing it would affect the
+            generated OpenAPI, but currently it doesn't affect the parsing of the data.
+            """
+        ),
+    ] = "multipart/form-data",
+    alias: Annotated[
+        Optional[str],
+        Doc(
+            """
+            An alternative name for the parameter field.
+
+            This will be used to extract the data and for the generated OpenAPI.
+            It is particularly useful when you can't use the name you want because it
+            is a Python reserved keyword or similar.
+            """
+        ),
+    ] = None,
+    alias_priority: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Priority of the alias. This affects whether an alias generator is used.
+            """
+        ),
+    ] = _Unset,
+    # TODO: update when deprecating Pydantic v1, import these types
+    # validation_alias: str | AliasPath | AliasChoices | None
+    validation_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Whitelist' validation step. The parameter field will be the single one
+            allowed by the alias or set of aliases defined.
+            """
+        ),
+    ] = None,
+    serialization_alias: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            'Blacklist' validation step. The vanilla parameter field will be the
+            single one of the alias' or set of aliases' fields and all the other
+            fields will be ignored at serialization time.
+            """
+        ),
+    ] = None,
+    title: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable title.
+            """
+        ),
+    ] = None,
+    description: Annotated[
+        Optional[str],
+        Doc(
+            """
+            Human-readable description.
+            """
+        ),
+    ] = None,
+    gt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than. If set, value must be greater than this. Only applicable to
+            numbers.
+            """
+        ),
+    ] = None,
+    ge: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Greater than or equal. If set, value must be greater than or equal to
+            this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    lt: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than. If set, value must be less than this. Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    le: Annotated[
+        Optional[float],
+        Doc(
+            """
+            Less than or equal. If set, value must be less than or equal to this.
+            Only applicable to numbers.
+            """
+        ),
+    ] = None,
+    min_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Minimum length for strings.
+            """
+        ),
+    ] = None,
+    max_length: Annotated[
+        Optional[int],
+        Doc(
+            """
+            Maximum length for strings.
+            """
+        ),
+    ] = None,
+    pattern: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+    ] = None,
+    regex: Annotated[
+        Optional[str],
+        Doc(
+            """
+            RegEx pattern for strings.
+            """
+        ),
+        deprecated(
+            "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+        ),
+    ] = None,
+    discriminator: Annotated[
+        Union[str, None],
+        Doc(
+            """
+            Parameter field name for discriminating the type in a tagged union.
+            """
+        ),
+    ] = None,
+    strict: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            If `True`, strict validation is applied to the field.
+            """
+        ),
+    ] = _Unset,
+    multiple_of: Annotated[
+        Union[float, None],
+        Doc(
+            """
+            Value must be a multiple of this. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    allow_inf_nan: Annotated[
+        Union[bool, None],
+        Doc(
+            """
+            Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+            """
+        ),
+    ] = _Unset,
+    max_digits: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of allow digits for strings.
+            """
+        ),
+    ] = _Unset,
+    decimal_places: Annotated[
+        Union[int, None],
+        Doc(
+            """
+            Maximum number of decimal places allowed for numbers.
+            """
+        ),
+    ] = _Unset,
+    examples: Annotated[
+        Optional[List[Any]],
+        Doc(
+            """
+            Example values for this field.
+            """
+        ),
+    ] = None,
+    example: Annotated[
+        Optional[Any],
+        deprecated(
+            "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+            "although still supported. Use examples instead."
+        ),
+    ] = _Unset,
+    openapi_examples: Annotated[
+        Optional[Dict[str, Example]],
+        Doc(
+            """
+            OpenAPI-specific examples.
+
+            It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+            Swagger UI (that provides the `/docs` interface) has better support for the
+            OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+            use case for this.
+
+            Read more about it in the
+            [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+            """
+        ),
+    ] = None,
+    deprecated: Annotated[
+        Union[deprecated, str, bool, None],
+        Doc(
+            """
+            Mark this parameter field as deprecated.
+
+            It will affect the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = None,
+    include_in_schema: Annotated[
+        bool,
+        Doc(
+            """
+            To include (or not) this parameter field in the generated OpenAPI.
+            You probably don't need it, but it's available.
+
+            This affects the generated OpenAPI (e.g. visible at `/docs`).
+            """
+        ),
+    ] = True,
+    json_schema_extra: Annotated[
+        Union[Dict[str, Any], None],
+        Doc(
+            """
+            Any additional JSON schema data.
+            """
+        ),
+    ] = None,
+    **extra: Annotated[
+        Any,
+        Doc(
+            """
+            Include extra fields used by the JSON Schema.
+            """
+        ),
+        deprecated(
+            """
+            The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+            """
+        ),
+    ],
+) -> Any:
+    return params.File(
+        default=default,
+        default_factory=default_factory,
+        media_type=media_type,
+        alias=alias,
+        alias_priority=alias_priority,
+        validation_alias=validation_alias,
+        serialization_alias=serialization_alias,
+        title=title,
+        description=description,
+        gt=gt,
+        ge=ge,
+        lt=lt,
+        le=le,
+        min_length=min_length,
+        max_length=max_length,
+        pattern=pattern,
+        regex=regex,
+        discriminator=discriminator,
+        strict=strict,
+        multiple_of=multiple_of,
+        allow_inf_nan=allow_inf_nan,
+        max_digits=max_digits,
+        decimal_places=decimal_places,
+        example=example,
+        examples=examples,
+        openapi_examples=openapi_examples,
+        deprecated=deprecated,
+        include_in_schema=include_in_schema,
+        json_schema_extra=json_schema_extra,
+        **extra,
+    )
+
+
+def Depends(  # noqa: N802
+    dependency: Annotated[
+        Optional[Callable[..., Any]],
+        Doc(
+            """
+            A "dependable" callable (like a function).
+
+            Don't call it directly, FastAPI will call it for you, just pass the object
+            directly.
+            """
+        ),
+    ] = None,
+    *,
+    use_cache: Annotated[
+        bool,
+        Doc(
+            """
+            By default, after a dependency is called the first time in a request, if
+            the dependency is declared again for the rest of the request (for example
+            if the dependency is needed by several dependencies), the value will be
+            re-used for the rest of the request.
+
+            Set `use_cache` to `False` to disable this behavior and ensure the
+            dependency is called again (if declared more than once) in the same request.
+            """
+        ),
+    ] = True,
+) -> Any:
+    """
+    Declare a FastAPI dependency.
+
+    It takes a single "dependable" callable (like a function).
+
+    Don't call it directly, FastAPI will call it for you.
+
+    Read more about it in the
+    [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
+
+    **Example**
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+
+    app = FastAPI()
+
+
+    async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
+        return {"q": q, "skip": skip, "limit": limit}
+
+
+    @app.get("/items/")
+    async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
+        return commons
+    ```
+    """
+    return params.Depends(dependency=dependency, use_cache=use_cache)
+
+
+def Security(  # noqa: N802
+    dependency: Annotated[
+        Optional[Callable[..., Any]],
+        Doc(
+            """
+            A "dependable" callable (like a function).
+
+            Don't call it directly, FastAPI will call it for you, just pass the object
+            directly.
+            """
+        ),
+    ] = None,
+    *,
+    scopes: Annotated[
+        Optional[Sequence[str]],
+        Doc(
+            """
+            OAuth2 scopes required for the *path operation* that uses this Security
+            dependency.
+
+            The term "scope" comes from the OAuth2 specification, it seems to be
+            intentionally vague and interpretable. It normally refers to permissions,
+            in cases to roles.
+
+            These scopes are integrated with OpenAPI (and the API docs at `/docs`).
+            So they are visible in the OpenAPI specification.
+            )
+            """
+        ),
+    ] = None,
+    use_cache: Annotated[
+        bool,
+        Doc(
+            """
+            By default, after a dependency is called the first time in a request, if
+            the dependency is declared again for the rest of the request (for example
+            if the dependency is needed by several dependencies), the value will be
+            re-used for the rest of the request.
+
+            Set `use_cache` to `False` to disable this behavior and ensure the
+            dependency is called again (if declared more than once) in the same request.
+            """
+        ),
+    ] = True,
+) -> Any:
+    """
+    Declare a FastAPI Security dependency.
+
+    The only difference with a regular dependency is that it can declare OAuth2
+    scopes that will be integrated with OpenAPI and the automatic UI docs (by default
+    at `/docs`).
+
+    It takes a single "dependable" callable (like a function).
+
+    Don't call it directly, FastAPI will call it for you.
+
+    Read more about it in the
+    [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/) and
+    in the
+    [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+
+    **Example**
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Security, FastAPI
+
+    from .db import User
+    from .security import get_current_active_user
+
+    app = FastAPI()
+
+    @app.get("/users/me/items/")
+    async def read_own_items(
+        current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])]
+    ):
+        return [{"item_id": "Foo", "owner": current_user.username}]
+    ```
+    """
+    return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/params.py b/.venv/lib/python3.12/site-packages/fastapi/params.py
new file mode 100644
index 00000000..8f5601dd
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/params.py
@@ -0,0 +1,786 @@
+import warnings
+from enum import Enum
+from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+
+from fastapi.openapi.models import Example
+from pydantic.fields import FieldInfo
+from typing_extensions import Annotated, deprecated
+
+from ._compat import (
+    PYDANTIC_V2,
+    PYDANTIC_VERSION_MINOR_TUPLE,
+    Undefined,
+)
+
+_Unset: Any = Undefined
+
+
+class ParamTypes(Enum):
+    query = "query"
+    header = "header"
+    path = "path"
+    cookie = "cookie"
+
+
+class Param(FieldInfo):
+    in_: ParamTypes
+
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        if example is not _Unset:
+            warnings.warn(
+                "`example` has been deprecated, please use `examples` instead",
+                category=DeprecationWarning,
+                stacklevel=4,
+            )
+        self.example = example
+        self.include_in_schema = include_in_schema
+        self.openapi_examples = openapi_examples
+        kwargs = dict(
+            default=default,
+            default_factory=default_factory,
+            alias=alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            discriminator=discriminator,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            **extra,
+        )
+        if examples is not None:
+            kwargs["examples"] = examples
+        if regex is not None:
+            warnings.warn(
+                "`regex` has been deprecated, please use `pattern` instead",
+                category=DeprecationWarning,
+                stacklevel=4,
+            )
+        current_json_schema_extra = json_schema_extra or extra
+        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
+            self.deprecated = deprecated
+        else:
+            kwargs["deprecated"] = deprecated
+        if PYDANTIC_V2:
+            kwargs.update(
+                {
+                    "annotation": annotation,
+                    "alias_priority": alias_priority,
+                    "validation_alias": validation_alias,
+                    "serialization_alias": serialization_alias,
+                    "strict": strict,
+                    "json_schema_extra": current_json_schema_extra,
+                }
+            )
+            kwargs["pattern"] = pattern or regex
+        else:
+            kwargs["regex"] = pattern or regex
+            kwargs.update(**current_json_schema_extra)
+        use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
+
+        super().__init__(**use_kwargs)
+
+    def __repr__(self) -> str:
+        return f"{self.__class__.__name__}({self.default})"
+
+
+class Path(Param):
+    in_ = ParamTypes.path
+
+    def __init__(
+        self,
+        default: Any = ...,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        assert default is ..., "Path parameters cannot have a default value"
+        self.in_ = self.in_
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class Query(Param):
+    in_ = ParamTypes.query
+
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class Header(Param):
+    in_ = ParamTypes.header
+
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        convert_underscores: bool = True,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        self.convert_underscores = convert_underscores
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class Cookie(Param):
+    in_ = ParamTypes.cookie
+
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class Body(FieldInfo):
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        embed: Union[bool, None] = None,
+        media_type: str = "application/json",
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        self.embed = embed
+        self.media_type = media_type
+        if example is not _Unset:
+            warnings.warn(
+                "`example` has been deprecated, please use `examples` instead",
+                category=DeprecationWarning,
+                stacklevel=4,
+            )
+        self.example = example
+        self.include_in_schema = include_in_schema
+        self.openapi_examples = openapi_examples
+        kwargs = dict(
+            default=default,
+            default_factory=default_factory,
+            alias=alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            discriminator=discriminator,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            **extra,
+        )
+        if examples is not None:
+            kwargs["examples"] = examples
+        if regex is not None:
+            warnings.warn(
+                "`regex` has been deprecated, please use `pattern` instead",
+                category=DeprecationWarning,
+                stacklevel=4,
+            )
+        current_json_schema_extra = json_schema_extra or extra
+        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
+            self.deprecated = deprecated
+        else:
+            kwargs["deprecated"] = deprecated
+        if PYDANTIC_V2:
+            kwargs.update(
+                {
+                    "annotation": annotation,
+                    "alias_priority": alias_priority,
+                    "validation_alias": validation_alias,
+                    "serialization_alias": serialization_alias,
+                    "strict": strict,
+                    "json_schema_extra": current_json_schema_extra,
+                }
+            )
+            kwargs["pattern"] = pattern or regex
+        else:
+            kwargs["regex"] = pattern or regex
+            kwargs.update(**current_json_schema_extra)
+
+        use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
+
+        super().__init__(**use_kwargs)
+
+    def __repr__(self) -> str:
+        return f"{self.__class__.__name__}({self.default})"
+
+
+class Form(Body):
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        media_type: str = "application/x-www-form-urlencoded",
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            media_type=media_type,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class File(Form):
+    def __init__(
+        self,
+        default: Any = Undefined,
+        *,
+        default_factory: Union[Callable[[], Any], None] = _Unset,
+        annotation: Optional[Any] = None,
+        media_type: str = "multipart/form-data",
+        alias: Optional[str] = None,
+        alias_priority: Union[int, None] = _Unset,
+        # TODO: update when deprecating Pydantic v1, import these types
+        # validation_alias: str | AliasPath | AliasChoices | None
+        validation_alias: Union[str, None] = None,
+        serialization_alias: Union[str, None] = None,
+        title: Optional[str] = None,
+        description: Optional[str] = None,
+        gt: Optional[float] = None,
+        ge: Optional[float] = None,
+        lt: Optional[float] = None,
+        le: Optional[float] = None,
+        min_length: Optional[int] = None,
+        max_length: Optional[int] = None,
+        pattern: Optional[str] = None,
+        regex: Annotated[
+            Optional[str],
+            deprecated(
+                "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+            ),
+        ] = None,
+        discriminator: Union[str, None] = None,
+        strict: Union[bool, None] = _Unset,
+        multiple_of: Union[float, None] = _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,
+        example: Annotated[
+            Optional[Any],
+            deprecated(
+                "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+                "although still supported. Use examples instead."
+            ),
+        ] = _Unset,
+        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,
+        **extra: Any,
+    ):
+        super().__init__(
+            default=default,
+            default_factory=default_factory,
+            annotation=annotation,
+            media_type=media_type,
+            alias=alias,
+            alias_priority=alias_priority,
+            validation_alias=validation_alias,
+            serialization_alias=serialization_alias,
+            title=title,
+            description=description,
+            gt=gt,
+            ge=ge,
+            lt=lt,
+            le=le,
+            min_length=min_length,
+            max_length=max_length,
+            pattern=pattern,
+            regex=regex,
+            discriminator=discriminator,
+            strict=strict,
+            multiple_of=multiple_of,
+            allow_inf_nan=allow_inf_nan,
+            max_digits=max_digits,
+            decimal_places=decimal_places,
+            deprecated=deprecated,
+            example=example,
+            examples=examples,
+            openapi_examples=openapi_examples,
+            include_in_schema=include_in_schema,
+            json_schema_extra=json_schema_extra,
+            **extra,
+        )
+
+
+class Depends:
+    def __init__(
+        self, dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
+    ):
+        self.dependency = dependency
+        self.use_cache = use_cache
+
+    def __repr__(self) -> str:
+        attr = getattr(self.dependency, "__name__", type(self.dependency).__name__)
+        cache = "" if self.use_cache else ", use_cache=False"
+        return f"{self.__class__.__name__}({attr}{cache})"
+
+
+class Security(Depends):
+    def __init__(
+        self,
+        dependency: Optional[Callable[..., Any]] = None,
+        *,
+        scopes: Optional[Sequence[str]] = None,
+        use_cache: bool = True,
+    ):
+        super().__init__(dependency=dependency, use_cache=use_cache)
+        self.scopes = scopes or []
diff --git a/.venv/lib/python3.12/site-packages/fastapi/py.typed b/.venv/lib/python3.12/site-packages/fastapi/py.typed
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/py.typed
diff --git a/.venv/lib/python3.12/site-packages/fastapi/requests.py b/.venv/lib/python3.12/site-packages/fastapi/requests.py
new file mode 100644
index 00000000..d16552c0
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/requests.py
@@ -0,0 +1,2 @@
+from starlette.requests import HTTPConnection as HTTPConnection  # noqa: F401
+from starlette.requests import Request as Request  # noqa: F401
diff --git a/.venv/lib/python3.12/site-packages/fastapi/responses.py b/.venv/lib/python3.12/site-packages/fastapi/responses.py
new file mode 100644
index 00000000..6c8db6f3
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/responses.py
@@ -0,0 +1,48 @@
+from typing import Any
+
+from starlette.responses import FileResponse as FileResponse  # noqa
+from starlette.responses import HTMLResponse as HTMLResponse  # noqa
+from starlette.responses import JSONResponse as JSONResponse  # noqa
+from starlette.responses import PlainTextResponse as PlainTextResponse  # noqa
+from starlette.responses import RedirectResponse as RedirectResponse  # noqa
+from starlette.responses import Response as Response  # noqa
+from starlette.responses import StreamingResponse as StreamingResponse  # noqa
+
+try:
+    import ujson
+except ImportError:  # pragma: nocover
+    ujson = None  # type: ignore
+
+
+try:
+    import orjson
+except ImportError:  # pragma: nocover
+    orjson = None  # type: ignore
+
+
+class UJSONResponse(JSONResponse):
+    """
+    JSON response using the high-performance ujson library to serialize data to JSON.
+
+    Read more about it in the
+    [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+    """
+
+    def render(self, content: Any) -> bytes:
+        assert ujson is not None, "ujson must be installed to use UJSONResponse"
+        return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
+
+
+class ORJSONResponse(JSONResponse):
+    """
+    JSON response using the high-performance orjson library to serialize data to JSON.
+
+    Read more about it in the
+    [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+    """
+
+    def render(self, content: Any) -> bytes:
+        assert orjson is not None, "orjson must be installed to use ORJSONResponse"
+        return orjson.dumps(
+            content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY
+        )
diff --git a/.venv/lib/python3.12/site-packages/fastapi/routing.py b/.venv/lib/python3.12/site-packages/fastapi/routing.py
new file mode 100644
index 00000000..457481e3
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/routing.py
@@ -0,0 +1,4439 @@
+import asyncio
+import dataclasses
+import email.message
+import inspect
+import json
+from contextlib import AsyncExitStack, asynccontextmanager
+from enum import Enum, IntEnum
+from typing import (
+    Any,
+    AsyncIterator,
+    Callable,
+    Coroutine,
+    Dict,
+    List,
+    Mapping,
+    Optional,
+    Sequence,
+    Set,
+    Tuple,
+    Type,
+    Union,
+)
+
+from fastapi import params
+from fastapi._compat import (
+    ModelField,
+    Undefined,
+    _get_model_config,
+    _model_dump,
+    _normalize_errors,
+    lenient_issubclass,
+)
+from fastapi.datastructures import Default, DefaultPlaceholder
+from fastapi.dependencies.models import Dependant
+from fastapi.dependencies.utils import (
+    _should_embed_body_fields,
+    get_body_field,
+    get_dependant,
+    get_flat_dependant,
+    get_parameterless_sub_dependant,
+    get_typed_return_annotation,
+    solve_dependencies,
+)
+from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import (
+    FastAPIError,
+    RequestValidationError,
+    ResponseValidationError,
+    WebSocketRequestValidationError,
+)
+from fastapi.types import DecoratedCallable, IncEx
+from fastapi.utils import (
+    create_cloned_field,
+    create_model_field,
+    generate_unique_id,
+    get_value_or_default,
+    is_body_allowed_for_status_code,
+)
+from pydantic import BaseModel
+from starlette import routing
+from starlette.concurrency import run_in_threadpool
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.responses import JSONResponse, Response
+from starlette.routing import (
+    BaseRoute,
+    Match,
+    compile_path,
+    get_name,
+    request_response,
+    websocket_session,
+)
+from starlette.routing import Mount as Mount  # noqa
+from starlette.types import AppType, ASGIApp, Lifespan, Scope
+from starlette.websockets import WebSocket
+from typing_extensions import Annotated, Doc, deprecated
+
+
+def _prepare_response_content(
+    res: Any,
+    *,
+    exclude_unset: bool,
+    exclude_defaults: bool = False,
+    exclude_none: bool = False,
+) -> Any:
+    if isinstance(res, BaseModel):
+        read_with_orm_mode = getattr(_get_model_config(res), "read_with_orm_mode", None)
+        if read_with_orm_mode:
+            # Let from_orm extract the data from this model instead of converting
+            # it now to a dict.
+            # Otherwise, there's no way to extract lazy data that requires attribute
+            # access instead of dict iteration, e.g. lazy relationships.
+            return res
+        return _model_dump(
+            res,
+            by_alias=True,
+            exclude_unset=exclude_unset,
+            exclude_defaults=exclude_defaults,
+            exclude_none=exclude_none,
+        )
+    elif isinstance(res, list):
+        return [
+            _prepare_response_content(
+                item,
+                exclude_unset=exclude_unset,
+                exclude_defaults=exclude_defaults,
+                exclude_none=exclude_none,
+            )
+            for item in res
+        ]
+    elif isinstance(res, dict):
+        return {
+            k: _prepare_response_content(
+                v,
+                exclude_unset=exclude_unset,
+                exclude_defaults=exclude_defaults,
+                exclude_none=exclude_none,
+            )
+            for k, v in res.items()
+        }
+    elif dataclasses.is_dataclass(res):
+        return dataclasses.asdict(res)
+    return res
+
+
+def _merge_lifespan_context(
+    original_context: Lifespan[Any], nested_context: Lifespan[Any]
+) -> Lifespan[Any]:
+    @asynccontextmanager
+    async def merged_lifespan(
+        app: AppType,
+    ) -> AsyncIterator[Optional[Mapping[str, Any]]]:
+        async with original_context(app) as maybe_original_state:
+            async with nested_context(app) as maybe_nested_state:
+                if maybe_nested_state is None and maybe_original_state is None:
+                    yield None  # old ASGI compatibility
+                else:
+                    yield {**(maybe_nested_state or {}), **(maybe_original_state or {})}
+
+    return merged_lifespan  # type: ignore[return-value]
+
+
+async def serialize_response(
+    *,
+    field: Optional[ModelField] = None,
+    response_content: Any,
+    include: Optional[IncEx] = None,
+    exclude: Optional[IncEx] = None,
+    by_alias: bool = True,
+    exclude_unset: bool = False,
+    exclude_defaults: bool = False,
+    exclude_none: bool = False,
+    is_coroutine: bool = True,
+) -> Any:
+    if field:
+        errors = []
+        if not hasattr(field, "serialize"):
+            # pydantic v1
+            response_content = _prepare_response_content(
+                response_content,
+                exclude_unset=exclude_unset,
+                exclude_defaults=exclude_defaults,
+                exclude_none=exclude_none,
+            )
+        if is_coroutine:
+            value, errors_ = field.validate(response_content, {}, loc=("response",))
+        else:
+            value, errors_ = await run_in_threadpool(
+                field.validate, response_content, {}, loc=("response",)
+            )
+        if isinstance(errors_, list):
+            errors.extend(errors_)
+        elif errors_:
+            errors.append(errors_)
+        if errors:
+            raise ResponseValidationError(
+                errors=_normalize_errors(errors), body=response_content
+            )
+
+        if hasattr(field, "serialize"):
+            return field.serialize(
+                value,
+                include=include,
+                exclude=exclude,
+                by_alias=by_alias,
+                exclude_unset=exclude_unset,
+                exclude_defaults=exclude_defaults,
+                exclude_none=exclude_none,
+            )
+
+        return jsonable_encoder(
+            value,
+            include=include,
+            exclude=exclude,
+            by_alias=by_alias,
+            exclude_unset=exclude_unset,
+            exclude_defaults=exclude_defaults,
+            exclude_none=exclude_none,
+        )
+    else:
+        return jsonable_encoder(response_content)
+
+
+async def run_endpoint_function(
+    *, 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.
+    assert dependant.call is not None, "dependant.call must be a function"
+
+    if is_coroutine:
+        return await dependant.call(**values)
+    else:
+        return await run_in_threadpool(dependant.call, **values)
+
+
+def get_request_handler(
+    dependant: Dependant,
+    body_field: Optional[ModelField] = None,
+    status_code: Optional[int] = None,
+    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,
+    response_model_by_alias: bool = True,
+    response_model_exclude_unset: bool = False,
+    response_model_exclude_defaults: bool = False,
+    response_model_exclude_none: bool = False,
+    dependency_overrides_provider: Optional[Any] = None,
+    embed_body_fields: bool = False,
+) -> Callable[[Request], Coroutine[Any, Any, Response]]:
+    assert dependant.call is not None, "dependant.call must be a function"
+    is_coroutine = asyncio.iscoroutinefunction(dependant.call)
+    is_body_form = body_field and isinstance(body_field.field_info, params.Form)
+    if isinstance(response_class, DefaultPlaceholder):
+        actual_response_class: Type[Response] = response_class.value
+    else:
+        actual_response_class = response_class
+
+    async def app(request: Request) -> Response:
+        response: Union[Response, None] = None
+        async with AsyncExitStack() as file_stack:
+            try:
+                body: Any = None
+                if body_field:
+                    if is_body_form:
+                        body = await request.form()
+                        file_stack.push_async_callback(body.close)
+                    else:
+                        body_bytes = await request.body()
+                        if body_bytes:
+                            json_body: Any = Undefined
+                            content_type_value = request.headers.get("content-type")
+                            if not content_type_value:
+                                json_body = await request.json()
+                            else:
+                                message = email.message.Message()
+                                message["content-type"] = content_type_value
+                                if message.get_content_maintype() == "application":
+                                    subtype = message.get_content_subtype()
+                                    if subtype == "json" or subtype.endswith("+json"):
+                                        json_body = await request.json()
+                            if json_body != Undefined:
+                                body = json_body
+                            else:
+                                body = body_bytes
+            except json.JSONDecodeError as e:
+                validation_error = RequestValidationError(
+                    [
+                        {
+                            "type": "json_invalid",
+                            "loc": ("body", e.pos),
+                            "msg": "JSON decode error",
+                            "input": {},
+                            "ctx": {"error": e.msg},
+                        }
+                    ],
+                    body=e.doc,
+                )
+                raise validation_error from e
+            except HTTPException:
+                # If a middleware raises an HTTPException, it should be raised again
+                raise
+            except Exception as e:
+                http_error = HTTPException(
+                    status_code=400, detail="There was an error parsing the body"
+                )
+                raise http_error from e
+            errors: List[Any] = []
+            async with AsyncExitStack() as async_exit_stack:
+                solved_result = await solve_dependencies(
+                    request=request,
+                    dependant=dependant,
+                    body=body,
+                    dependency_overrides_provider=dependency_overrides_provider,
+                    async_exit_stack=async_exit_stack,
+                    embed_body_fields=embed_body_fields,
+                )
+                errors = solved_result.errors
+                if not errors:
+                    raw_response = await run_endpoint_function(
+                        dependant=dependant,
+                        values=solved_result.values,
+                        is_coroutine=is_coroutine,
+                    )
+                    if isinstance(raw_response, Response):
+                        if raw_response.background is None:
+                            raw_response.background = solved_result.background_tasks
+                        response = raw_response
+                    else:
+                        response_args: Dict[str, Any] = {
+                            "background": solved_result.background_tasks
+                        }
+                        # If status_code was set, use it, otherwise use the default from the
+                        # response class, in the case of redirect it's 307
+                        current_status_code = (
+                            status_code
+                            if status_code
+                            else solved_result.response.status_code
+                        )
+                        if current_status_code is not None:
+                            response_args["status_code"] = current_status_code
+                        if solved_result.response.status_code:
+                            response_args["status_code"] = (
+                                solved_result.response.status_code
+                            )
+                        content = await serialize_response(
+                            field=response_field,
+                            response_content=raw_response,
+                            include=response_model_include,
+                            exclude=response_model_exclude,
+                            by_alias=response_model_by_alias,
+                            exclude_unset=response_model_exclude_unset,
+                            exclude_defaults=response_model_exclude_defaults,
+                            exclude_none=response_model_exclude_none,
+                            is_coroutine=is_coroutine,
+                        )
+                        response = actual_response_class(content, **response_args)
+                        if not is_body_allowed_for_status_code(response.status_code):
+                            response.body = b""
+                        response.headers.raw.extend(solved_result.response.headers.raw)
+            if errors:
+                validation_error = RequestValidationError(
+                    _normalize_errors(errors), body=body
+                )
+                raise validation_error
+        if response is None:
+            raise FastAPIError(
+                "No response object was returned. There's a high chance that the "
+                "application code is raising an exception and a dependency with yield "
+                "has a block with a bare except, or a block with except Exception, "
+                "and is not raising the exception again. Read more about it in the "
+                "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except"
+            )
+        return response
+
+    return app
+
+
+def get_websocket_app(
+    dependant: Dependant,
+    dependency_overrides_provider: Optional[Any] = None,
+    embed_body_fields: bool = False,
+) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
+    async def app(websocket: WebSocket) -> None:
+        async with AsyncExitStack() as async_exit_stack:
+            # TODO: remove this scope later, after a few releases
+            # This scope fastapi_astack is no longer used by FastAPI, kept for
+            # compatibility, just in case
+            websocket.scope["fastapi_astack"] = async_exit_stack
+            solved_result = await solve_dependencies(
+                request=websocket,
+                dependant=dependant,
+                dependency_overrides_provider=dependency_overrides_provider,
+                async_exit_stack=async_exit_stack,
+                embed_body_fields=embed_body_fields,
+            )
+            if solved_result.errors:
+                raise WebSocketRequestValidationError(
+                    _normalize_errors(solved_result.errors)
+                )
+            assert dependant.call is not None, "dependant.call must be a function"
+            await dependant.call(**solved_result.values)
+
+    return app
+
+
+class APIWebSocketRoute(routing.WebSocketRoute):
+    def __init__(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        *,
+        name: Optional[str] = None,
+        dependencies: Optional[Sequence[params.Depends]] = None,
+        dependency_overrides_provider: Optional[Any] = None,
+    ) -> None:
+        self.path = path
+        self.endpoint = endpoint
+        self.name = get_name(endpoint) if name is None else name
+        self.dependencies = list(dependencies or [])
+        self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+        self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
+        for depends in self.dependencies[::-1]:
+            self.dependant.dependencies.insert(
+                0,
+                get_parameterless_sub_dependant(depends=depends, path=self.path_format),
+            )
+        self._flat_dependant = get_flat_dependant(self.dependant)
+        self._embed_body_fields = _should_embed_body_fields(
+            self._flat_dependant.body_params
+        )
+        self.app = websocket_session(
+            get_websocket_app(
+                dependant=self.dependant,
+                dependency_overrides_provider=dependency_overrides_provider,
+                embed_body_fields=self._embed_body_fields,
+            )
+        )
+
+    def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+        match, child_scope = super().matches(scope)
+        if match != Match.NONE:
+            child_scope["route"] = self
+        return match, child_scope
+
+
+class APIRoute(routing.Route):
+    def __init__(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        *,
+        response_model: Any = Default(None),
+        status_code: Optional[int] = 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,
+        deprecated: Optional[bool] = None,
+        name: Optional[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_by_alias: bool = True,
+        response_model_exclude_unset: bool = False,
+        response_model_exclude_defaults: bool = False,
+        response_model_exclude_none: bool = False,
+        include_in_schema: bool = True,
+        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,
+        generate_unique_id_function: Union[
+            Callable[["APIRoute"], str], DefaultPlaceholder
+        ] = Default(generate_unique_id),
+    ) -> None:
+        self.path = path
+        self.endpoint = endpoint
+        if isinstance(response_model, DefaultPlaceholder):
+            return_annotation = get_typed_return_annotation(endpoint)
+            if lenient_issubclass(return_annotation, Response):
+                response_model = None
+            else:
+                response_model = return_annotation
+        self.response_model = response_model
+        self.summary = summary
+        self.response_description = response_description
+        self.deprecated = deprecated
+        self.operation_id = operation_id
+        self.response_model_include = response_model_include
+        self.response_model_exclude = response_model_exclude
+        self.response_model_by_alias = response_model_by_alias
+        self.response_model_exclude_unset = response_model_exclude_unset
+        self.response_model_exclude_defaults = response_model_exclude_defaults
+        self.response_model_exclude_none = response_model_exclude_none
+        self.include_in_schema = include_in_schema
+        self.response_class = response_class
+        self.dependency_overrides_provider = dependency_overrides_provider
+        self.callbacks = callbacks
+        self.openapi_extra = openapi_extra
+        self.generate_unique_id_function = generate_unique_id_function
+        self.tags = tags or []
+        self.responses = responses or {}
+        self.name = get_name(endpoint) if name is None else name
+        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}
+        if isinstance(generate_unique_id_function, DefaultPlaceholder):
+            current_generate_unique_id: Callable[[APIRoute], str] = (
+                generate_unique_id_function.value
+            )
+        else:
+            current_generate_unique_id = generate_unique_id_function
+        self.unique_id = self.operation_id or current_generate_unique_id(self)
+        # normalize enums e.g. http.HTTPStatus
+        if isinstance(status_code, IntEnum):
+            status_code = int(status_code)
+        self.status_code = status_code
+        if self.response_model:
+            assert is_body_allowed_for_status_code(status_code), (
+                f"Status code {status_code} must not have a response body"
+            )
+            response_name = "Response_" + self.unique_id
+            self.response_field = create_model_field(
+                name=response_name,
+                type_=self.response_model,
+                mode="serialization",
+            )
+            # Create a clone of the field, so that a Pydantic submodel is not returned
+            # as is just because it's an instance of a subclass of a more limited class
+            # e.g. UserInDB (containing hashed_password) could be a subclass of User
+            # that doesn't have the hashed_password. But because it's a subclass, it
+            # would pass the validation and be returned as is.
+            # By being a new field, no inheritance will be passed as is. A new model
+            # will always be created.
+            # TODO: remove when deprecating Pydantic v1
+            self.secure_cloned_response_field: Optional[ModelField] = (
+                create_cloned_field(self.response_field)
+            )
+        else:
+            self.response_field = None  # type: ignore
+            self.secure_cloned_response_field = None
+        self.dependencies = list(dependencies or [])
+        self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "")
+        # if a "form feed" character (page break) is found in the description text,
+        # truncate description text to the content preceding the first "form feed"
+        self.description = self.description.split("\f")[0].strip()
+        response_fields = {}
+        for additional_status_code, response in self.responses.items():
+            assert isinstance(response, dict), "An additional response must be a dict"
+            model = response.get("model")
+            if model:
+                assert is_body_allowed_for_status_code(additional_status_code), (
+                    f"Status code {additional_status_code} must not have a response body"
+                )
+                response_name = f"Response_{additional_status_code}_{self.unique_id}"
+                response_field = create_model_field(
+                    name=response_name, type_=model, mode="serialization"
+                )
+                response_fields[additional_status_code] = response_field
+        if response_fields:
+            self.response_fields: Dict[Union[int, str], ModelField] = response_fields
+        else:
+            self.response_fields = {}
+
+        assert callable(endpoint), "An endpoint must be a callable"
+        self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
+        for depends in self.dependencies[::-1]:
+            self.dependant.dependencies.insert(
+                0,
+                get_parameterless_sub_dependant(depends=depends, path=self.path_format),
+            )
+        self._flat_dependant = get_flat_dependant(self.dependant)
+        self._embed_body_fields = _should_embed_body_fields(
+            self._flat_dependant.body_params
+        )
+        self.body_field = get_body_field(
+            flat_dependant=self._flat_dependant,
+            name=self.unique_id,
+            embed_body_fields=self._embed_body_fields,
+        )
+        self.app = request_response(self.get_route_handler())
+
+    def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
+        return get_request_handler(
+            dependant=self.dependant,
+            body_field=self.body_field,
+            status_code=self.status_code,
+            response_class=self.response_class,
+            response_field=self.secure_cloned_response_field,
+            response_model_include=self.response_model_include,
+            response_model_exclude=self.response_model_exclude,
+            response_model_by_alias=self.response_model_by_alias,
+            response_model_exclude_unset=self.response_model_exclude_unset,
+            response_model_exclude_defaults=self.response_model_exclude_defaults,
+            response_model_exclude_none=self.response_model_exclude_none,
+            dependency_overrides_provider=self.dependency_overrides_provider,
+            embed_body_fields=self._embed_body_fields,
+        )
+
+    def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+        match, child_scope = super().matches(scope)
+        if match != Match.NONE:
+            child_scope["route"] = self
+        return match, child_scope
+
+
+class APIRouter(routing.Router):
+    """
+    `APIRouter` class, used to group *path operations*, for example to structure
+    an app in multiple files. It would then be included in the `FastAPI` app, or
+    in another `APIRouter` (ultimately included in the app).
+
+    Read more about it in the
+    [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+    ## Example
+
+    ```python
+    from fastapi import APIRouter, FastAPI
+
+    app = FastAPI()
+    router = APIRouter()
+
+
+    @router.get("/users/", tags=["users"])
+    async def read_users():
+        return [{"username": "Rick"}, {"username": "Morty"}]
+
+
+    app.include_router(router)
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to all the *path operations* in this
+                router.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to all the
+                *path operations* in this router.
+
+                Read more about it in the
+                [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        default_response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                The default response class to be used.
+
+                Read more in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+                """
+            ),
+        ] = Default(JSONResponse),
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses to be shown in OpenAPI.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+                And in the
+                [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                OpenAPI callbacks that should apply to all *path operations* in this
+                router.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        routes: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                **Note**: you probably shouldn't use this parameter, it is inherited
+                from Starlette and supported for compatibility.
+
+                ---
+
+                A list of routes to serve incoming HTTP and WebSocket requests.
+                """
+            ),
+            deprecated(
+                """
+                You normally wouldn't use this parameter with FastAPI, it is inherited
+                from Starlette and supported for compatibility.
+
+                In FastAPI, you normally would use the *path operation methods*,
+                like `router.get()`, `router.post()`, etc.
+                """
+            ),
+        ] = None,
+        redirect_slashes: Annotated[
+            bool,
+            Doc(
+                """
+                Whether to detect and redirect slashes in URLs when the client doesn't
+                use the same format.
+                """
+            ),
+        ] = True,
+        default: Annotated[
+            Optional[ASGIApp],
+            Doc(
+                """
+                Default function handler for this router. Used to handle
+                404 Not Found errors.
+                """
+            ),
+        ] = None,
+        dependency_overrides_provider: Annotated[
+            Optional[Any],
+            Doc(
+                """
+                Only used internally by FastAPI to handle dependency overrides.
+
+                You shouldn't need to use it. It normally points to the `FastAPI` app
+                object.
+                """
+            ),
+        ] = None,
+        route_class: Annotated[
+            Type[APIRoute],
+            Doc(
+                """
+                Custom route (*path operation*) class to be used by this router.
+
+                Read more about it in the
+                [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router).
+                """
+            ),
+        ] = APIRoute,
+        on_startup: Annotated[
+            Optional[Sequence[Callable[[], Any]]],
+            Doc(
+                """
+                A list of startup event handler functions.
+
+                You should instead use the `lifespan` handlers.
+
+                Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        on_shutdown: Annotated[
+            Optional[Sequence[Callable[[], Any]]],
+            Doc(
+                """
+                A list of shutdown event handler functions.
+
+                You should instead use the `lifespan` handlers.
+
+                Read more in the
+                [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        # the generic to Lifespan[AppType] is the type of the top level application
+        # which the router cannot know statically, so we use typing.Any
+        lifespan: Annotated[
+            Optional[Lifespan[Any]],
+            Doc(
+                """
+                A `Lifespan` context manager handler. This replaces `startup` and
+                `shutdown` functions with a single context manager.
+
+                Read more in the
+                [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark all *path operations* in this router as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                To include (or not) all the *path operations* in this router in the
+                generated OpenAPI.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> None:
+        super().__init__(
+            routes=routes,
+            redirect_slashes=redirect_slashes,
+            default=default,
+            on_startup=on_startup,
+            on_shutdown=on_shutdown,
+            lifespan=lifespan,
+        )
+        if prefix:
+            assert prefix.startswith("/"), "A path prefix must start with '/'"
+            assert not prefix.endswith("/"), (
+                "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.dependencies = list(dependencies or [])
+        self.deprecated = deprecated
+        self.include_in_schema = include_in_schema
+        self.responses = responses or {}
+        self.callbacks = callbacks or []
+        self.dependency_overrides_provider = dependency_overrides_provider
+        self.route_class = route_class
+        self.default_response_class = default_response_class
+        self.generate_unique_id_function = generate_unique_id_function
+
+    def route(
+        self,
+        path: str,
+        methods: Optional[List[str]] = None,
+        name: Optional[str] = None,
+        include_in_schema: bool = True,
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_route(
+                path,
+                func,
+                methods=methods,
+                name=name,
+                include_in_schema=include_in_schema,
+            )
+            return func
+
+        return decorator
+
+    def add_api_route(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        *,
+        response_model: Any = Default(None),
+        status_code: Optional[int] = 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,
+        deprecated: Optional[bool] = 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_by_alias: bool = True,
+        response_model_exclude_unset: bool = False,
+        response_model_exclude_defaults: bool = False,
+        response_model_exclude_none: bool = False,
+        include_in_schema: bool = True,
+        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,
+        generate_unique_id_function: Union[
+            Callable[[APIRoute], str], DefaultPlaceholder
+        ] = Default(generate_unique_id),
+    ) -> None:
+        route_class = route_class_override or self.route_class
+        responses = responses or {}
+        combined_responses = {**self.responses, **responses}
+        current_response_class = get_value_or_default(
+            response_class, self.default_response_class
+        )
+        current_tags = self.tags.copy()
+        if tags:
+            current_tags.extend(tags)
+        current_dependencies = self.dependencies.copy()
+        if dependencies:
+            current_dependencies.extend(dependencies)
+        current_callbacks = self.callbacks.copy()
+        if callbacks:
+            current_callbacks.extend(callbacks)
+        current_generate_unique_id = get_value_or_default(
+            generate_unique_id_function, self.generate_unique_id_function
+        )
+        route = route_class(
+            self.prefix + path,
+            endpoint=endpoint,
+            response_model=response_model,
+            status_code=status_code,
+            tags=current_tags,
+            dependencies=current_dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=combined_responses,
+            deprecated=deprecated or self.deprecated,
+            methods=methods,
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema and self.include_in_schema,
+            response_class=current_response_class,
+            name=name,
+            dependency_overrides_provider=self.dependency_overrides_provider,
+            callbacks=current_callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=current_generate_unique_id,
+        )
+        self.routes.append(route)
+
+    def api_route(
+        self,
+        path: str,
+        *,
+        response_model: Any = Default(None),
+        status_code: Optional[int] = None,
+        tags: Optional[List[Union[str, Enum]]] = None,
+        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,
+        deprecated: Optional[bool] = 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_by_alias: bool = True,
+        response_model_exclude_unset: bool = False,
+        response_model_exclude_defaults: bool = False,
+        response_model_exclude_none: bool = False,
+        include_in_schema: bool = True,
+        response_class: Type[Response] = Default(JSONResponse),
+        name: Optional[str] = None,
+        callbacks: Optional[List[BaseRoute]] = None,
+        openapi_extra: Optional[Dict[str, Any]] = None,
+        generate_unique_id_function: Callable[[APIRoute], str] = Default(
+            generate_unique_id
+        ),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_api_route(
+                path,
+                func,
+                response_model=response_model,
+                status_code=status_code,
+                tags=tags,
+                dependencies=dependencies,
+                summary=summary,
+                description=description,
+                response_description=response_description,
+                responses=responses,
+                deprecated=deprecated,
+                methods=methods,
+                operation_id=operation_id,
+                response_model_include=response_model_include,
+                response_model_exclude=response_model_exclude,
+                response_model_by_alias=response_model_by_alias,
+                response_model_exclude_unset=response_model_exclude_unset,
+                response_model_exclude_defaults=response_model_exclude_defaults,
+                response_model_exclude_none=response_model_exclude_none,
+                include_in_schema=include_in_schema,
+                response_class=response_class,
+                name=name,
+                callbacks=callbacks,
+                openapi_extra=openapi_extra,
+                generate_unique_id_function=generate_unique_id_function,
+            )
+            return func
+
+        return decorator
+
+    def add_api_websocket_route(
+        self,
+        path: str,
+        endpoint: Callable[..., Any],
+        name: Optional[str] = None,
+        *,
+        dependencies: Optional[Sequence[params.Depends]] = None,
+    ) -> None:
+        current_dependencies = self.dependencies.copy()
+        if dependencies:
+            current_dependencies.extend(dependencies)
+
+        route = APIWebSocketRoute(
+            self.prefix + path,
+            endpoint=endpoint,
+            name=name,
+            dependencies=current_dependencies,
+            dependency_overrides_provider=self.dependency_overrides_provider,
+        )
+        self.routes.append(route)
+
+    def websocket(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                WebSocket path.
+                """
+            ),
+        ],
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A name for the WebSocket. Only used internally.
+                """
+            ),
+        ] = None,
+        *,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be used for this
+                WebSocket.
+
+                Read more about it in the
+                [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+                """
+            ),
+        ] = None,
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Decorate a WebSocket function.
+
+        Read more about it in the
+        [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+        **Example**
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI, WebSocket
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.websocket("/ws")
+        async def websocket_endpoint(websocket: WebSocket):
+            await websocket.accept()
+            while True:
+                data = await websocket.receive_text()
+                await websocket.send_text(f"Message text was: {data}")
+
+        app.include_router(router)
+        ```
+        """
+
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_api_websocket_route(
+                path, func, name=name, dependencies=dependencies
+            )
+            return func
+
+        return decorator
+
+    def websocket_route(
+        self, path: str, name: Union[str, None] = None
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_websocket_route(path, func, name=name)
+            return func
+
+        return decorator
+
+    def include_router(
+        self,
+        router: Annotated["APIRouter", Doc("The `APIRouter` to include.")],
+        *,
+        prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to all the *path operations* in this
+                router.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to all the
+                *path operations* in this router.
+
+                Read more about it in the
+                [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        default_response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                The default response class to be used.
+
+                Read more in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+                """
+            ),
+        ] = Default(JSONResponse),
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses to be shown in OpenAPI.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+                And in the
+                [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                OpenAPI callbacks that should apply to all *path operations* in this
+                router.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark all *path operations* in this router as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include (or not) all the *path operations* in this router in the
+                generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = True,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> None:
+        """
+        Include another `APIRouter` in the same current `APIRouter`.
+
+        Read more about it in the
+        [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+
+        app = FastAPI()
+        internal_router = APIRouter()
+        users_router = APIRouter()
+
+        @users_router.get("/users/")
+        def read_users():
+            return [{"name": "Rick"}, {"name": "Morty"}]
+
+        internal_router.include_router(users_router)
+        app.include_router(internal_router)
+        ```
+        """
+        if prefix:
+            assert prefix.startswith("/"), "A path prefix must start with '/'"
+            assert not prefix.endswith("/"), (
+                "A path prefix must not end with '/', as the routes will start with '/'"
+            )
+        else:
+            for r in router.routes:
+                path = getattr(r, "path")  # noqa: B009
+                name = getattr(r, "name", "unknown")
+                if path is not None and not path:
+                    raise FastAPIError(
+                        f"Prefix and path cannot be both empty (path operation: {name})"
+                    )
+        if responses is None:
+            responses = {}
+        for route in router.routes:
+            if isinstance(route, APIRoute):
+                combined_responses = {**responses, **route.responses}
+                use_response_class = get_value_or_default(
+                    route.response_class,
+                    router.default_response_class,
+                    default_response_class,
+                    self.default_response_class,
+                )
+                current_tags = []
+                if tags:
+                    current_tags.extend(tags)
+                if route.tags:
+                    current_tags.extend(route.tags)
+                current_dependencies: List[params.Depends] = []
+                if dependencies:
+                    current_dependencies.extend(dependencies)
+                if route.dependencies:
+                    current_dependencies.extend(route.dependencies)
+                current_callbacks = []
+                if callbacks:
+                    current_callbacks.extend(callbacks)
+                if route.callbacks:
+                    current_callbacks.extend(route.callbacks)
+                current_generate_unique_id = get_value_or_default(
+                    route.generate_unique_id_function,
+                    router.generate_unique_id_function,
+                    generate_unique_id_function,
+                    self.generate_unique_id_function,
+                )
+                self.add_api_route(
+                    prefix + route.path,
+                    route.endpoint,
+                    response_model=route.response_model,
+                    status_code=route.status_code,
+                    tags=current_tags,
+                    dependencies=current_dependencies,
+                    summary=route.summary,
+                    description=route.description,
+                    response_description=route.response_description,
+                    responses=combined_responses,
+                    deprecated=route.deprecated or deprecated or self.deprecated,
+                    methods=route.methods,
+                    operation_id=route.operation_id,
+                    response_model_include=route.response_model_include,
+                    response_model_exclude=route.response_model_exclude,
+                    response_model_by_alias=route.response_model_by_alias,
+                    response_model_exclude_unset=route.response_model_exclude_unset,
+                    response_model_exclude_defaults=route.response_model_exclude_defaults,
+                    response_model_exclude_none=route.response_model_exclude_none,
+                    include_in_schema=route.include_in_schema
+                    and self.include_in_schema
+                    and include_in_schema,
+                    response_class=use_response_class,
+                    name=route.name,
+                    route_class_override=type(route),
+                    callbacks=current_callbacks,
+                    openapi_extra=route.openapi_extra,
+                    generate_unique_id_function=current_generate_unique_id,
+                )
+            elif isinstance(route, routing.Route):
+                methods = list(route.methods or [])
+                self.add_route(
+                    prefix + route.path,
+                    route.endpoint,
+                    methods=methods,
+                    include_in_schema=route.include_in_schema,
+                    name=route.name,
+                )
+            elif isinstance(route, APIWebSocketRoute):
+                current_dependencies = []
+                if dependencies:
+                    current_dependencies.extend(dependencies)
+                if route.dependencies:
+                    current_dependencies.extend(route.dependencies)
+                self.add_api_websocket_route(
+                    prefix + route.path,
+                    route.endpoint,
+                    dependencies=current_dependencies,
+                    name=route.name,
+                )
+            elif isinstance(route, routing.WebSocketRoute):
+                self.add_websocket_route(
+                    prefix + route.path, route.endpoint, name=route.name
+                )
+        for handler in router.on_startup:
+            self.add_event_handler("startup", handler)
+        for handler in router.on_shutdown:
+            self.add_event_handler("shutdown", handler)
+        self.lifespan_context = _merge_lifespan_context(
+            self.lifespan_context,
+            router.lifespan_context,
+        )
+
+    def get(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP GET operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.get("/items/")
+        def read_items():
+            return [{"name": "Empanada"}, {"name": "Arepa"}]
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["GET"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def put(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP PUT operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.put("/items/{item_id}")
+        def replace_item(item_id: str, item: Item):
+            return {"message": "Item replaced", "id": item_id}
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["PUT"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def post(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP POST operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.post("/items/")
+        def create_item(item: Item):
+            return {"message": "Item created"}
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["POST"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def delete(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP DELETE operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.delete("/items/{item_id}")
+        def delete_item(item_id: str):
+            return {"message": "Item deleted"}
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["DELETE"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def options(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP OPTIONS operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.options("/items/")
+        def get_item_options():
+            return {"additions": ["Aji", "Guacamole"]}
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["OPTIONS"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def head(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP HEAD operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.head("/items/", status_code=204)
+        def get_items_headers(response: Response):
+            response.headers["X-Cat-Dog"] = "Alone in the world"
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["HEAD"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def patch(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP PATCH operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.patch("/items/")
+        def update_item(item: Item):
+            return {"message": "Item updated in place"}
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["PATCH"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    def trace(
+        self,
+        path: Annotated[
+            str,
+            Doc(
+                """
+                The URL path to be used for this *path operation*.
+
+                For example, in `http://example.com/items`, the path is `/items`.
+                """
+            ),
+        ],
+        *,
+        response_model: Annotated[
+            Any,
+            Doc(
+                """
+                The type to use for the response.
+
+                It could be any valid Pydantic *field* type. So, it doesn't have to
+                be a Pydantic model, it could be other things, like a `list`, `dict`,
+                etc.
+
+                It will be used for:
+
+                * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+                    show it as the response (JSON Schema).
+                * Serialization: you could return an arbitrary object and the
+                    `response_model` would be used to serialize that object into the
+                    corresponding JSON.
+                * Filtering: the JSON sent to the client will only contain the data
+                    (fields) defined in the `response_model`. If you returned an object
+                    that contains an attribute `password` but the `response_model` does
+                    not include that field, the JSON sent to the client would not have
+                    that `password`.
+                * Validation: whatever you return will be serialized with the
+                    `response_model`, converting any data as necessary to generate the
+                    corresponding JSON. But if the data in the object returned is not
+                    valid, that would mean a violation of the contract with the client,
+                    so it's an error from the API developer. So, FastAPI will raise an
+                    error and return a 500 error code (Internal Server Error).
+
+                Read more about it in the
+                [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+                """
+            ),
+        ] = Default(None),
+        status_code: Annotated[
+            Optional[int],
+            Doc(
+                """
+                The default status code to be used for the response.
+
+                You could override the status code by returning a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+                """
+            ),
+        ] = None,
+        tags: Annotated[
+            Optional[List[Union[str, Enum]]],
+            Doc(
+                """
+                A list of tags to be applied to the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+                """
+            ),
+        ] = None,
+        dependencies: Annotated[
+            Optional[Sequence[params.Depends]],
+            Doc(
+                """
+                A list of dependencies (using `Depends()`) to be applied to the
+                *path operation*.
+
+                Read more about it in the
+                [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+                """
+            ),
+        ] = None,
+        summary: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A summary for the *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                A description for the *path operation*.
+
+                If not provided, it will be extracted automatically from the docstring
+                of the *path operation function*.
+
+                It can contain Markdown.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+                """
+            ),
+        ] = None,
+        response_description: Annotated[
+            str,
+            Doc(
+                """
+                The description for the default response.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = "Successful Response",
+        responses: Annotated[
+            Optional[Dict[Union[int, str], Dict[str, Any]]],
+            Doc(
+                """
+                Additional responses that could be returned by this *path operation*.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        deprecated: Annotated[
+            Optional[bool],
+            Doc(
+                """
+                Mark this *path operation* as deprecated.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        operation_id: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Custom operation ID to be used by this *path operation*.
+
+                By default, it is generated automatically.
+
+                If you provide a custom operation ID, you need to make sure it is
+                unique for the whole API.
+
+                You can customize the
+                operation ID generation with the parameter
+                `generate_unique_id_function` in the `FastAPI` class.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = None,
+        response_model_include: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to include only certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_exclude: Annotated[
+            Optional[IncEx],
+            Doc(
+                """
+                Configuration passed to Pydantic to exclude certain fields in the
+                response data.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = None,
+        response_model_by_alias: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response model
+                should be serialized by alias when an alias is used.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+                """
+            ),
+        ] = True,
+        response_model_exclude_unset: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that were not set and
+                have their default values. This is different from
+                `response_model_exclude_defaults` in that if the fields are set,
+                they will be included in the response, even if the value is the same
+                as the default.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_defaults: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data
+                should have all the fields, including the ones that have the same value
+                as the default. This is different from `response_model_exclude_unset`
+                in that if the fields are set but contain the same default values,
+                they will be excluded from the response.
+
+                When `True`, default values are omitted from the response.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+                """
+            ),
+        ] = False,
+        response_model_exclude_none: Annotated[
+            bool,
+            Doc(
+                """
+                Configuration passed to Pydantic to define if the response data should
+                exclude fields set to `None`.
+
+                This is much simpler (less smart) than `response_model_exclude_unset`
+                and `response_model_exclude_defaults`. You probably want to use one of
+                those two instead of this one, as those allow returning `None` values
+                when it makes sense.
+
+                Read more about it in the
+                [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+                """
+            ),
+        ] = False,
+        include_in_schema: Annotated[
+            bool,
+            Doc(
+                """
+                Include this *path operation* in the generated OpenAPI schema.
+
+                This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-from-openapi).
+                """
+            ),
+        ] = True,
+        response_class: Annotated[
+            Type[Response],
+            Doc(
+                """
+                Response class to be used for this *path operation*.
+
+                This will not be used if you return a response directly.
+
+                Read more about it in the
+                [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+                """
+            ),
+        ] = Default(JSONResponse),
+        name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Name for this *path operation*. Only used internally.
+                """
+            ),
+        ] = None,
+        callbacks: Annotated[
+            Optional[List[BaseRoute]],
+            Doc(
+                """
+                List of *path operations* that will be used as OpenAPI callbacks.
+
+                This is only for OpenAPI documentation, the callbacks won't be used
+                directly.
+
+                It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+                Read more about it in the
+                [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+                """
+            ),
+        ] = None,
+        openapi_extra: Annotated[
+            Optional[Dict[str, Any]],
+            Doc(
+                """
+                Extra metadata to be included in the OpenAPI schema for this *path
+                operation*.
+
+                Read more about it in the
+                [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+                """
+            ),
+        ] = None,
+        generate_unique_id_function: Annotated[
+            Callable[[APIRoute], str],
+            Doc(
+                """
+                Customize the function used to generate unique IDs for the *path
+                operations* shown in the generated OpenAPI.
+
+                This is particularly useful when automatically generating clients or
+                SDKs for your API.
+
+                Read more about it in the
+                [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+                """
+            ),
+        ] = Default(generate_unique_id),
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add a *path operation* using an HTTP TRACE operation.
+
+        ## Example
+
+        ```python
+        from fastapi import APIRouter, FastAPI
+        from pydantic import BaseModel
+
+        class Item(BaseModel):
+            name: str
+            description: str | None = None
+
+        app = FastAPI()
+        router = APIRouter()
+
+        @router.trace("/items/{item_id}")
+        def trace_item(item_id: str):
+            return None
+
+        app.include_router(router)
+        ```
+        """
+        return self.api_route(
+            path=path,
+            response_model=response_model,
+            status_code=status_code,
+            tags=tags,
+            dependencies=dependencies,
+            summary=summary,
+            description=description,
+            response_description=response_description,
+            responses=responses,
+            deprecated=deprecated,
+            methods=["TRACE"],
+            operation_id=operation_id,
+            response_model_include=response_model_include,
+            response_model_exclude=response_model_exclude,
+            response_model_by_alias=response_model_by_alias,
+            response_model_exclude_unset=response_model_exclude_unset,
+            response_model_exclude_defaults=response_model_exclude_defaults,
+            response_model_exclude_none=response_model_exclude_none,
+            include_in_schema=include_in_schema,
+            response_class=response_class,
+            name=name,
+            callbacks=callbacks,
+            openapi_extra=openapi_extra,
+            generate_unique_id_function=generate_unique_id_function,
+        )
+
+    @deprecated(
+        """
+        on_event is deprecated, use lifespan event handlers instead.
+
+        Read more about it in the
+        [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+        """
+    )
+    def on_event(
+        self,
+        event_type: Annotated[
+            str,
+            Doc(
+                """
+                The type of event. `startup` or `shutdown`.
+                """
+            ),
+        ],
+    ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+        """
+        Add an event handler for the router.
+
+        `on_event` is deprecated, use `lifespan` event handlers instead.
+
+        Read more about it in the
+        [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+        """
+
+        def decorator(func: DecoratedCallable) -> DecoratedCallable:
+            self.add_event_handler(event_type, func)
+            return func
+
+        return decorator
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/__init__.py b/.venv/lib/python3.12/site-packages/fastapi/security/__init__.py
new file mode 100644
index 00000000..3aa6bf21
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/__init__.py
@@ -0,0 +1,15 @@
+from .api_key import APIKeyCookie as APIKeyCookie
+from .api_key import APIKeyHeader as APIKeyHeader
+from .api_key import APIKeyQuery as APIKeyQuery
+from .http import HTTPAuthorizationCredentials as HTTPAuthorizationCredentials
+from .http import HTTPBasic as HTTPBasic
+from .http import HTTPBasicCredentials as HTTPBasicCredentials
+from .http import HTTPBearer as HTTPBearer
+from .http import HTTPDigest as HTTPDigest
+from .oauth2 import OAuth2 as OAuth2
+from .oauth2 import OAuth2AuthorizationCodeBearer as OAuth2AuthorizationCodeBearer
+from .oauth2 import OAuth2PasswordBearer as OAuth2PasswordBearer
+from .oauth2 import OAuth2PasswordRequestForm as OAuth2PasswordRequestForm
+from .oauth2 import OAuth2PasswordRequestFormStrict as OAuth2PasswordRequestFormStrict
+from .oauth2 import SecurityScopes as SecurityScopes
+from .open_id_connect_url import OpenIdConnect as OpenIdConnect
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/api_key.py b/.venv/lib/python3.12/site-packages/fastapi/security/api_key.py
new file mode 100644
index 00000000..70c2dca8
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/api_key.py
@@ -0,0 +1,288 @@
+from typing import Optional
+
+from fastapi.openapi.models import APIKey, APIKeyIn
+from fastapi.security.base import SecurityBase
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class APIKeyBase(SecurityBase):
+    @staticmethod
+    def check_api_key(api_key: Optional[str], auto_error: bool) -> Optional[str]:
+        if not api_key:
+            if auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            return None
+        return api_key
+
+
+class APIKeyQuery(APIKeyBase):
+    """
+    API key authentication using a query parameter.
+
+    This defines the name of the query parameter that should be provided in the request
+    with the API key and integrates that into the OpenAPI documentation. It extracts
+    the key value sent in the query parameter automatically and provides it as the
+    dependency result. But it doesn't define how to send that API key to the client.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be a string containing the key value.
+
+    ## Example
+
+    ```python
+    from fastapi import Depends, FastAPI
+    from fastapi.security import APIKeyQuery
+
+    app = FastAPI()
+
+    query_scheme = APIKeyQuery(name="api_key")
+
+
+    @app.get("/items/")
+    async def read_items(api_key: str = Depends(query_scheme)):
+        return {"api_key": api_key}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        name: Annotated[
+            str,
+            Doc("Query parameter name."),
+        ],
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the query parameter is not provided, `APIKeyQuery` will
+                automatically cancel the request and send the client an error.
+
+                If `auto_error` is set to `False`, when the query parameter is not
+                available, instead of erroring out, the dependency result will be
+                `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in a query
+                parameter or in an HTTP Bearer token).
+                """
+            ),
+        ] = True,
+    ):
+        self.model: APIKey = APIKey(
+            **{"in": APIKeyIn.query},  # type: ignore[arg-type]
+            name=name,
+            description=description,
+        )
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        api_key = request.query_params.get(self.model.name)
+        return self.check_api_key(api_key, self.auto_error)
+
+
+class APIKeyHeader(APIKeyBase):
+    """
+    API key authentication using a header.
+
+    This defines the name of the header that should be provided in the request with
+    the API key and integrates that into the OpenAPI documentation. It extracts
+    the key value sent in the header automatically and provides it as the dependency
+    result. But it doesn't define how to send that key to the client.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be a string containing the key value.
+
+    ## Example
+
+    ```python
+    from fastapi import Depends, FastAPI
+    from fastapi.security import APIKeyHeader
+
+    app = FastAPI()
+
+    header_scheme = APIKeyHeader(name="x-key")
+
+
+    @app.get("/items/")
+    async def read_items(key: str = Depends(header_scheme)):
+        return {"key": key}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        name: Annotated[str, Doc("Header name.")],
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the header is not provided, `APIKeyHeader` will
+                automatically cancel the request and send the client an error.
+
+                If `auto_error` is set to `False`, when the header is not available,
+                instead of erroring out, the dependency result will be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in a header or
+                in an HTTP Bearer token).
+                """
+            ),
+        ] = True,
+    ):
+        self.model: APIKey = APIKey(
+            **{"in": APIKeyIn.header},  # type: ignore[arg-type]
+            name=name,
+            description=description,
+        )
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        api_key = request.headers.get(self.model.name)
+        return self.check_api_key(api_key, self.auto_error)
+
+
+class APIKeyCookie(APIKeyBase):
+    """
+    API key authentication using a cookie.
+
+    This defines the name of the cookie that should be provided in the request with
+    the API key and integrates that into the OpenAPI documentation. It extracts
+    the key value sent in the cookie automatically and provides it as the dependency
+    result. But it doesn't define how to set that cookie.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be a string containing the key value.
+
+    ## Example
+
+    ```python
+    from fastapi import Depends, FastAPI
+    from fastapi.security import APIKeyCookie
+
+    app = FastAPI()
+
+    cookie_scheme = APIKeyCookie(name="session")
+
+
+    @app.get("/items/")
+    async def read_items(session: str = Depends(cookie_scheme)):
+        return {"session": session}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        name: Annotated[str, Doc("Cookie name.")],
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the cookie is not provided, `APIKeyCookie` will
+                automatically cancel the request and send the client an error.
+
+                If `auto_error` is set to `False`, when the cookie is not available,
+                instead of erroring out, the dependency result will be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in a cookie or
+                in an HTTP Bearer token).
+                """
+            ),
+        ] = True,
+    ):
+        self.model: APIKey = APIKey(
+            **{"in": APIKeyIn.cookie},  # type: ignore[arg-type]
+            name=name,
+            description=description,
+        )
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        api_key = request.cookies.get(self.model.name)
+        return self.check_api_key(api_key, self.auto_error)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/base.py b/.venv/lib/python3.12/site-packages/fastapi/security/base.py
new file mode 100644
index 00000000..c43555de
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/base.py
@@ -0,0 +1,6 @@
+from fastapi.openapi.models import SecurityBase as SecurityBaseModel
+
+
+class SecurityBase:
+    model: SecurityBaseModel
+    scheme_name: str
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/http.py b/.venv/lib/python3.12/site-packages/fastapi/security/http.py
new file mode 100644
index 00000000..9ab2df3c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/http.py
@@ -0,0 +1,423 @@
+import binascii
+from base64 import b64decode
+from typing import Optional
+
+from fastapi.exceptions import HTTPException
+from fastapi.openapi.models import HTTPBase as HTTPBaseModel
+from fastapi.openapi.models import HTTPBearer as HTTPBearerModel
+from fastapi.security.base import SecurityBase
+from fastapi.security.utils import get_authorization_scheme_param
+from pydantic import BaseModel
+from starlette.requests import Request
+from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class HTTPBasicCredentials(BaseModel):
+    """
+    The HTTP Basic credentials given as the result of using `HTTPBasic` in a
+    dependency.
+
+    Read more about it in the
+    [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+    """
+
+    username: Annotated[str, Doc("The HTTP Basic username.")]
+    password: Annotated[str, Doc("The HTTP Basic password.")]
+
+
+class HTTPAuthorizationCredentials(BaseModel):
+    """
+    The HTTP authorization credentials in the result of using `HTTPBearer` or
+    `HTTPDigest` in a dependency.
+
+    The HTTP authorization header value is split by the first space.
+
+    The first part is the `scheme`, the second part is the `credentials`.
+
+    For example, in an HTTP Bearer token scheme, the client will send a header
+    like:
+
+    ```
+    Authorization: Bearer deadbeef12346
+    ```
+
+    In this case:
+
+    * `scheme` will have the value `"Bearer"`
+    * `credentials` will have the value `"deadbeef12346"`
+    """
+
+    scheme: Annotated[
+        str,
+        Doc(
+            """
+            The HTTP authorization scheme extracted from the header value.
+            """
+        ),
+    ]
+    credentials: Annotated[
+        str,
+        Doc(
+            """
+            The HTTP authorization credentials extracted from the header value.
+            """
+        ),
+    ]
+
+
+class HTTPBase(SecurityBase):
+    def __init__(
+        self,
+        *,
+        scheme: str,
+        scheme_name: Optional[str] = None,
+        description: Optional[str] = None,
+        auto_error: bool = True,
+    ):
+        self.model = HTTPBaseModel(scheme=scheme, description=description)
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(
+        self, request: Request
+    ) -> Optional[HTTPAuthorizationCredentials]:
+        authorization = request.headers.get("Authorization")
+        scheme, credentials = get_authorization_scheme_param(authorization)
+        if not (authorization and scheme and credentials):
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            else:
+                return None
+        return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
+
+
+class HTTPBasic(HTTPBase):
+    """
+    HTTP Basic authentication.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be an `HTTPBasicCredentials` object containing the
+    `username` and the `password`.
+
+    Read more about it in the
+    [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+    from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+    app = FastAPI()
+
+    security = HTTPBasic()
+
+
+    @app.get("/users/me")
+    def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
+        return {"username": credentials.username, "password": credentials.password}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        realm: Annotated[
+            Optional[str],
+            Doc(
+                """
+                HTTP Basic authentication realm.
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the HTTP Basic authentication is not provided (a
+                header), `HTTPBasic` will automatically cancel the request and send the
+                client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Basic authentication
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in HTTP Basic
+                authentication or in an HTTP Bearer token).
+                """
+            ),
+        ] = True,
+    ):
+        self.model = HTTPBaseModel(scheme="basic", description=description)
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.realm = realm
+        self.auto_error = auto_error
+
+    async def __call__(  # type: ignore
+        self, request: Request
+    ) -> Optional[HTTPBasicCredentials]:
+        authorization = request.headers.get("Authorization")
+        scheme, param = get_authorization_scheme_param(authorization)
+        if self.realm:
+            unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
+        else:
+            unauthorized_headers = {"WWW-Authenticate": "Basic"}
+        if not authorization or scheme.lower() != "basic":
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_401_UNAUTHORIZED,
+                    detail="Not authenticated",
+                    headers=unauthorized_headers,
+                )
+            else:
+                return None
+        invalid_user_credentials_exc = HTTPException(
+            status_code=HTTP_401_UNAUTHORIZED,
+            detail="Invalid authentication credentials",
+            headers=unauthorized_headers,
+        )
+        try:
+            data = b64decode(param).decode("ascii")
+        except (ValueError, UnicodeDecodeError, binascii.Error):
+            raise invalid_user_credentials_exc  # noqa: B904
+        username, separator, password = data.partition(":")
+        if not separator:
+            raise invalid_user_credentials_exc
+        return HTTPBasicCredentials(username=username, password=password)
+
+
+class HTTPBearer(HTTPBase):
+    """
+    HTTP Bearer token authentication.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be an `HTTPAuthorizationCredentials` object containing
+    the `scheme` and the `credentials`.
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+    from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
+
+    app = FastAPI()
+
+    security = HTTPBearer()
+
+
+    @app.get("/users/me")
+    def read_current_user(
+        credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+    ):
+        return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        bearerFormat: Annotated[Optional[str], Doc("Bearer token format.")] = None,
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the HTTP Bearer token is not provided (in an
+                `Authorization` header), `HTTPBearer` will automatically cancel the
+                request and send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Bearer token
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in an HTTP
+                Bearer token or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        self.model = HTTPBearerModel(bearerFormat=bearerFormat, description=description)
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(
+        self, request: Request
+    ) -> Optional[HTTPAuthorizationCredentials]:
+        authorization = request.headers.get("Authorization")
+        scheme, credentials = get_authorization_scheme_param(authorization)
+        if not (authorization and scheme and credentials):
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            else:
+                return None
+        if scheme.lower() != "bearer":
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN,
+                    detail="Invalid authentication credentials",
+                )
+            else:
+                return None
+        return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
+
+
+class HTTPDigest(HTTPBase):
+    """
+    HTTP Digest authentication.
+
+    ## Usage
+
+    Create an instance object and use that object as the dependency in `Depends()`.
+
+    The dependency result will be an `HTTPAuthorizationCredentials` object containing
+    the `scheme` and the `credentials`.
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+    from fastapi.security import HTTPAuthorizationCredentials, HTTPDigest
+
+    app = FastAPI()
+
+    security = HTTPDigest()
+
+
+    @app.get("/users/me")
+    def read_current_user(
+        credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+    ):
+        return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+    ```
+    """
+
+    def __init__(
+        self,
+        *,
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if the HTTP Digest is not provided, `HTTPDigest` will
+                automatically cancel the request and send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Digest is not
+                available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, in HTTP
+                Digest or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        self.model = HTTPBaseModel(scheme="digest", description=description)
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(
+        self, request: Request
+    ) -> Optional[HTTPAuthorizationCredentials]:
+        authorization = request.headers.get("Authorization")
+        scheme, credentials = get_authorization_scheme_param(authorization)
+        if not (authorization and scheme and credentials):
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            else:
+                return None
+        if scheme.lower() != "digest":
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN,
+                    detail="Invalid authentication credentials",
+                )
+            else:
+                return None
+        return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/oauth2.py b/.venv/lib/python3.12/site-packages/fastapi/security/oauth2.py
new file mode 100644
index 00000000..5ffad598
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/oauth2.py
@@ -0,0 +1,638 @@
+from typing import Any, Dict, List, Optional, Union, cast
+
+from fastapi.exceptions import HTTPException
+from fastapi.openapi.models import OAuth2 as OAuth2Model
+from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
+from fastapi.param_functions import Form
+from fastapi.security.base import SecurityBase
+from fastapi.security.utils import get_authorization_scheme_param
+from starlette.requests import Request
+from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+
+# TODO: import from typing when deprecating Python 3.9
+from typing_extensions import Annotated, Doc
+
+
+class OAuth2PasswordRequestForm:
+    """
+    This is a dependency class to collect the `username` and `password` as form data
+    for an OAuth2 password flow.
+
+    The OAuth2 specification dictates that for a password flow the data should be
+    collected using form data (instead of JSON) and that it should have the specific
+    fields `username` and `password`.
+
+    All the initialization parameters are extracted from the request.
+
+    Read more about it in the
+    [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+    from fastapi.security import OAuth2PasswordRequestForm
+
+    app = FastAPI()
+
+
+    @app.post("/login")
+    def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
+        data = {}
+        data["scopes"] = []
+        for scope in form_data.scopes:
+            data["scopes"].append(scope)
+        if form_data.client_id:
+            data["client_id"] = form_data.client_id
+        if form_data.client_secret:
+            data["client_secret"] = form_data.client_secret
+        return data
+    ```
+
+    Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+    You could have custom internal logic to separate it by colon characters (`:`) or
+    similar, and get the two parts `items` and `read`. Many applications do that to
+    group and organize permissions, you could do it as well in your application, just
+    know that that it is application specific, it's not part of the specification.
+    """
+
+    def __init__(
+        self,
+        *,
+        grant_type: Annotated[
+            Union[str, None],
+            Form(pattern="^password$"),
+            Doc(
+                """
+                The OAuth2 spec says it is required and MUST be the fixed string
+                "password". Nevertheless, this dependency class is permissive and
+                allows not passing it. If you want to enforce it, use instead the
+                `OAuth2PasswordRequestFormStrict` dependency.
+                """
+            ),
+        ] = None,
+        username: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                `username` string. The OAuth2 spec requires the exact field name
+                `username`.
+                """
+            ),
+        ],
+        password: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                `password` string. The OAuth2 spec requires the exact field name
+                `password".
+                """
+            ),
+        ],
+        scope: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                A single string with actually several scopes separated by spaces. Each
+                scope is also a string.
+
+                For example, a single string with:
+
+                ```python
+                "items:read items:write users:read profile openid"
+                ````
+
+                would represent the scopes:
+
+                * `items:read`
+                * `items:write`
+                * `users:read`
+                * `profile`
+                * `openid`
+                """
+            ),
+        ] = "",
+        client_id: Annotated[
+            Union[str, None],
+            Form(),
+            Doc(
+                """
+                If there's a `client_id`, it can be sent as part of the form fields.
+                But the OAuth2 specification recommends sending the `client_id` and
+                `client_secret` (if any) using HTTP Basic auth.
+                """
+            ),
+        ] = None,
+        client_secret: Annotated[
+            Union[str, None],
+            Form(),
+            Doc(
+                """
+                If there's a `client_password` (and a `client_id`), they can be sent
+                as part of the form fields. But the OAuth2 specification recommends
+                sending the `client_id` and `client_secret` (if any) using HTTP Basic
+                auth.
+                """
+            ),
+        ] = None,
+    ):
+        self.grant_type = grant_type
+        self.username = username
+        self.password = password
+        self.scopes = scope.split()
+        self.client_id = client_id
+        self.client_secret = client_secret
+
+
+class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
+    """
+    This is a dependency class to collect the `username` and `password` as form data
+    for an OAuth2 password flow.
+
+    The OAuth2 specification dictates that for a password flow the data should be
+    collected using form data (instead of JSON) and that it should have the specific
+    fields `username` and `password`.
+
+    All the initialization parameters are extracted from the request.
+
+    The only difference between `OAuth2PasswordRequestFormStrict` and
+    `OAuth2PasswordRequestForm` is that `OAuth2PasswordRequestFormStrict` requires the
+    client to send the form field `grant_type` with the value `"password"`, which
+    is required in the OAuth2 specification (it seems that for no particular reason),
+    while for `OAuth2PasswordRequestForm` `grant_type` is optional.
+
+    Read more about it in the
+    [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+    ## Example
+
+    ```python
+    from typing import Annotated
+
+    from fastapi import Depends, FastAPI
+    from fastapi.security import OAuth2PasswordRequestForm
+
+    app = FastAPI()
+
+
+    @app.post("/login")
+    def login(form_data: Annotated[OAuth2PasswordRequestFormStrict, Depends()]):
+        data = {}
+        data["scopes"] = []
+        for scope in form_data.scopes:
+            data["scopes"].append(scope)
+        if form_data.client_id:
+            data["client_id"] = form_data.client_id
+        if form_data.client_secret:
+            data["client_secret"] = form_data.client_secret
+        return data
+    ```
+
+    Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+    You could have custom internal logic to separate it by colon characters (`:`) or
+    similar, and get the two parts `items` and `read`. Many applications do that to
+    group and organize permissions, you could do it as well in your application, just
+    know that that it is application specific, it's not part of the specification.
+
+
+    grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
+        This dependency is strict about it. If you want to be permissive, use instead the
+        OAuth2PasswordRequestForm dependency class.
+    username: username string. The OAuth2 spec requires the exact field name "username".
+    password: password string. The OAuth2 spec requires the exact field name "password".
+    scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
+        "items:read items:write users:read profile openid"
+    client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
+        using HTTP Basic auth, as: client_id:client_secret
+    client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
+        using HTTP Basic auth, as: client_id:client_secret
+    """
+
+    def __init__(
+        self,
+        grant_type: Annotated[
+            str,
+            Form(pattern="^password$"),
+            Doc(
+                """
+                The OAuth2 spec says it is required and MUST be the fixed string
+                "password". This dependency is strict about it. If you want to be
+                permissive, use instead the `OAuth2PasswordRequestForm` dependency
+                class.
+                """
+            ),
+        ],
+        username: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                `username` string. The OAuth2 spec requires the exact field name
+                `username`.
+                """
+            ),
+        ],
+        password: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                `password` string. The OAuth2 spec requires the exact field name
+                `password".
+                """
+            ),
+        ],
+        scope: Annotated[
+            str,
+            Form(),
+            Doc(
+                """
+                A single string with actually several scopes separated by spaces. Each
+                scope is also a string.
+
+                For example, a single string with:
+
+                ```python
+                "items:read items:write users:read profile openid"
+                ````
+
+                would represent the scopes:
+
+                * `items:read`
+                * `items:write`
+                * `users:read`
+                * `profile`
+                * `openid`
+                """
+            ),
+        ] = "",
+        client_id: Annotated[
+            Union[str, None],
+            Form(),
+            Doc(
+                """
+                If there's a `client_id`, it can be sent as part of the form fields.
+                But the OAuth2 specification recommends sending the `client_id` and
+                `client_secret` (if any) using HTTP Basic auth.
+                """
+            ),
+        ] = None,
+        client_secret: Annotated[
+            Union[str, None],
+            Form(),
+            Doc(
+                """
+                If there's a `client_password` (and a `client_id`), they can be sent
+                as part of the form fields. But the OAuth2 specification recommends
+                sending the `client_id` and `client_secret` (if any) using HTTP Basic
+                auth.
+                """
+            ),
+        ] = None,
+    ):
+        super().__init__(
+            grant_type=grant_type,
+            username=username,
+            password=password,
+            scope=scope,
+            client_id=client_id,
+            client_secret=client_secret,
+        )
+
+
+class OAuth2(SecurityBase):
+    """
+    This is the base class for OAuth2 authentication, an instance of it would be used
+    as a dependency. All other OAuth2 classes inherit from it and customize it for
+    each OAuth2 flow.
+
+    You normally would not create a new class inheriting from it but use one of the
+    existing subclasses, and maybe compose them if you want to support multiple flows.
+
+    Read more about it in the
+    [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/).
+    """
+
+    def __init__(
+        self,
+        *,
+        flows: Annotated[
+            Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]],
+            Doc(
+                """
+                The dictionary of OAuth2 flows.
+                """
+            ),
+        ] = OAuthFlowsModel(),
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if no HTTP Authorization header is provided, required for
+                OAuth2 authentication, it will automatically cancel the request and
+                send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Authorization header
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, with OAuth2
+                or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        self.model = OAuth2Model(
+            flows=cast(OAuthFlowsModel, flows), description=description
+        )
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        authorization = request.headers.get("Authorization")
+        if not authorization:
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            else:
+                return None
+        return authorization
+
+
+class OAuth2PasswordBearer(OAuth2):
+    """
+    OAuth2 flow for authentication using a bearer token obtained with a password.
+    An instance of it would be used as a dependency.
+
+    Read more about it in the
+    [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+    """
+
+    def __init__(
+        self,
+        tokenUrl: Annotated[
+            str,
+            Doc(
+                """
+                The URL to obtain the OAuth2 token. This would be the *path operation*
+                that has `OAuth2PasswordRequestForm` as a dependency.
+                """
+            ),
+        ],
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        scopes: Annotated[
+            Optional[Dict[str, str]],
+            Doc(
+                """
+                The OAuth2 scopes that would be required by the *path operations* that
+                use this dependency.
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if no HTTP Authorization header is provided, required for
+                OAuth2 authentication, it will automatically cancel the request and
+                send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Authorization header
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, with OAuth2
+                or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        if not scopes:
+            scopes = {}
+        flows = OAuthFlowsModel(
+            password=cast(Any, {"tokenUrl": tokenUrl, "scopes": scopes})
+        )
+        super().__init__(
+            flows=flows,
+            scheme_name=scheme_name,
+            description=description,
+            auto_error=auto_error,
+        )
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        authorization = request.headers.get("Authorization")
+        scheme, param = get_authorization_scheme_param(authorization)
+        if not authorization or scheme.lower() != "bearer":
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_401_UNAUTHORIZED,
+                    detail="Not authenticated",
+                    headers={"WWW-Authenticate": "Bearer"},
+                )
+            else:
+                return None
+        return param
+
+
+class OAuth2AuthorizationCodeBearer(OAuth2):
+    """
+    OAuth2 flow for authentication using a bearer token obtained with an OAuth2 code
+    flow. An instance of it would be used as a dependency.
+    """
+
+    def __init__(
+        self,
+        authorizationUrl: str,
+        tokenUrl: Annotated[
+            str,
+            Doc(
+                """
+                The URL to obtain the OAuth2 token.
+                """
+            ),
+        ],
+        refreshUrl: Annotated[
+            Optional[str],
+            Doc(
+                """
+                The URL to refresh the token and obtain a new one.
+                """
+            ),
+        ] = None,
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        scopes: Annotated[
+            Optional[Dict[str, str]],
+            Doc(
+                """
+                The OAuth2 scopes that would be required by the *path operations* that
+                use this dependency.
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if no HTTP Authorization header is provided, required for
+                OAuth2 authentication, it will automatically cancel the request and
+                send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Authorization header
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, with OAuth2
+                or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        if not scopes:
+            scopes = {}
+        flows = OAuthFlowsModel(
+            authorizationCode=cast(
+                Any,
+                {
+                    "authorizationUrl": authorizationUrl,
+                    "tokenUrl": tokenUrl,
+                    "refreshUrl": refreshUrl,
+                    "scopes": scopes,
+                },
+            )
+        )
+        super().__init__(
+            flows=flows,
+            scheme_name=scheme_name,
+            description=description,
+            auto_error=auto_error,
+        )
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        authorization = request.headers.get("Authorization")
+        scheme, param = get_authorization_scheme_param(authorization)
+        if not authorization or scheme.lower() != "bearer":
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_401_UNAUTHORIZED,
+                    detail="Not authenticated",
+                    headers={"WWW-Authenticate": "Bearer"},
+                )
+            else:
+                return None  # pragma: nocover
+        return param
+
+
+class SecurityScopes:
+    """
+    This is a special class that you can define in a parameter in a dependency to
+    obtain the OAuth2 scopes required by all the dependencies in the same chain.
+
+    This way, multiple dependencies can have different scopes, even when used in the
+    same *path operation*. And with this, you can access all the scopes required in
+    all those dependencies in a single place.
+
+    Read more about it in the
+    [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+    """
+
+    def __init__(
+        self,
+        scopes: Annotated[
+            Optional[List[str]],
+            Doc(
+                """
+                This will be filled by FastAPI.
+                """
+            ),
+        ] = None,
+    ):
+        self.scopes: Annotated[
+            List[str],
+            Doc(
+                """
+                The list of all the scopes required by dependencies.
+                """
+            ),
+        ] = scopes or []
+        self.scope_str: Annotated[
+            str,
+            Doc(
+                """
+                All the scopes required by all the dependencies in a single string
+                separated by spaces, as defined in the OAuth2 specification.
+                """
+            ),
+        ] = " ".join(self.scopes)
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/open_id_connect_url.py b/.venv/lib/python3.12/site-packages/fastapi/security/open_id_connect_url.py
new file mode 100644
index 00000000..c8cceb91
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/open_id_connect_url.py
@@ -0,0 +1,84 @@
+from typing import Optional
+
+from fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel
+from fastapi.security.base import SecurityBase
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class OpenIdConnect(SecurityBase):
+    """
+    OpenID Connect authentication class. An instance of it would be used as a
+    dependency.
+    """
+
+    def __init__(
+        self,
+        *,
+        openIdConnectUrl: Annotated[
+            str,
+            Doc(
+                """
+            The OpenID Connect URL.
+            """
+            ),
+        ],
+        scheme_name: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme name.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        description: Annotated[
+            Optional[str],
+            Doc(
+                """
+                Security scheme description.
+
+                It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+                """
+            ),
+        ] = None,
+        auto_error: Annotated[
+            bool,
+            Doc(
+                """
+                By default, if no HTTP Authorization header is provided, required for
+                OpenID Connect authentication, it will automatically cancel the request
+                and send the client an error.
+
+                If `auto_error` is set to `False`, when the HTTP Authorization header
+                is not available, instead of erroring out, the dependency result will
+                be `None`.
+
+                This is useful when you want to have optional authentication.
+
+                It is also useful when you want to have authentication that can be
+                provided in one of multiple optional ways (for example, with OpenID
+                Connect or in a cookie).
+                """
+            ),
+        ] = True,
+    ):
+        self.model = OpenIdConnectModel(
+            openIdConnectUrl=openIdConnectUrl, description=description
+        )
+        self.scheme_name = scheme_name or self.__class__.__name__
+        self.auto_error = auto_error
+
+    async def __call__(self, request: Request) -> Optional[str]:
+        authorization = request.headers.get("Authorization")
+        if not authorization:
+            if self.auto_error:
+                raise HTTPException(
+                    status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+                )
+            else:
+                return None
+        return authorization
diff --git a/.venv/lib/python3.12/site-packages/fastapi/security/utils.py b/.venv/lib/python3.12/site-packages/fastapi/security/utils.py
new file mode 100644
index 00000000..fa7a450b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/security/utils.py
@@ -0,0 +1,10 @@
+from typing import Optional, Tuple
+
+
+def get_authorization_scheme_param(
+    authorization_header_value: Optional[str],
+) -> Tuple[str, str]:
+    if not authorization_header_value:
+        return "", ""
+    scheme, _, param = authorization_header_value.partition(" ")
+    return scheme, param
diff --git a/.venv/lib/python3.12/site-packages/fastapi/staticfiles.py b/.venv/lib/python3.12/site-packages/fastapi/staticfiles.py
new file mode 100644
index 00000000..299015d4
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/staticfiles.py
@@ -0,0 +1 @@
+from starlette.staticfiles import StaticFiles as StaticFiles  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/templating.py b/.venv/lib/python3.12/site-packages/fastapi/templating.py
new file mode 100644
index 00000000..0cb86848
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/templating.py
@@ -0,0 +1 @@
+from starlette.templating import Jinja2Templates as Jinja2Templates  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/testclient.py b/.venv/lib/python3.12/site-packages/fastapi/testclient.py
new file mode 100644
index 00000000..4012406a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/testclient.py
@@ -0,0 +1 @@
+from starlette.testclient import TestClient as TestClient  # noqa
diff --git a/.venv/lib/python3.12/site-packages/fastapi/types.py b/.venv/lib/python3.12/site-packages/fastapi/types.py
new file mode 100644
index 00000000..3205654c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/types.py
@@ -0,0 +1,10 @@
+import types
+from enum import Enum
+from typing import Any, Callable, Dict, Set, Type, 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]]
diff --git a/.venv/lib/python3.12/site-packages/fastapi/utils.py b/.venv/lib/python3.12/site-packages/fastapi/utils.py
new file mode 100644
index 00000000..4c7350fe
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/utils.py
@@ -0,0 +1,220 @@
+import re
+import warnings
+from dataclasses import is_dataclass
+from typing import (
+    TYPE_CHECKING,
+    Any,
+    Dict,
+    MutableMapping,
+    Optional,
+    Set,
+    Type,
+    Union,
+    cast,
+)
+from weakref import WeakKeyDictionary
+
+import fastapi
+from fastapi._compat import (
+    PYDANTIC_V2,
+    BaseConfig,
+    ModelField,
+    PydanticSchemaGenerationError,
+    Undefined,
+    UndefinedType,
+    Validator,
+    lenient_issubclass,
+)
+from fastapi.datastructures import DefaultPlaceholder, DefaultType
+from pydantic import BaseModel, create_model
+from pydantic.fields import FieldInfo
+from typing_extensions import Literal
+
+if TYPE_CHECKING:  # pragma: nocover
+    from .routing import APIRoute
+
+# Cache for `create_cloned_field`
+_CLONED_TYPES_CACHE: MutableMapping[Type[BaseModel], Type[BaseModel]] = (
+    WeakKeyDictionary()
+)
+
+
+def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
+    if status_code is None:
+        return True
+    # Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#patterned-fields-1
+    if status_code in {
+        "default",
+        "1XX",
+        "2XX",
+        "3XX",
+        "4XX",
+        "5XX",
+    }:
+        return True
+    current_status_code = int(status_code)
+    return not (current_status_code < 200 or current_status_code in {204, 205, 304})
+
+
+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,
+    default: Optional[Any] = Undefined,
+    required: Union[bool, UndefinedType] = Undefined,
+    model_config: Type[BaseConfig] = BaseConfig,
+    field_info: Optional[FieldInfo] = None,
+    alias: Optional[str] = None,
+    mode: Literal["validation", "serialization"] = "validation",
+) -> ModelField:
+    class_validators = class_validators or {}
+    if PYDANTIC_V2:
+        field_info = field_info or FieldInfo(
+            annotation=type_, default=default, alias=alias
+        )
+    else:
+        field_info = field_info or FieldInfo()
+    kwargs = {"name": name, "field_info": field_info}
+    if PYDANTIC_V2:
+        kwargs.update({"mode": mode})
+    else:
+        kwargs.update(
+            {
+                "type_": type_,
+                "class_validators": class_validators,
+                "default": default,
+                "required": required,
+                "model_config": model_config,
+                "alias": alias,
+            }
+        )
+    try:
+        return ModelField(**kwargs)  # type: ignore[arg-type]
+    except (RuntimeError, PydanticSchemaGenerationError):
+        raise fastapi.exceptions.FastAPIError(
+            "Invalid args for response field! Hint: "
+            f"check that {type_} is a valid Pydantic field type. "
+            "If you are using a return type annotation that is not a valid Pydantic "
+            "field (e.g. Union[Response, dict, None]) you can disable generating the "
+            "response model from the type annotation with the path operation decorator "
+            "parameter response_model=None. Read more: "
+            "https://fastapi.tiangolo.com/tutorial/response-model/"
+        ) from None
+
+
+def create_cloned_field(
+    field: ModelField,
+    *,
+    cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
+) -> ModelField:
+    if PYDANTIC_V2:
+        return field
+    # cloned_types caches already cloned types to support recursive models and improve
+    # performance by avoiding unnecessary cloning
+    if cloned_types is None:
+        cloned_types = _CLONED_TYPES_CACHE
+
+    original_type = field.type_
+    if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
+        original_type = original_type.__pydantic_model__
+    use_type = original_type
+    if lenient_issubclass(original_type, BaseModel):
+        original_type = cast(Type[BaseModel], original_type)
+        use_type = cloned_types.get(original_type)
+        if use_type is None:
+            use_type = create_model(original_type.__name__, __base__=original_type)
+            cloned_types[original_type] = use_type
+            for f in original_type.__fields__.values():
+                use_type.__fields__[f.name] = create_cloned_field(
+                    f, cloned_types=cloned_types
+                )
+    new_field = create_model_field(name=field.name, type_=use_type)
+    new_field.has_alias = field.has_alias  # type: ignore[attr-defined]
+    new_field.alias = field.alias  # type: ignore[misc]
+    new_field.class_validators = field.class_validators  # type: ignore[attr-defined]
+    new_field.default = field.default  # type: ignore[misc]
+    new_field.required = field.required  # type: ignore[misc]
+    new_field.model_config = field.model_config  # type: ignore[attr-defined]
+    new_field.field_info = field.field_info
+    new_field.allow_none = field.allow_none  # type: ignore[attr-defined]
+    new_field.validate_always = field.validate_always  # type: ignore[attr-defined]
+    if field.sub_fields:  # type: ignore[attr-defined]
+        new_field.sub_fields = [  # type: ignore[attr-defined]
+            create_cloned_field(sub_field, cloned_types=cloned_types)
+            for sub_field in field.sub_fields  # type: ignore[attr-defined]
+        ]
+    if field.key_field:  # type: ignore[attr-defined]
+        new_field.key_field = create_cloned_field(  # type: ignore[attr-defined]
+            field.key_field,  # type: ignore[attr-defined]
+            cloned_types=cloned_types,
+        )
+    new_field.validators = field.validators  # type: ignore[attr-defined]
+    new_field.pre_validators = field.pre_validators  # type: ignore[attr-defined]
+    new_field.post_validators = field.post_validators  # type: ignore[attr-defined]
+    new_field.parse_json = field.parse_json  # type: ignore[attr-defined]
+    new_field.shape = field.shape  # type: ignore[attr-defined]
+    new_field.populate_validators()  # type: ignore[attr-defined]
+    return new_field
+
+
+def generate_operation_id_for_path(
+    *, name: str, path: str, method: str
+) -> str:  # pragma: nocover
+    warnings.warn(
+        "fastapi.utils.generate_operation_id_for_path() was deprecated, "
+        "it is not used internally, and will be removed soon",
+        DeprecationWarning,
+        stacklevel=2,
+    )
+    operation_id = f"{name}{path}"
+    operation_id = re.sub(r"\W", "_", operation_id)
+    operation_id = f"{operation_id}_{method.lower()}"
+    return operation_id
+
+
+def generate_unique_id(route: "APIRoute") -> str:
+    operation_id = f"{route.name}{route.path_format}"
+    operation_id = re.sub(r"\W", "_", operation_id)
+    assert route.methods
+    operation_id = f"{operation_id}_{list(route.methods)[0].lower()}"
+    return operation_id
+
+
+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
+            and isinstance(main_dict[key], dict)
+            and isinstance(value, dict)
+        ):
+            deep_dict_update(main_dict[key], value)
+        elif (
+            key in main_dict
+            and isinstance(main_dict[key], list)
+            and isinstance(update_dict[key], list)
+        ):
+            main_dict[key] = main_dict[key] + update_dict[key]
+        else:
+            main_dict[key] = value
+
+
+def get_value_or_default(
+    first_item: Union[DefaultPlaceholder, DefaultType],
+    *extra_items: Union[DefaultPlaceholder, DefaultType],
+) -> Union[DefaultPlaceholder, DefaultType]:
+    """
+    Pass items or `DefaultPlaceholder`s by descending priority.
+
+    The first one to _not_ be a `DefaultPlaceholder` will be returned.
+
+    Otherwise, the first item (a `DefaultPlaceholder`) will be returned.
+    """
+    items = (first_item,) + extra_items
+    for item in items:
+        if not isinstance(item, DefaultPlaceholder):
+            return item
+    return first_item
diff --git a/.venv/lib/python3.12/site-packages/fastapi/websockets.py b/.venv/lib/python3.12/site-packages/fastapi/websockets.py
new file mode 100644
index 00000000..55a4ac4a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/fastapi/websockets.py
@@ -0,0 +1,3 @@
+from starlette.websockets import WebSocket as WebSocket  # noqa
+from starlette.websockets import WebSocketDisconnect as WebSocketDisconnect  # noqa
+from starlette.websockets import WebSocketState as WebSocketState  # noqa