fastapi 0.99.0__py3-none-any.whl → 0.100.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.

Potentially problematic release.


This version of fastapi might be problematic. Click here for more details.

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, ValidationError, create_model
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 RequestValidationError(ValidationError):
30
- def __init__(self, errors: Sequence[ErrorList], *, body: Any = None) -> None:
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(ValidationError):
36
- def __init__(self, errors: Sequence[ErrorList]) -> None:
37
- super().__init__(errors, WebSocketErrorModel)
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
@@ -1,2 +1,3 @@
1
1
  METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}
2
2
  REF_PREFIX = "#/components/schemas/"
3
+ REF_TEMPLATE = "#/components/schemas/{model}"
fastapi/openapi/models.py CHANGED
@@ -1,13 +1,21 @@
1
1
  from enum import Enum
2
- from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Union
3
-
2
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Set, 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
6
14
  from typing_extensions import Annotated, Literal
7
15
  from typing_extensions import deprecated as typing_deprecated
8
16
 
9
17
  try:
10
- import email_validator # type: ignore
18
+ import email_validator
11
19
 
12
20
  assert email_validator # make autoflake ignore the unused import
13
21
  from pydantic import EmailStr
@@ -26,14 +34,39 @@ except ImportError: # pragma: no cover
26
34
  )
27
35
  return str(v)
28
36
 
37
+ @classmethod
38
+ def _validate(cls, __input_value: Any, _: Any) -> str:
39
+ logger.warning(
40
+ "email-validator not installed, email fields will be treated as str.\n"
41
+ "To install, run: pip install email-validator"
42
+ )
43
+ return str(__input_value)
44
+
45
+ @classmethod
46
+ def __get_pydantic_json_schema__(
47
+ cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
48
+ ) -> JsonSchemaValue:
49
+ return {"type": "string", "format": "email"}
50
+
51
+ @classmethod
52
+ def __get_pydantic_core_schema__(
53
+ cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
54
+ ) -> CoreSchema:
55
+ return general_plain_validator_function(cls._validate)
56
+
29
57
 
30
58
  class Contact(BaseModel):
31
59
  name: Optional[str] = None
32
60
  url: Optional[AnyUrl] = None
33
61
  email: Optional[EmailStr] = None
34
62
 
35
- class Config:
36
- extra = "allow"
63
+ if PYDANTIC_V2:
64
+ model_config = {"extra": "allow"}
65
+
66
+ else:
67
+
68
+ class Config:
69
+ extra = "allow"
37
70
 
38
71
 
39
72
  class License(BaseModel):
@@ -41,8 +74,13 @@ class License(BaseModel):
41
74
  identifier: Optional[str] = None
42
75
  url: Optional[AnyUrl] = None
43
76
 
44
- class Config:
45
- extra = "allow"
77
+ if PYDANTIC_V2:
78
+ model_config = {"extra": "allow"}
79
+
80
+ else:
81
+
82
+ class Config:
83
+ extra = "allow"
46
84
 
47
85
 
48
86
  class Info(BaseModel):
@@ -54,17 +92,27 @@ class Info(BaseModel):
54
92
  license: Optional[License] = None
55
93
  version: str
56
94
 
57
- class Config:
58
- extra = "allow"
95
+ if PYDANTIC_V2:
96
+ model_config = {"extra": "allow"}
97
+
98
+ else:
99
+
100
+ class Config:
101
+ extra = "allow"
59
102
 
60
103
 
61
104
  class ServerVariable(BaseModel):
62
- enum: Annotated[Optional[List[str]], Field(min_items=1)] = None
105
+ enum: Annotated[Optional[List[str]], Field(min_length=1)] = None
63
106
  default: str
64
107
  description: Optional[str] = None
65
108
 
66
- class Config:
67
- extra = "allow"
109
+ if PYDANTIC_V2:
110
+ model_config = {"extra": "allow"}
111
+
112
+ else:
113
+
114
+ class Config:
115
+ extra = "allow"
68
116
 
69
117
 
70
118
  class Server(BaseModel):
@@ -72,8 +120,13 @@ class Server(BaseModel):
72
120
  description: Optional[str] = None
73
121
  variables: Optional[Dict[str, ServerVariable]] = None
74
122
 
75
- class Config:
76
- extra = "allow"
123
+ if PYDANTIC_V2:
124
+ model_config = {"extra": "allow"}
125
+
126
+ else:
127
+
128
+ class Config:
129
+ extra = "allow"
77
130
 
