fastapi 0.96.1__py3-none-any.whl → 0.100.0b1__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.
Potentially problematic release.
This version of fastapi might be problematic. Click here for more details.
- fastapi/__init__.py +1 -1
- fastapi/_compat.py +597 -0
- fastapi/applications.py +51 -27
- fastapi/datastructures.py +31 -4
- fastapi/dependencies/models.py +1 -1
- fastapi/dependencies/utils.py +76 -120
- fastapi/encoders.py +91 -13
- fastapi/exception_handlers.py +11 -2
- fastapi/exceptions.py +20 -8
- fastapi/middleware/asyncexitstack.py +13 -16
- fastapi/openapi/constants.py +1 -0
- fastapi/openapi/models.py +203 -57
- fastapi/openapi/utils.py +65 -44
- fastapi/param_functions.py +15 -1
- fastapi/params.py +57 -8
- fastapi/routing.py +126 -61
- fastapi/security/api_key.py +9 -3
- fastapi/security/oauth2.py +32 -21
- fastapi/types.py +9 -1
- fastapi/utils.py +62 -60
- {fastapi-0.96.1.dist-info → fastapi-0.100.0b1.dist-info}/METADATA +3 -37
- fastapi-0.100.0b1.dist-info/RECORD +48 -0
- fastapi-0.96.1.dist-info/RECORD +0 -47
- {fastapi-0.96.1.dist-info → fastapi-0.100.0b1.dist-info}/WHEEL +0 -0
- {fastapi-0.96.1.dist-info → fastapi-0.100.0b1.dist-info}/licenses/LICENSE +0 -0
fastapi/encoders.py
CHANGED
|
@@ -1,15 +1,87 @@
|
|
|
1
1
|
import dataclasses
|
|
2
|
-
|
|
2
|
+
import datetime
|
|
3
|
+
from collections import defaultdict, deque
|
|
4
|
+
from decimal import Decimal
|
|
3
5
|
from enum import Enum
|
|
4
|
-
from
|
|
6
|
+
from ipaddress import (
|
|
7
|
+
IPv4Address,
|
|
8
|
+
IPv4Interface,
|
|
9
|
+
IPv4Network,
|
|
10
|
+
IPv6Address,
|
|
11
|
+
IPv6Interface,
|
|
12
|
+
IPv6Network,
|
|
13
|
+
)
|
|
14
|
+
from pathlib import Path, PurePath
|
|
15
|
+
from re import Pattern
|
|
5
16
|
from types import GeneratorType
|
|
6
|
-
from typing import Any, Callable, Dict, List, Optional,
|
|
17
|
+
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
|
|
18
|
+
from uuid import UUID
|
|
7
19
|
|
|
20
|
+
from fastapi.types import IncEx
|
|
8
21
|
from pydantic import BaseModel
|
|
9
|
-
from pydantic.
|
|
22
|
+
from pydantic.color import Color
|
|
23
|
+
from pydantic.networks import NameEmail
|
|
24
|
+
from pydantic.types import SecretBytes, SecretStr
|
|
10
25
|
|
|
11
|
-
|
|
12
|
-
|
|
26
|
+
from ._compat import PYDANTIC_V2, MultiHostUrl, Url, _model_dump
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Taken from Pydantic v1 as is
|
|
30
|
+
def isoformat(o: Union[datetime.date, datetime.time]) -> str:
|
|
31
|
+
return o.isoformat()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Taken from Pydantic v1 as is
|
|
35
|
+
# TODO: pv2 should this return strings instead?
|
|
36
|
+
def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
|
|
37
|
+
"""
|
|
38
|
+
Encodes a Decimal as int of there's no exponent, otherwise float
|
|
39
|
+
|
|
40
|
+
This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
|
|
41
|
+
where a integer (but not int typed) is used. Encoding this as a float
|
|
42
|
+
results in failed round-tripping between encode and parse.
|
|
43
|
+
Our Id type is a prime example of this.
|
|
44
|
+
|
|
45
|
+
>>> decimal_encoder(Decimal("1.0"))
|
|
46
|
+
1.0
|
|
47
|
+
|
|
48
|
+
>>> decimal_encoder(Decimal("1"))
|
|
49
|
+
1
|
|
50
|
+
"""
|
|
51
|
+
if dec_value.as_tuple().exponent >= 0: # type: ignore[operator]
|
|
52
|
+
return int(dec_value)
|
|
53
|
+
else:
|
|
54
|
+
return float(dec_value)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
|
|
58
|
+
bytes: lambda o: o.decode(),
|
|
59
|
+
Color: str,
|
|
60
|
+
datetime.date: isoformat,
|
|
61
|
+
datetime.datetime: isoformat,
|
|
62
|
+
datetime.time: isoformat,
|
|
63
|
+
datetime.timedelta: lambda td: td.total_seconds(),
|
|
64
|
+
Decimal: decimal_encoder,
|
|
65
|
+
Enum: lambda o: o.value,
|
|
66
|
+
frozenset: list,
|
|
67
|
+
deque: list,
|
|
68
|
+
GeneratorType: list,
|
|
69
|
+
IPv4Address: str,
|
|
70
|
+
IPv4Interface: str,
|
|
71
|
+
IPv4Network: str,
|
|
72
|
+
IPv6Address: str,
|
|
73
|
+
IPv6Interface: str,
|
|
74
|
+
IPv6Network: str,
|
|
75
|
+
NameEmail: str,
|
|
76
|
+
Path: str,
|
|
77
|
+
Pattern: lambda o: o.pattern,
|
|
78
|
+
SecretBytes: str,
|
|
79
|
+
SecretStr: str,
|
|
80
|
+
set: list,
|
|
81
|
+
UUID: str,
|
|
82
|
+
Url: str,
|
|
83
|
+
MultiHostUrl: str,
|
|
84
|
+
}
|
|
13
85
|
|
|
14
86
|
|
|
15
87
|
def generate_encoders_by_class_tuples(
|
|
@@ -28,8 +100,8 @@ encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
|
|
|
28
100
|
|
|
29
101
|
def jsonable_encoder(
|
|
30
102
|
obj: Any,
|
|
31
|
-
include: Optional[
|
|
32
|
-
exclude: Optional[
|
|
103
|
+
include: Optional[IncEx] = None,
|
|
104
|
+
exclude: Optional[IncEx] = None,
|
|
33
105
|
by_alias: bool = True,
|
|
34
106
|
exclude_unset: bool = False,
|
|
35
107
|
exclude_defaults: bool = False,
|
|
@@ -50,10 +122,15 @@ def jsonable_encoder(
|
|
|
50
122
|
if exclude is not None and not isinstance(exclude, (set, dict)):
|
|
51
123
|
exclude = set(exclude)
|
|
52
124
|
if isinstance(obj, BaseModel):
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
125
|
+
# TODO: remove when deprecating Pydantic v1
|
|
126
|
+
encoders: Dict[Any, Any] = {}
|
|
127
|
+
if not PYDANTIC_V2:
|
|
128
|
+
encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
|
|
129
|
+
if custom_encoder:
|
|
130
|
+
encoders.update(custom_encoder)
|
|
131
|
+
obj_dict = _model_dump(
|
|
132
|
+
obj,
|
|
133
|
+
mode="json",
|
|
57
134
|
include=include,
|
|
58
135
|
exclude=exclude,
|
|
59
136
|
by_alias=by_alias,
|
|
@@ -67,7 +144,8 @@ def jsonable_encoder(
|
|
|
67
144
|
obj_dict,
|
|
68
145
|
exclude_none=exclude_none,
|
|
69
146
|
exclude_defaults=exclude_defaults,
|
|
70
|
-
|
|
147
|
+
# TODO: remove when deprecating Pydantic v1
|
|
148
|
+
custom_encoder=encoders,
|
|
71
149
|
sqlalchemy_safe=sqlalchemy_safe,
|
|
72
150
|
)
|
|
73
151
|
if dataclasses.is_dataclass(obj):
|
fastapi/exception_handlers.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from fastapi.encoders import jsonable_encoder
|
|
2
|
-
from fastapi.exceptions import RequestValidationError
|
|
2
|
+
from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
|
|
3
3
|
from fastapi.utils import is_body_allowed_for_status_code
|
|
4
|
+
from fastapi.websockets import WebSocket
|
|
4
5
|
from starlette.exceptions import HTTPException
|
|
5
6
|
from starlette.requests import Request
|
|
6
7
|
from starlette.responses import JSONResponse, Response
|
|
7
|
-
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
|
|
8
|
+
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
|
|
@@ -23,3 +24,11 @@ async def request_validation_exception_handler(
|
|
|
23
24
|
status_code=HTTP_422_UNPROCESSABLE_ENTITY,
|
|
24
25
|
content={"detail": jsonable_encoder(exc.errors())},
|
|
25
26
|
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
async def websocket_request_validation_exception_handler(
|
|
30
|
+
websocket: WebSocket, exc: WebSocketRequestValidationError
|
|
31
|
+
) -> None:
|
|
32
|
+
await websocket.close(
|
|
33
|
+
code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
|
|
34
|
+
)
|
fastapi/exceptions.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Any, Dict, Optional, Sequence, Type
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel,
|
|
4
|
-
from pydantic.error_wrappers import ErrorList
|
|
3
|
+
from pydantic import BaseModel, create_model
|
|
5
4
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
6
5
|
from starlette.exceptions import WebSocketException as WebSocketException # noqa: F401
|
|
7
6
|
|
|
@@ -26,12 +25,25 @@ class FastAPIError(RuntimeError):
|
|
|
26
25
|
"""
|
|
27
26
|
|
|
28
27
|
|
|
29
|
-
class
|
|
30
|
-
def __init__(self, errors: Sequence[
|
|
28
|
+
class ValidationException(Exception):
|
|
29
|
+
def __init__(self, errors: Sequence[Any]) -> None:
|
|
30
|
+
self._errors = errors
|
|
31
|
+
|
|
32
|
+
def errors(self) -> Sequence[Any]:
|
|
33
|
+
return self._errors
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class RequestValidationError(ValidationException):
|
|
37
|
+
def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
|
|
38
|
+
super().__init__(errors)
|
|
31
39
|
self.body = body
|
|
32
|
-
super().__init__(errors, RequestErrorModel)
|
|
33
40
|
|
|
34
41
|
|
|
35
|
-
class WebSocketRequestValidationError(
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
class WebSocketRequestValidationError(ValidationException):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class ResponseValidationError(ValidationException):
|
|
47
|
+
def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
|
|
48
|
+
super().__init__(errors)
|
|
49
|
+
self.body = body
|
|
@@ -10,19 +10,16 @@ class AsyncExitStackMiddleware:
|
|
|
10
10
|
self.context_name = context_name
|
|
11
11
|
|
|
12
12
|
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
raise dependency_exception
|
|
27
|
-
else:
|
|
28
|
-
await self.app(scope, receive, send) # pragma: no cover
|
|
13
|
+
dependency_exception: Optional[Exception] = None
|
|
14
|
+
async with AsyncExitStack() as stack:
|
|
15
|
+
scope[self.context_name] = stack
|
|
16
|
+
try:
|
|
17
|
+
await self.app(scope, receive, send)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
dependency_exception = e
|
|
20
|
+
raise e
|
|
21
|
+
if dependency_exception:
|
|
22
|
+
# This exception was possibly handled by the dependency but it should
|
|
23
|
+
# still bubble up so that the ServerErrorMiddleware can return a 500
|
|
24
|
+
# or the ExceptionMiddleware can catch and handle any other exceptions
|
|
25
|
+
raise dependency_exception
|
fastapi/openapi/constants.py
CHANGED
fastapi/openapi/models.py
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
|
|
3
|
-
|
|
2
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union
|
|
3
|
+
|
|
4
|
+
from fastapi._compat import (
|
|
5
|
+
PYDANTIC_V2,
|
|
6
|
+
CoreSchema,
|
|
7
|
+
GetJsonSchemaHandler,
|
|
8
|
+
JsonSchemaValue,
|
|
9
|
+
_model_rebuild,
|
|
10
|
+
general_plain_validator_function,
|
|
11
|
+
)
|
|
4
12
|
from fastapi.logger import logger
|
|
5
13
|
from pydantic import AnyUrl, BaseModel, Field
|
|
14
|
+
from typing_extensions import Literal
|
|
6
15
|
|
|
7
16
|
try:
|
|
8
|
-
import email_validator
|
|
17
|
+
import email_validator
|
|
9
18
|
|
|
10
19
|
assert email_validator # make autoflake ignore the unused import
|
|
11
20
|
from pydantic import EmailStr
|
|
@@ -24,22 +33,52 @@ except ImportError: # pragma: no cover
|
|
|
24
33
|
)
|
|
25
34
|
return str(v)
|
|
26
35
|
|
|
36
|
+
@classmethod
|
|
37
|
+
def _validate(cls, __input_value: Any, _: Any) -> str:
|
|
38
|
+
logger.warning(
|
|
39
|
+
"email-validator not installed, email fields will be treated as str.\n"
|
|
40
|
+
"To install, run: pip install email-validator"
|
|
41
|
+
)
|
|
42
|
+
return str(__input_value)
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def __get_pydantic_json_schema__(
|
|
46
|
+
cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
|
|
47
|
+
) -> JsonSchemaValue:
|
|
48
|
+
return {"type": "string", "format": "email"}
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def __get_pydantic_core_schema__(
|
|
52
|
+
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
|
|
53
|
+
) -> CoreSchema:
|
|
54
|
+
return general_plain_validator_function(cls._validate)
|
|
55
|
+
|
|
27
56
|
|
|
28
57
|
class Contact(BaseModel):
|
|
29
58
|
name: Optional[str] = None
|
|
30
59
|
url: Optional[AnyUrl] = None
|
|
31
60
|
email: Optional[EmailStr] = None
|
|
32
61
|
|
|
33
|
-
|
|
34
|
-
|
|
62
|
+
if PYDANTIC_V2:
|
|
63
|
+
model_config = {"extra": "allow"}
|
|
64
|
+
|
|
65
|
+
else:
|
|
66
|
+
|
|
67
|
+
class Config:
|
|
68
|
+
extra = "allow"
|
|
35
69
|
|
|
36
70
|
|
|
37
71
|
class License(BaseModel):
|
|
38
72
|
name: str
|
|
39
73
|
url: Optional[AnyUrl] = None
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
|
|
75
|
+
if PYDANTIC_V2:
|
|
76
|
+
model_config = {"extra": "allow"}
|
|
77
|
+
|
|
78
|
+
else:
|
|
79
|
+
|
|
80
|
+
class Config:
|
|
81
|
+
extra = "allow"
|
|
43
82
|
|
|
44
83
|
|
|
45
84
|
class Info(BaseModel):
|
|
@@ -50,8 +89,13 @@ class Info(BaseModel):
|
|
|
50
89
|
license: Optional[License] = None
|
|
51
90
|
version: str
|
|
52
91
|
|
|
53
|
-
|
|
54
|
-
|
|
92
|
+
if PYDANTIC_V2:
|
|
93
|
+
model_config = {"extra": "allow"}
|
|
94
|
+
|
|
95
|
+
else:
|
|
96
|
+
|
|
97
|
+
class Config:
|
|
98
|
+
extra = "allow"
|
|
55
99
|
|
|
56
100
|
|
|
57
101
|
class ServerVariable(BaseModel):
|
|
@@ -59,8 +103,13 @@ class ServerVariable(BaseModel):
|
|
|
59
103
|
default: str
|
|
60
104
|
description: Optional[str] = None
|
|
61
105
|
|
|
62
|
-
|
|
63
|
-
|
|
106
|
+
if PYDANTIC_V2:
|
|
107
|
+
model_config = {"extra": "allow"}
|
|
108
|
+
|
|
109
|
+
else:
|
|
110
|
+
|
|
111
|
+
class Config:
|
|
112
|
+
extra = "allow"
|
|
64
113
|
|
|
65
114
|
|
|
66
115
|
class Server(BaseModel):
|
|
@@ -68,8 +117,13 @@ class Server(BaseModel):
|
|
|
68
117
|
description: Optional[str] = None
|
|
69
118
|
variables: Optional[Dict[str, ServerVariable]] = None
|
|
70
119
|
|
|
71
|
-
|
|
72
|
-
|
|
120
|
+
if PYDANTIC_V2:
|
|
121
|
+
model_config = {"extra": "allow"}
|
|
122
|
+
|
|
123
|
+
else:
|
|
124
|
+
|
|
125
|
+
class Config:
|
|
126
|
+
extra = "allow"
|
|
73
127
|
|
|
74
128
|
|
|
75
129
|
class Reference(BaseModel):
|
|
@@ -88,16 +142,26 @@ class XML(BaseModel):
|
|
|
88
142
|
attribute: Optional[bool] = None
|
|
89
143
|
wrapped: Optional[bool] = None
|
|
90
144
|
|
|
91
|
-
|
|
92
|
-
|
|
145
|
+
if PYDANTIC_V2:
|
|
146
|
+
model_config = {"extra": "allow"}
|
|
147
|
+
|
|
148
|
+
else:
|
|
149
|
+
|
|
150
|
+
class Config:
|
|
151
|
+
extra = "allow"
|
|
93
152
|
|
|
94
153
|
|
|
95
154
|
class ExternalDocumentation(BaseModel):
|
|
96
155
|
description: Optional[str] = None
|
|
97
156
|
url: AnyUrl
|
|
98
157
|
|
|
99
|
-
|
|
100
|
-
|
|
158
|
+
if PYDANTIC_V2:
|
|
159
|
+
model_config = {"extra": "allow"}
|
|
160
|
+
|
|
161
|
+
else:
|
|
162
|
+
|
|
163
|
+
class Config:
|
|
164
|
+
extra = "allow"
|
|
101
165
|
|
|
102
166
|
|
|
103
167
|
class Schema(BaseModel):
|
|
@@ -138,8 +202,13 @@ class Schema(BaseModel):
|
|
|
138
202
|
example: Optional[Any] = None
|
|
139
203
|
deprecated: Optional[bool] = None
|
|
140
204
|
|
|
141
|
-
|
|
142
|
-
|
|
205
|
+
if PYDANTIC_V2:
|
|
206
|
+
model_config = {"extra": "allow"}
|
|
207
|
+
|
|
208
|
+
else:
|
|
209
|
+
|
|
210
|
+
class Config:
|
|
211
|
+
extra = "allow"
|
|
143
212
|
|
|
144
213
|
|
|
145
214
|
class Example(BaseModel):
|
|
@@ -148,8 +217,13 @@ class Example(BaseModel):
|
|
|
148
217
|
value: Optional[Any] = None
|
|
149
218
|
externalValue: Optional[AnyUrl] = None
|
|
150
219
|
|
|
151
|
-
|
|
152
|
-
|
|
220
|
+
if PYDANTIC_V2:
|
|
221
|
+
model_config = {"extra": "allow"}
|
|
222
|
+
|
|
223
|
+
else:
|
|
224
|
+
|
|
225
|
+
class Config:
|
|
226
|
+
extra = "allow"
|
|
153
227
|
|
|
154
228
|
|
|
155
229
|
class ParameterInType(Enum):
|
|
@@ -166,8 +240,13 @@ class Encoding(BaseModel):
|
|
|
166
240
|
explode: Optional[bool] = None
|
|
167
241
|
allowReserved: Optional[bool] = None
|
|
168
242
|
|
|
169
|
-
|
|
170
|
-
|
|
243
|
+
if PYDANTIC_V2:
|
|
244
|
+
model_config = {"extra": "allow"}
|
|
245
|
+
|
|
246
|
+
else:
|
|
247
|
+
|
|
248
|
+
class Config:
|
|
249
|
+
extra = "allow"
|
|
171
250
|
|
|
172
251
|
|
|
173
252
|
class MediaType(BaseModel):
|
|
@@ -176,8 +255,13 @@ class MediaType(BaseModel):
|
|
|
176
255
|
examples: Optional[Dict[str, Union[Example, Reference]]] = None
|
|
177
256
|
encoding: Optional[Dict[str, Encoding]] = None
|
|
178
257
|
|
|
179
|
-
|
|
180
|
-
|
|
258
|
+
if PYDANTIC_V2:
|
|
259
|
+
model_config = {"extra": "allow"}
|
|
260
|
+
|
|
261
|
+
else:
|
|
262
|
+
|
|
263
|
+
class Config:
|
|
264
|
+
extra = "allow"
|
|
181
265
|
|
|
182
266
|
|
|
183
267
|
class ParameterBase(BaseModel):
|
|
@@ -194,8 +278,13 @@ class ParameterBase(BaseModel):
|
|
|
194
278
|
# Serialization rules for more complex scenarios
|
|
195
279
|
content: Optional[Dict[str, MediaType]] = None
|
|
196
280
|
|
|
197
|
-
|
|
198
|
-
|
|
281
|
+
if PYDANTIC_V2:
|
|
282
|
+
model_config = {"extra": "allow"}
|
|
283
|
+
|
|
284
|
+
else:
|
|
285
|
+
|
|
286
|
+
class Config:
|
|
287
|
+
extra = "allow"
|
|
199
288
|
|
|
200
289
|
|
|
201
290
|
class Parameter(ParameterBase):
|
|
@@ -212,8 +301,13 @@ class RequestBody(BaseModel):
|
|
|
212
301
|
content: Dict[str, MediaType]
|
|
213
302
|
required: Optional[bool] = None
|
|
214
303
|
|
|
215
|
-
|
|
216
|
-
|
|
304
|
+
if PYDANTIC_V2:
|
|
305
|
+
model_config = {"extra": "allow"}
|
|
306
|
+
|
|
307
|
+
else:
|
|
308
|
+
|
|
309
|
+
class Config:
|
|
310
|
+
extra = "allow"
|
|
217
311
|
|
|
218
312
|
|
|
219
313
|
class Link(BaseModel):
|
|
@@ -224,8 +318,13 @@ class Link(BaseModel):
|
|
|
224
318
|
description: Optional[str] = None
|
|
225
319
|
server: Optional[Server] = None
|
|
226
320
|
|
|
227
|
-
|
|
228
|
-
|
|
321
|
+
if PYDANTIC_V2:
|
|
322
|
+
model_config = {"extra": "allow"}
|
|
323
|
+
|
|
324
|
+
else:
|
|
325
|
+
|
|
326
|
+
class Config:
|
|
327
|
+
extra = "allow"
|
|
229
328
|
|
|
230
329
|
|
|
231
330
|
class Response(BaseModel):
|
|
@@ -234,8 +333,13 @@ class Response(BaseModel):
|
|
|
234
333
|
content: Optional[Dict[str, MediaType]] = None
|
|
235
334
|
links: Optional[Dict[str, Union[Link, Reference]]] = None
|
|
236
335
|
|
|
237
|
-
|
|
238
|
-
|
|
336
|
+
if PYDANTIC_V2:
|
|
337
|
+
model_config = {"extra": "allow"}
|
|
338
|
+
|
|
339
|
+
else:
|
|
340
|
+
|
|
341
|
+
class Config:
|
|
342
|
+
extra = "allow"
|
|
239
343
|
|
|
240
344
|
|
|
241
345
|
class Operation(BaseModel):
|
|
@@ -253,8 +357,13 @@ class Operation(BaseModel):
|
|
|
253
357
|
security: Optional[List[Dict[str, List[str]]]] = None
|
|
254
358
|
servers: Optional[List[Server]] = None
|
|
255
359
|
|
|
256
|
-
|
|
257
|
-
|
|
360
|
+
if PYDANTIC_V2:
|
|
361
|
+
model_config = {"extra": "allow"}
|
|
362
|
+
|
|
363
|
+
else:
|
|
364
|
+
|
|
365
|
+
class Config:
|
|
366
|
+
extra = "allow"
|
|
258
367
|
|
|
259
368
|
|
|
260
369
|
class PathItem(BaseModel):
|
|
@@ -272,8 +381,13 @@ class PathItem(BaseModel):
|
|
|
272
381
|
servers: Optional[List[Server]] = None
|
|
273
382
|
parameters: Optional[List[Union[Parameter, Reference]]] = None
|
|
274
383
|
|
|
275
|
-
|
|
276
|
-
|
|
384
|
+
if PYDANTIC_V2:
|
|
385
|
+
model_config = {"extra": "allow"}
|
|
386
|
+
|
|
387
|
+
else:
|
|
388
|
+
|
|
389
|
+
class Config:
|
|
390
|
+
extra = "allow"
|
|
277
391
|
|
|
278
392
|
|
|
279
393
|
class SecuritySchemeType(Enum):
|
|
@@ -287,8 +401,13 @@ class SecurityBase(BaseModel):
|
|
|
287
401
|
type_: SecuritySchemeType = Field(alias="type")
|
|
288
402
|
description: Optional[str] = None
|
|
289
403
|
|
|
290
|
-
|
|
291
|
-
|
|
404
|
+
if PYDANTIC_V2:
|
|
405
|
+
model_config = {"extra": "allow"}
|
|
406
|
+
|
|
407
|
+
else:
|
|
408
|
+
|
|
409
|
+
class Config:
|
|
410
|
+
extra = "allow"
|
|
292
411
|
|
|
293
412
|
|
|
294
413
|
class APIKeyIn(Enum):
|
|
@@ -298,18 +417,18 @@ class APIKeyIn(Enum):
|
|
|
298
417
|
|
|
299
418
|
|
|
300
419
|
class APIKey(SecurityBase):
|
|
301
|
-
type_ = Field(SecuritySchemeType.apiKey, alias="type")
|
|
420
|
+
type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type")
|
|
302
421
|
in_: APIKeyIn = Field(alias="in")
|
|
303
422
|
name: str
|
|
304
423
|
|
|
305
424
|
|
|
306
425
|
class HTTPBase(SecurityBase):
|
|
307
|
-
type_ = Field(SecuritySchemeType.http, alias="type")
|
|
426
|
+
type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type")
|
|
308
427
|
scheme: str
|
|
309
428
|
|
|
310
429
|
|
|
311
430
|
class HTTPBearer(HTTPBase):
|
|
312
|
-
scheme = "bearer"
|
|
431
|
+
scheme: Literal["bearer"] = "bearer"
|
|
313
432
|
bearerFormat: Optional[str] = None
|
|
314
433
|
|
|
315
434
|
|
|
@@ -317,8 +436,13 @@ class OAuthFlow(BaseModel):
|
|
|
317
436
|
refreshUrl: Optional[str] = None
|
|
318
437
|
scopes: Dict[str, str] = {}
|
|
319
438
|
|
|
320
|
-
|
|
321
|
-
|
|
439
|
+
if PYDANTIC_V2:
|
|
440
|
+
model_config = {"extra": "allow"}
|
|
441
|
+
|
|
442
|
+
else:
|
|
443
|
+
|
|
444
|
+
class Config:
|
|
445
|
+
extra = "allow"
|
|
322
446
|
|
|
323
447
|
|
|
324
448
|
class OAuthFlowImplicit(OAuthFlow):
|
|
@@ -344,17 +468,24 @@ class OAuthFlows(BaseModel):
|
|
|
344
468
|
clientCredentials: Optional[OAuthFlowClientCredentials] = None
|
|
345
469
|
authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
|
|
346
470
|
|
|
347
|
-
|
|
348
|
-
|
|
471
|
+
if PYDANTIC_V2:
|
|
472
|
+
model_config = {"extra": "allow"}
|
|
473
|
+
|
|
474
|
+
else:
|
|
475
|
+
|
|
476
|
+
class Config:
|
|
477
|
+
extra = "allow"
|
|
349
478
|
|
|
350
479
|
|
|
351
480
|
class OAuth2(SecurityBase):
|
|
352
|
-
type_ = Field(SecuritySchemeType.oauth2, alias="type")
|
|
481
|
+
type_: SecuritySchemeType = Field(default=SecuritySchemeType.oauth2, alias="type")
|
|
353
482
|
flows: OAuthFlows
|
|
354
483
|
|
|
355
484
|
|
|
356
485
|
class OpenIdConnect(SecurityBase):
|
|
357
|
-
type_ = Field(
|
|
486
|
+
type_: SecuritySchemeType = Field(
|
|
487
|
+
default=SecuritySchemeType.openIdConnect, alias="type"
|
|
488
|
+
)
|
|
358
489
|
openIdConnectUrl: str
|
|
359
490
|
|
|
360
491
|
|
|
@@ -373,8 +504,13 @@ class Components(BaseModel):
|
|
|
373
504
|
# Using Any for Specification Extensions
|
|
374
505
|
callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
|
|
375
506
|
|
|
376
|
-
|
|
377
|
-
|
|
507
|
+
if PYDANTIC_V2:
|
|
508
|
+
model_config = {"extra": "allow"}
|
|
509
|
+
|
|
510
|
+
else:
|
|
511
|
+
|
|
512
|
+
class Config:
|
|
513
|
+
extra = "allow"
|
|
378
514
|
|
|
379
515
|
|
|
380
516
|
class Tag(BaseModel):
|
|
@@ -382,8 +518,13 @@ class Tag(BaseModel):
|
|
|
382
518
|
description: Optional[str] = None
|
|
383
519
|
externalDocs: Optional[ExternalDocumentation] = None
|
|
384
520
|
|
|
385
|
-
|
|
386
|
-
|
|
521
|
+
if PYDANTIC_V2:
|
|
522
|
+
model_config = {"extra": "allow"}
|
|
523
|
+
|
|
524
|
+
else:
|
|
525
|
+
|
|
526
|
+
class Config:
|
|
527
|
+
extra = "allow"
|
|
387
528
|
|
|
388
529
|
|
|
389
530
|
class OpenAPI(BaseModel):
|
|
@@ -397,10 +538,15 @@ class OpenAPI(BaseModel):
|
|
|
397
538
|
tags: Optional[List[Tag]] = None
|
|
398
539
|
externalDocs: Optional[ExternalDocumentation] = None
|
|
399
540
|
|
|
400
|
-
|
|
401
|
-
|
|
541
|
+
if PYDANTIC_V2:
|
|
542
|
+
model_config = {"extra": "allow"}
|
|
543
|
+
|
|
544
|
+
else:
|
|
545
|
+
|
|
546
|
+
class Config:
|
|
547
|
+
extra = "allow"
|
|
402
548
|
|
|
403
549
|
|
|
404
|
-
Schema
|
|
405
|
-
Operation
|
|
406
|
-
Encoding
|
|
550
|
+
_model_rebuild(Schema)
|
|
551
|
+
_model_rebuild(Operation)
|
|
552
|
+
_model_rebuild(Encoding)
|