fastapi 0.128.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi/__init__.py +25 -0
- fastapi/__main__.py +3 -0
- fastapi/_compat/__init__.py +41 -0
- fastapi/_compat/shared.py +206 -0
- fastapi/_compat/v2.py +568 -0
- fastapi/applications.py +4669 -0
- fastapi/background.py +60 -0
- fastapi/cli.py +13 -0
- fastapi/concurrency.py +41 -0
- fastapi/datastructures.py +183 -0
- fastapi/dependencies/__init__.py +0 -0
- fastapi/dependencies/models.py +193 -0
- fastapi/dependencies/utils.py +1021 -0
- fastapi/encoders.py +346 -0
- fastapi/exception_handlers.py +34 -0
- fastapi/exceptions.py +246 -0
- fastapi/logger.py +3 -0
- fastapi/middleware/__init__.py +1 -0
- fastapi/middleware/asyncexitstack.py +18 -0
- fastapi/middleware/cors.py +1 -0
- fastapi/middleware/gzip.py +1 -0
- fastapi/middleware/httpsredirect.py +3 -0
- fastapi/middleware/trustedhost.py +3 -0
- fastapi/middleware/wsgi.py +1 -0
- fastapi/openapi/__init__.py +0 -0
- fastapi/openapi/constants.py +3 -0
- fastapi/openapi/docs.py +344 -0
- fastapi/openapi/models.py +438 -0
- fastapi/openapi/utils.py +567 -0
- fastapi/param_functions.py +2369 -0
- fastapi/params.py +755 -0
- fastapi/py.typed +0 -0
- fastapi/requests.py +2 -0
- fastapi/responses.py +48 -0
- fastapi/routing.py +4508 -0
- fastapi/security/__init__.py +15 -0
- fastapi/security/api_key.py +318 -0
- fastapi/security/base.py +6 -0
- fastapi/security/http.py +423 -0
- fastapi/security/oauth2.py +663 -0
- fastapi/security/open_id_connect_url.py +94 -0
- fastapi/security/utils.py +10 -0
- fastapi/staticfiles.py +1 -0
- fastapi/templating.py +1 -0
- fastapi/testclient.py +1 -0
- fastapi/types.py +11 -0
- fastapi/utils.py +164 -0
- fastapi/websockets.py +3 -0
- fastapi-0.128.0.dist-info/METADATA +645 -0
- fastapi-0.128.0.dist-info/RECORD +53 -0
- fastapi-0.128.0.dist-info/WHEEL +4 -0
- fastapi-0.128.0.dist-info/entry_points.txt +5 -0
- fastapi-0.128.0.dist-info/licenses/LICENSE +21 -0
fastapi/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.128.0"
|
|
4
|
+
|
|
5
|
+
from starlette import status as status
|
|
6
|
+
|
|
7
|
+
from .applications import FastAPI as FastAPI
|
|
8
|
+
from .background import BackgroundTasks as BackgroundTasks
|
|
9
|
+
from .datastructures import UploadFile as UploadFile
|
|
10
|
+
from .exceptions import HTTPException as HTTPException
|
|
11
|
+
from .exceptions import WebSocketException as WebSocketException
|
|
12
|
+
from .param_functions import Body as Body
|
|
13
|
+
from .param_functions import Cookie as Cookie
|
|
14
|
+
from .param_functions import Depends as Depends
|
|
15
|
+
from .param_functions import File as File
|
|
16
|
+
from .param_functions import Form as Form
|
|
17
|
+
from .param_functions import Header as Header
|
|
18
|
+
from .param_functions import Path as Path
|
|
19
|
+
from .param_functions import Query as Query
|
|
20
|
+
from .param_functions import Security as Security
|
|
21
|
+
from .requests import Request as Request
|
|
22
|
+
from .responses import Response as Response
|
|
23
|
+
from .routing import APIRouter as APIRouter
|
|
24
|
+
from .websockets import WebSocket as WebSocket
|
|
25
|
+
from .websockets import WebSocketDisconnect as WebSocketDisconnect
|
fastapi/__main__.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from .shared import PYDANTIC_V2 as PYDANTIC_V2
|
|
2
|
+
from .shared import PYDANTIC_VERSION_MINOR_TUPLE as PYDANTIC_VERSION_MINOR_TUPLE
|
|
3
|
+
from .shared import annotation_is_pydantic_v1 as annotation_is_pydantic_v1
|
|
4
|
+
from .shared import field_annotation_is_scalar as field_annotation_is_scalar
|
|
5
|
+
from .shared import is_pydantic_v1_model_class as is_pydantic_v1_model_class
|
|
6
|
+
from .shared import is_pydantic_v1_model_instance as is_pydantic_v1_model_instance
|
|
7
|
+
from .shared import (
|
|
8
|
+
is_uploadfile_or_nonable_uploadfile_annotation as is_uploadfile_or_nonable_uploadfile_annotation,
|
|
9
|
+
)
|
|
10
|
+
from .shared import (
|
|
11
|
+
is_uploadfile_sequence_annotation as is_uploadfile_sequence_annotation,
|
|
12
|
+
)
|
|
13
|
+
from .shared import lenient_issubclass as lenient_issubclass
|
|
14
|
+
from .shared import sequence_types as sequence_types
|
|
15
|
+
from .shared import value_is_sequence as value_is_sequence
|
|
16
|
+
from .v2 import BaseConfig as BaseConfig
|
|
17
|
+
from .v2 import ModelField as ModelField
|
|
18
|
+
from .v2 import PydanticSchemaGenerationError as PydanticSchemaGenerationError
|
|
19
|
+
from .v2 import RequiredParam as RequiredParam
|
|
20
|
+
from .v2 import Undefined as Undefined
|
|
21
|
+
from .v2 import UndefinedType as UndefinedType
|
|
22
|
+
from .v2 import Url as Url
|
|
23
|
+
from .v2 import Validator as Validator
|
|
24
|
+
from .v2 import _regenerate_error_with_loc as _regenerate_error_with_loc
|
|
25
|
+
from .v2 import copy_field_info as copy_field_info
|
|
26
|
+
from .v2 import create_body_model as create_body_model
|
|
27
|
+
from .v2 import evaluate_forwardref as evaluate_forwardref
|
|
28
|
+
from .v2 import get_cached_model_fields as get_cached_model_fields
|
|
29
|
+
from .v2 import get_compat_model_name_map as get_compat_model_name_map
|
|
30
|
+
from .v2 import get_definitions as get_definitions
|
|
31
|
+
from .v2 import get_missing_field_error as get_missing_field_error
|
|
32
|
+
from .v2 import get_schema_from_model_field as get_schema_from_model_field
|
|
33
|
+
from .v2 import is_bytes_field as is_bytes_field
|
|
34
|
+
from .v2 import is_bytes_sequence_field as is_bytes_sequence_field
|
|
35
|
+
from .v2 import is_scalar_field as is_scalar_field
|
|
36
|
+
from .v2 import is_scalar_sequence_field as is_scalar_sequence_field
|
|
37
|
+
from .v2 import is_sequence_field as is_sequence_field
|
|
38
|
+
from .v2 import serialize_sequence_value as serialize_sequence_value
|
|
39
|
+
from .v2 import (
|
|
40
|
+
with_info_plain_validator_function as with_info_plain_validator_function,
|
|
41
|
+
)
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import types
|
|
3
|
+
import typing
|
|
4
|
+
import warnings
|
|
5
|
+
from collections import deque
|
|
6
|
+
from collections.abc import Mapping, Sequence
|
|
7
|
+
from dataclasses import is_dataclass
|
|
8
|
+
from typing import (
|
|
9
|
+
Annotated,
|
|
10
|
+
Any,
|
|
11
|
+
Union,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
from fastapi.types import UnionType
|
|
15
|
+
from pydantic import BaseModel
|
|
16
|
+
from pydantic.version import VERSION as PYDANTIC_VERSION
|
|
17
|
+
from starlette.datastructures import UploadFile
|
|
18
|
+
from typing_extensions import get_args, get_origin
|
|
19
|
+
|
|
20
|
+
# Copy from Pydantic v2, compatible with v1
|
|
21
|
+
if sys.version_info < (3, 10):
|
|
22
|
+
WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias) # type: ignore[attr-defined]
|
|
23
|
+
else:
|
|
24
|
+
WithArgsTypes: tuple[Any, ...] = (
|
|
25
|
+
typing._GenericAlias, # type: ignore[attr-defined]
|
|
26
|
+
types.GenericAlias,
|
|
27
|
+
types.UnionType,
|
|
28
|
+
) # pyright: ignore[reportAttributeAccessIssue]
|
|
29
|
+
|
|
30
|
+
PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2])
|
|
31
|
+
PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
sequence_annotation_to_type = {
|
|
35
|
+
Sequence: list,
|
|
36
|
+
list: list,
|
|
37
|
+
tuple: tuple,
|
|
38
|
+
set: set,
|
|
39
|
+
frozenset: frozenset,
|
|
40
|
+
deque: deque,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sequence_types = tuple(sequence_annotation_to_type.keys())
|
|
44
|
+
|
|
45
|
+
Url: type[Any]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Copy of Pydantic v2, compatible with v1
|
|
49
|
+
def lenient_issubclass(
|
|
50
|
+
cls: Any, class_or_tuple: Union[type[Any], tuple[type[Any], ...], None]
|
|
51
|
+
) -> bool:
|
|
52
|
+
try:
|
|
53
|
+
return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type]
|
|
54
|
+
except TypeError: # pragma: no cover
|
|
55
|
+
if isinstance(cls, WithArgsTypes):
|
|
56
|
+
return False
|
|
57
|
+
raise # pragma: no cover
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _annotation_is_sequence(annotation: Union[type[Any], None]) -> bool:
|
|
61
|
+
if lenient_issubclass(annotation, (str, bytes)):
|
|
62
|
+
return False
|
|
63
|
+
return lenient_issubclass(annotation, sequence_types)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def field_annotation_is_sequence(annotation: Union[type[Any], None]) -> bool:
|
|
67
|
+
origin = get_origin(annotation)
|
|
68
|
+
if origin is Union or origin is UnionType:
|
|
69
|
+
for arg in get_args(annotation):
|
|
70
|
+
if field_annotation_is_sequence(arg):
|
|
71
|
+
return True
|
|
72
|
+
return False
|
|
73
|
+
return _annotation_is_sequence(annotation) or _annotation_is_sequence(
|
|
74
|
+
get_origin(annotation)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def value_is_sequence(value: Any) -> bool:
|
|
79
|
+
return isinstance(value, sequence_types) and not isinstance(value, (str, bytes))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _annotation_is_complex(annotation: Union[type[Any], None]) -> bool:
|
|
83
|
+
return (
|
|
84
|
+
lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile))
|
|
85
|
+
or _annotation_is_sequence(annotation)
|
|
86
|
+
or is_dataclass(annotation)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def field_annotation_is_complex(annotation: Union[type[Any], None]) -> bool:
|
|
91
|
+
origin = get_origin(annotation)
|
|
92
|
+
if origin is Union or origin is UnionType:
|
|
93
|
+
return any(field_annotation_is_complex(arg) for arg in get_args(annotation))
|
|
94
|
+
|
|
95
|
+
if origin is Annotated:
|
|
96
|
+
return field_annotation_is_complex(get_args(annotation)[0])
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
_annotation_is_complex(annotation)
|
|
100
|
+
or _annotation_is_complex(origin)
|
|
101
|
+
or hasattr(origin, "__pydantic_core_schema__")
|
|
102
|
+
or hasattr(origin, "__get_pydantic_core_schema__")
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def field_annotation_is_scalar(annotation: Any) -> bool:
|
|
107
|
+
# handle Ellipsis here to make tuple[int, ...] work nicely
|
|
108
|
+
return annotation is Ellipsis or not field_annotation_is_complex(annotation)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def field_annotation_is_scalar_sequence(annotation: Union[type[Any], None]) -> bool:
|
|
112
|
+
origin = get_origin(annotation)
|
|
113
|
+
if origin is Union or origin is UnionType:
|
|
114
|
+
at_least_one_scalar_sequence = False
|
|
115
|
+
for arg in get_args(annotation):
|
|
116
|
+
if field_annotation_is_scalar_sequence(arg):
|
|
117
|
+
at_least_one_scalar_sequence = True
|
|
118
|
+
continue
|
|
119
|
+
elif not field_annotation_is_scalar(arg):
|
|
120
|
+
return False
|
|
121
|
+
return at_least_one_scalar_sequence
|
|
122
|
+
return field_annotation_is_sequence(annotation) and all(
|
|
123
|
+
field_annotation_is_scalar(sub_annotation)
|
|
124
|
+
for sub_annotation in get_args(annotation)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool:
|
|
129
|
+
if lenient_issubclass(annotation, bytes):
|
|
130
|
+
return True
|
|
131
|
+
origin = get_origin(annotation)
|
|
132
|
+
if origin is Union or origin is UnionType:
|
|
133
|
+
for arg in get_args(annotation):
|
|
134
|
+
if lenient_issubclass(arg, bytes):
|
|
135
|
+
return True
|
|
136
|
+
return False
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool:
|
|
140
|
+
if lenient_issubclass(annotation, UploadFile):
|
|
141
|
+
return True
|
|
142
|
+
origin = get_origin(annotation)
|
|
143
|
+
if origin is Union or origin is UnionType:
|
|
144
|
+
for arg in get_args(annotation):
|
|
145
|
+
if lenient_issubclass(arg, UploadFile):
|
|
146
|
+
return True
|
|
147
|
+
return False
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def is_bytes_sequence_annotation(annotation: Any) -> bool:
|
|
151
|
+
origin = get_origin(annotation)
|
|
152
|
+
if origin is Union or origin is UnionType:
|
|
153
|
+
at_least_one = False
|
|
154
|
+
for arg in get_args(annotation):
|
|
155
|
+
if is_bytes_sequence_annotation(arg):
|
|
156
|
+
at_least_one = True
|
|
157
|
+
continue
|
|
158
|
+
return at_least_one
|
|
159
|
+
return field_annotation_is_sequence(annotation) and all(
|
|
160
|
+
is_bytes_or_nonable_bytes_annotation(sub_annotation)
|
|
161
|
+
for sub_annotation in get_args(annotation)
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def is_uploadfile_sequence_annotation(annotation: Any) -> bool:
|
|
166
|
+
origin = get_origin(annotation)
|
|
167
|
+
if origin is Union or origin is UnionType:
|
|
168
|
+
at_least_one = False
|
|
169
|
+
for arg in get_args(annotation):
|
|
170
|
+
if is_uploadfile_sequence_annotation(arg):
|
|
171
|
+
at_least_one = True
|
|
172
|
+
continue
|
|
173
|
+
return at_least_one
|
|
174
|
+
return field_annotation_is_sequence(annotation) and all(
|
|
175
|
+
is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation)
|
|
176
|
+
for sub_annotation in get_args(annotation)
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def is_pydantic_v1_model_instance(obj: Any) -> bool:
|
|
181
|
+
with warnings.catch_warnings():
|
|
182
|
+
warnings.simplefilter("ignore", UserWarning)
|
|
183
|
+
from pydantic import v1
|
|
184
|
+
return isinstance(obj, v1.BaseModel)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def is_pydantic_v1_model_class(cls: Any) -> bool:
|
|
188
|
+
with warnings.catch_warnings():
|
|
189
|
+
warnings.simplefilter("ignore", UserWarning)
|
|
190
|
+
from pydantic import v1
|
|
191
|
+
return lenient_issubclass(cls, v1.BaseModel)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def annotation_is_pydantic_v1(annotation: Any) -> bool:
|
|
195
|
+
if is_pydantic_v1_model_class(annotation):
|
|
196
|
+
return True
|
|
197
|
+
origin = get_origin(annotation)
|
|
198
|
+
if origin is Union or origin is UnionType:
|
|
199
|
+
for arg in get_args(annotation):
|
|
200
|
+
if is_pydantic_v1_model_class(arg):
|
|
201
|
+
return True
|
|
202
|
+
if field_annotation_is_sequence(annotation):
|
|
203
|
+
for sub_annotation in get_args(annotation):
|
|
204
|
+
if annotation_is_pydantic_v1(sub_annotation):
|
|
205
|
+
return True
|
|
206
|
+
return False
|