78
131
 
79
132
  class Reference(BaseModel):
@@ -92,16 +145,26 @@ class XML(BaseModel):
92
145
  attribute: Optional[bool] = None
93
146
  wrapped: Optional[bool] = None
94
147
 
95
- class Config:
96
- extra = "allow"
148
+ if PYDANTIC_V2:
149
+ model_config = {"extra": "allow"}
150
+
151
+ else:
152
+
153
+ class Config:
154
+ extra = "allow"
97
155
 
98
156
 
99
157
  class ExternalDocumentation(BaseModel):
100
158
  description: Optional[str] = None
101
159
  url: AnyUrl
102
160
 
103
- class Config:
104
- extra = "allow"
161
+ if PYDANTIC_V2:
162
+ model_config = {"extra": "allow"}
163
+
164
+ else:
165
+
166
+ class Config:
167
+ extra = "allow"
105
168
 
106
169
 
107
170
  class Schema(BaseModel):
@@ -114,27 +177,30 @@ class Schema(BaseModel):
114
177
  dynamicAnchor: Optional[str] = Field(default=None, alias="$dynamicAnchor")
115
178
  ref: Optional[str] = Field(default=None, alias="$ref")
116
179
  dynamicRef: Optional[str] = Field(default=None, alias="$dynamicRef")
117
- defs: Optional[Dict[str, "Schema"]] = Field(default=None, alias="$defs")
180
+ defs: Optional[Dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs")
118
181
  comment: Optional[str] = Field(default=None, alias="$comment")
119
182
  # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-a-vocabulary-for-applying-s
120
183
  # A Vocabulary for Applying Subschemas
121
- allOf: Optional[List["Schema"]] = None
122
- anyOf: Optional[List["Schema"]] = None
123
- oneOf: Optional[List["Schema"]] = None
124
- not_: Optional["Schema"] = Field(default=None, alias="not")
125
- if_: Optional["Schema"] = Field(default=None, alias="if")
126
- then: Optional["Schema"] = None
127
- else_: Optional["Schema"] = Field(default=None, alias="else")
128
- dependentSchemas: Optional[Dict[str, "Schema"]] = None
129
- prefixItems: Optional[List["Schema"]] = None
130
- items: Optional[Union["Schema", List["Schema"]]] = None
131
- contains: Optional["Schema"] = None
132
- properties: Optional[Dict[str, "Schema"]] = None
133
- patternProperties: Optional[Dict[str, "Schema"]] = None
134
- additionalProperties: Optional["Schema"] = None
135
- propertyNames: Optional["Schema"] = None
136
- unevaluatedItems: Optional["Schema"] = None
137
- unevaluatedProperties: Optional["Schema"] = None
184
+ allOf: Optional[List["SchemaOrBool"]] = None
185
+ anyOf: Optional[List["SchemaOrBool"]] = None
186
+ oneOf: Optional[List["SchemaOrBool"]] = None
187
+ not_: Optional["SchemaOrBool"] = Field(default=None, alias="not")
188
+ if_: Optional["SchemaOrBool"] = Field(default=None, alias="if")
189
+ then: Optional["SchemaOrBool"] = None
190
+ else_: Optional["SchemaOrBool"] = Field(default=None, alias="else")
191
+ dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None
192
+ prefixItems: Optional[List["SchemaOrBool"]] = None
193
+ # TODO: uncomment and remove below when deprecating Pydantic v1
194
+ # It generales a list of schemas for tuples, before prefixItems was available
195
+ # items: Optional["SchemaOrBool"] = None
196
+ items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None
197
+ contains: Optional["SchemaOrBool"] = None
198
+ properties: Optional[Dict[str, "SchemaOrBool"]] = None
199
+ patternProperties: Optional[Dict[str, "SchemaOrBool"]] = None
200
+ additionalProperties: Optional["SchemaOrBool"] = None
201
+ propertyNames: Optional["SchemaOrBool"] = None
202
+ unevaluatedItems: Optional["SchemaOrBool"] = None
203
+ unevaluatedProperties: Optional["SchemaOrBool"] = None
138
204
  # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural
139
205
  # A Vocabulary for Structural Validation
140
206
  type: Optional[str] = None
@@ -164,7 +230,7 @@ class Schema(BaseModel):
164
230
  # A Vocabulary for the Contents of String-Encoded Data
165
231
  contentEncoding: Optional[str] = None
166
232
  contentMediaType: Optional[str] = None
167
- contentSchema: Optional["Schema"] = None
233
+ contentSchema: Optional["SchemaOrBool"] = None
168
234
  # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-basic-meta
169
235
  # A Vocabulary for Basic Meta-Data Annotations
170
236
  title: Optional[str] = None
@@ -187,8 +253,18 @@ class Schema(BaseModel):
187
253
  ),
188
254
  ] = None
189
255
 
190
- class Config:
191
- extra: str = "allow"
256
+ if PYDANTIC_V2:
257
+ model_config = {"extra": "allow"}
258
+
259
+ else:
260
+
261
+ class Config:
262
+ extra = "allow"
263
+
264
+
265
+ # Ref: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-documents
266
+ # A JSON Schema MUST be an object or a boolean.
267
+ SchemaOrBool = Union[Schema, bool]
192
268
 
193
269
 
194
270
  class Example(BaseModel):
@@ -197,8 +273,13 @@ class Example(BaseModel):
197
273
  value: Optional[Any] = None
198
274
  externalValue: Optional[AnyUrl] = None
199
275
 
200
- class Config:
201
- extra = "allow"
276
+ if PYDANTIC_V2:
277
+ model_config = {"extra": "allow"}
278
+
279
+ else:
280
+
281
+ class Config:
282
+ extra = "allow"
202
283
 
203
284
 
204
285
  class ParameterInType(Enum):
@@ -215,8 +296,13 @@ class Encoding(BaseModel):
215
296
  explode: Optional[bool] = None
216
297
  allowReserved: Optional[bool] = None
217
298
 
218
- class Config:
219
- extra = "allow"
299
+ if PYDANTIC_V2:
300
+ model_config = {"extra": "allow"}
301
+
302
+ else:
303
+
304
+ class Config:
305
+ extra = "allow"
220
306
 
221
307
 
222
308
  class MediaType(BaseModel):
@@ -225,8 +311,13 @@ class MediaType(BaseModel):
225
311
  examples: Optional[Dict[str, Union[Example, Reference]]] = None
226
312
  encoding: Optional[Dict[str, Encoding]] = None
227
313
 
228
- class Config:
229
- extra = "allow"
314
+ if PYDANTIC_V2:
315
+ model_config = {"extra": "allow"}
316
+
317
+ else:
318
+
319
+ class Config:
320
+ extra = "allow"
230
321
 
231
322
 
232
323
  class ParameterBase(BaseModel):
@@ -243,8 +334,13 @@ class ParameterBase(BaseModel):
243
334
  # Serialization rules for more complex scenarios
244
335
  content: Optional[Dict[str, MediaType]] = None
245
336
 
246
- class Config:
247
- extra = "allow"
337
+ if PYDANTIC_V2:
338
+ model_config = {"extra": "allow"}
339
+
340
+ else:
341
+
342
+ class Config:
343
+ extra = "allow"
248
344
 
249
345
 
250
346
  class Parameter(ParameterBase):
@@ -261,8 +357,13 @@ class RequestBody(BaseModel):
261
357
  content: Dict[str, MediaType]
262
358
  required: Optional[bool] = None
263
359
 
264
- class Config:
265
- extra = "allow"
360
+ if PYDANTIC_V2:
361
+ model_config = {"extra": "allow"}
362
+
363
+ else:
364
+
365
+ class Config:
366
+ extra = "allow"
266
367
 
267
368
 
268
369
  class Link(BaseModel):
@@ -273,8 +374,13 @@ class Link(BaseModel):
273
374
  description: Optional[str] = None
274
375
  server: Optional[Server] = None
275
376
 
276
- class Config:
277
- extra = "allow"
377
+ if PYDANTIC_V2:
378
+ model_config = {"extra": "allow"}
379
+
380
+ else:
381
+
382
+ class Config:
383
+ extra = "allow"
278
384
 
279
385
 
280
386
  class Response(BaseModel):
@@ -283,8 +389,13 @@ class Response(BaseModel):
283
389
  content: Optional[Dict[str, MediaType]] = None
284
390
  links: Optional[Dict[str, Union[Link, Reference]]] = None
285
391
 
286
- class Config:
287
- extra = "allow"
392
+ if PYDANTIC_V2:
393
+ model_config = {"extra": "allow"}
394
+
395
+ else:
396
+
397
+ class Config:
398
+ extra = "allow"
288
399
 
289
400
 
290
401
  class Operation(BaseModel):
@@ -302,8 +413,13 @@ class Operation(BaseModel):
302
413
  security: Optional[List[Dict[str, List[str]]]] = None
303
414
  servers: Optional[List[Server]] = None
304
415
 
305
- class Config:
306
- extra = "allow"
416
+ if PYDANTIC_V2:
417
+ model_config = {"extra": "allow"}
418
+
419
+ else:
420
+
421
+ class Config:
422
+ extra = "allow"
307
423
 
308
424
 
309
425
  class PathItem(BaseModel):
@@ -321,8 +437,13 @@ class PathItem(BaseModel):
321
437
  servers: Optional[List[Server]] = None
322
438
  parameters: Optional[List[Union[Parameter, Reference]]] = None
323
439
 
324
- class Config:
325
- extra = "allow"
440
+ if PYDANTIC_V2:
441
+ model_config = {"extra": "allow"}
442
+
443
+ else:
444
+
445
+ class Config:
446
+ extra = "allow"
326
447
 
327
448
 
328
449
  class SecuritySchemeType(Enum):
@@ -336,8 +457,13 @@ class SecurityBase(BaseModel):
336
457
  type_: SecuritySchemeType = Field(alias="type")
337
458
  description: Optional[str] = None
338
459
 
339
- class Config:
340
- extra = "allow"
460
+ if PYDANTIC_V2:
461
+ model_config = {"extra": "allow"}
462
+
463
+ else:
464
+
465
+ class Config:
466
+ extra = "allow"
341
467
 
342
468
 
343
469
  class APIKeyIn(Enum):
@@ -366,8 +492,13 @@ class OAuthFlow(BaseModel):
366
492
  refreshUrl: Optional[str] = None
367
493
  scopes: Dict[str, str] = {}
368
494
 
369
- class Config:
370
- extra = "allow"
495
+ if PYDANTIC_V2:
496
+ model_config = {"extra": "allow"}
497
+
498
+ else:
499
+
500
+ class Config:
501
+ extra = "allow"
371
502
 
372
503
 
373
504
  class OAuthFlowImplicit(OAuthFlow):
@@ -393,8 +524,13 @@ class OAuthFlows(BaseModel):
393
524
  clientCredentials: Optional[OAuthFlowClientCredentials] = None
394
525
  authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
395
526
 
396
- class Config:
397
- extra = "allow"
527
+ if PYDANTIC_V2:
528
+ model_config = {"extra": "allow"}
529
+
530
+ else:
531
+
532
+ class Config:
533
+ extra = "allow"
398
534
 
399
535
 
400
536
  class OAuth2(SecurityBase):
@@ -425,8 +561,13 @@ class Components(BaseModel):
425
561
  callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
426
562
  pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
427
563
 
428
- class Config:
429
- extra = "allow"
564
+ if PYDANTIC_V2:
565
+ model_config = {"extra": "allow"}
566
+
567
+ else:
568
+
569
+ class Config:
570
+ extra = "allow"
430
571
 
431
572
 
432
573
  class Tag(BaseModel):
@@ -434,8 +575,13 @@ class Tag(BaseModel):
434
575
  description: Optional[str] = None
435
576
  externalDocs: Optional[ExternalDocumentation] = None
436
577
 
437
- class Config:
438
- extra = "allow"
578
+ if PYDANTIC_V2:
579
+ model_config = {"extra": "allow"}
580
+
581
+ else:
582
+
583
+ class Config:
584
+ extra = "allow"
439
585
 
440
586
 
441
587
  class OpenAPI(BaseModel):
@@ -451,10 +597,15 @@ class OpenAPI(BaseModel):
451
597
  tags: Optional[List[Tag]] = None
452
598
  externalDocs: Optional[ExternalDocumentation] = None
453
599
 
454
- class Config:
455
- extra = "allow"
600
+ if PYDANTIC_V2:
601
+ model_config = {"extra": "allow"}
602
+
603
+ else:
604
+
605
+ class Config:
606
+ extra = "allow"
456
607
 
457
608
 
458
- Schema.update_forward_refs()
459
- Operation.update_forward_refs()
460
- Encoding.update_forward_refs()
609
+ _model_rebuild(Schema)
610
+ _model_rebuild(Operation)
611
+ _model_rebuild(Encoding)