fastapi 0.97.0__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.

@@ -9,6 +9,9 @@ from fastapi.security.utils import get_authorization_scheme_param
9
9
  from starlette.requests import Request
10
10
  from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
11
11
 
12
+ # TODO: import from typing when deprecating Python 3.9
13
+ from typing_extensions import Annotated
14
+
12
15
 
13
16
  class OAuth2PasswordRequestForm:
14
17
  """
@@ -45,12 +48,13 @@ class OAuth2PasswordRequestForm:
45
48
 
46
49
  def __init__(
47
50
  self,
48
- grant_type: str = Form(default=None, regex="password"),
49
- username: str = Form(),
50
- password: str = Form(),
51
- scope: str = Form(default=""),
52
- client_id: Optional[str] = Form(default=None),
53
- client_secret: Optional[str] = Form(default=None),
51
+ *,
52
+ grant_type: Annotated[Union[str, None], Form(pattern="password")] = None,
53
+ username: Annotated[str, Form()],
54
+ password: Annotated[str, Form()],
55
+ scope: Annotated[str, Form()] = "",
56
+ client_id: Annotated[Union[str, None], Form()] = None,
57
+ client_secret: Annotated[Union[str, None], Form()] = None,
54
58
  ):
55
59
  self.grant_type = grant_type
56
60
  self.username = username
@@ -95,12 +99,12 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
95
99
 
96
100
  def __init__(
97
101
  self,
98
- grant_type: str = Form(regex="password"),
99
- username: str = Form(),
100
- password: str = Form(),
101
- scope: str = Form(default=""),
102
- client_id: Optional[str] = Form(default=None),
103
- client_secret: Optional[str] = Form(default=None),
102
+ grant_type: Annotated[str, Form(pattern="password")],
103
+ username: Annotated[str, Form()],
104
+ password: Annotated[str, Form()],
105
+ scope: Annotated[str, Form()] = "",
106
+ client_id: Annotated[Union[str, None], Form()] = None,
107
+ client_secret: Annotated[Union[str, None], Form()] = None,
104
108
  ):
105
109
  super().__init__(
106
110
  grant_type=grant_type,
fastapi/types.py CHANGED
@@ -1,3 +1,11 @@
1
- from typing import Any, Callable, TypeVar
1
+ import types
2
+ from enum import Enum
3
+ from typing import Any, Callable, Dict, Set, Type, TypeVar, Union
4
+
5
+ from pydantic import BaseModel
2
6
 
3
7
  DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])
8
+ UnionType = getattr(types, "UnionType", Union)
9
+ NoneType = getattr(types, "UnionType", None)
10
+ ModelNameMap = Dict[Union[Type[BaseModel], Type[Enum]], str]
11
+ IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]]
fastapi/utils.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import re
2
2
  import warnings
3
3
  from dataclasses import is_dataclass
4
- from enum import Enum
5
4
  from typing import (
6
5
  TYPE_CHECKING,
7
6
  Any,
@@ -16,13 +15,19 @@ from typing import (
16
15
  from weakref import WeakKeyDictionary
17
16
 
18
17
  import fastapi
18
+ from fastapi._compat import (
19
+ PYDANTIC_V2,
20
+ BaseConfig,
21
+ ModelField,
22
+ PydanticSchemaGenerationError,
23
+ Undefined,
24
+ UndefinedType,
25
+ Validator,
26
+ lenient_issubclass,
27
+ )
19
28
  from fastapi.datastructures import DefaultPlaceholder, DefaultType
20
- from fastapi.openapi.constants import REF_PREFIX
21
- from pydantic import BaseConfig, BaseModel, create_model
22
- from pydantic.class_validators import Validator
23
- from pydantic.fields import FieldInfo, ModelField, UndefinedType
24
- from pydantic.schema import model_process_schema
25
- from pydantic.utils import lenient_issubclass
29
+ from pydantic import BaseModel, create_model
30
+ from pydantic.fields import FieldInfo
26
31
 
27
32
  if TYPE_CHECKING: # pragma: nocover
28
33
  from .routing import APIRoute
@@ -50,24 +55,6 @@ def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
50
55
  return not (current_status_code < 200 or current_status_code in {204, 304})
51
56
 
52
57
 
53
- def get_model_definitions(
54
- *,
55
- flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
56
- model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
57
- ) -> Dict[str, Any]:
58
- definitions: Dict[str, Dict[str, Any]] = {}
59
- for model in flat_models:
60
- m_schema, m_definitions, m_nested_models = model_process_schema(
61
- model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
62
- )
63
- definitions.update(m_definitions)
64
- model_name = model_name_map[model]
65
- if "description" in m_schema:
66
- m_schema["description"] = m_schema["description"].split("\f")[0]
67
- definitions[model_name] = m_schema
68
- return definitions
69
-
70
-
71
58
  def get_path_param_names(path: str) -> Set[str]:
72
59
  return set(re.findall("{(.*?)}", path))
73
60
 
@@ -76,8 +63,8 @@ def create_response_field(
76
63
  name: str,
77
64
  type_: Type[Any],
78
65
  class_validators: Optional[Dict[str, Validator]] = None,
79
- default: Optional[Any] = None,
80
- required: Union[bool, UndefinedType] = True,
66
+ default: Optional[Any] = Undefined,
67
+ required: Union[bool, UndefinedType] = Undefined,
81
68
  model_config: Type[BaseConfig] = BaseConfig,
82
69
  field_info: Optional[FieldInfo] = None,
83
70
  alias: Optional[str] = None,
@@ -86,20 +73,27 @@ def create_response_field(
86
73
  Create a new response field. Raises if type_ is invalid.
87
74
  """
88
75
  class_validators = class_validators or {}
89
- field_info = field_info or FieldInfo()
90
-
91
- try:
92
- return ModelField(
93
- name=name,
94
- type_=type_,
95
- class_validators=class_validators,
96
- default=default,
97
- required=required,
98
- model_config=model_config,
99
- alias=alias,
100
- field_info=field_info,
76
+ if PYDANTIC_V2:
77
+ field_info = field_info or FieldInfo(
78
+ annotation=type_, default=default, alias=alias
79
+ )
80
+ else:
81
+ field_info = field_info or FieldInfo()
82
+ kwargs = {"name": name, "field_info": field_info}
83
+ if not PYDANTIC_V2:
84
+ kwargs.update(
85
+ {
86
+ "type_": type_,
87
+ "class_validators": class_validators,
88
+ "default": default,
89
+ "required": required,
90
+ "model_config": model_config,
91
+ "alias": alias,
92
+ }
101
93
  )
102
- except RuntimeError:
94
+ try:
95
+ return ModelField(**kwargs) # type: ignore[arg-type]
96
+ except (RuntimeError, PydanticSchemaGenerationError):
103
97
  raise fastapi.exceptions.FastAPIError(
104
98
  "Invalid args for response field! Hint: "
105
99
  f"check that {type_} is a valid Pydantic field type. "
@@ -116,6 +110,8 @@ def create_cloned_field(
116
110
  *,
117
111
  cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
118
112
  ) -> ModelField:
113
+ if PYDANTIC_V2:
114
+ return field
119
115
  # cloned_types caches already cloned types to support recursive models and improve
120
116
  # performance by avoiding unecessary cloning
121
117
  if cloned_types is None:
@@ -136,30 +132,30 @@ def create_cloned_field(
136
132
  f, cloned_types=cloned_types
137
133
  )
138
134
  new_field = create_response_field(name=field.name, type_=use_type)
139
- new_field.has_alias = field.has_alias
140
- new_field.alias = field.alias
141
- new_field.class_validators = field.class_validators
142
- new_field.default = field.default
143
- new_field.required = field.required
144
- new_field.model_config = field.model_config
135
+ new_field.has_alias = field.has_alias # type: ignore[attr-defined]
136
+ new_field.alias = field.alias # type: ignore[misc]
137
+ new_field.class_validators = field.class_validators # type: ignore[attr-defined]
138
+ new_field.default = field.default # type: ignore[misc]
139
+ new_field.required = field.required # type: ignore[misc]
140
+ new_field.model_config = field.model_config # type: ignore[attr-defined]
145
141
  new_field.field_info = field.field_info
146
- new_field.allow_none = field.allow_none
147
- new_field.validate_always = field.validate_always
148
- if field.sub_fields:
149
- new_field.sub_fields = [
142
+ new_field.allow_none = field.allow_none # type: ignore[attr-defined]
143
+ new_field.validate_always = field.validate_always # type: ignore[attr-defined]
144
+ if field.sub_fields: # type: ignore[attr-defined]
145
+ new_field.sub_fields = [ # type: ignore[attr-defined]
150
146
  create_cloned_field(sub_field, cloned_types=cloned_types)
151
- for sub_field in field.sub_fields
147
+ for sub_field in field.sub_fields # type: ignore[attr-defined]
152
148
  ]
153
- if field.key_field:
154
- new_field.key_field = create_cloned_field(
155
- field.key_field, cloned_types=cloned_types
149
+ if field.key_field: # type: ignore[attr-defined]
150
+ new_field.key_field = create_cloned_field( # type: ignore[attr-defined]
151
+ field.key_field, cloned_types=cloned_types # type: ignore[attr-defined]
156
152
  )
157
- new_field.validators = field.validators
158
- new_field.pre_validators = field.pre_validators
159
- new_field.post_validators = field.post_validators
160
- new_field.parse_json = field.parse_json
161
- new_field.shape = field.shape
162
- new_field.populate_validators()
153
+ new_field.validators = field.validators # type: ignore[attr-defined]
154
+ new_field.pre_validators = field.pre_validators # type: ignore[attr-defined]
155
+ new_field.post_validators = field.post_validators # type: ignore[attr-defined]
156
+ new_field.parse_json = field.parse_json # type: ignore[attr-defined]
157
+ new_field.shape = field.shape # type: ignore[attr-defined]
158
+ new_field.populate_validators() # type: ignore[attr-defined]
163
159
  return new_field
164
160
 
165
161
 
@@ -220,3 +216,9 @@ def get_value_or_default(
220
216
  if not isinstance(item, DefaultPlaceholder):
221
217
  return item
222
218
  return first_item
219
+
220
+
221
+ def match_pydantic_error_url(error_type: str) -> Any:
222
+ from dirty_equals import IsStr
223
+
224
+ return IsStr(regex=rf"^https://errors\.pydantic\.dev/.*/v/{error_type}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastapi
3
- Version: 0.97.0
3
+ Version: 0.100.0b1
4
4
  Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production
5
5
  Project-URL: Homepage, https://github.com/tiangolo/fastapi
6
6
  Project-URL: Documentation, https://fastapi.tiangolo.com/
@@ -35,10 +35,10 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
35
35
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
36
36
  Classifier: Typing :: Typed
37
37
  Requires-Python: >=3.7
38
- Requires-Dist: pydantic!=1.8,!=1.8.1,<2.0.0,>=1.7.4
38
+ Requires-Dist: pydantic!=1.8,!=1.8.1,<3.0.0,>=1.7.4
39
39
  Requires-Dist: starlette<0.28.0,>=0.27.0
40
40
  Provides-Extra: all
41
- Requires-Dist: email-validator>=1.1.1; extra == 'all'
41
+ Requires-Dist: email-validator>=2.0.0; extra == 'all'
42
42
  Requires-Dist: httpx>=0.23.0; extra == 'all'
43
43
  Requires-Dist: itsdangerous>=1.1.0; extra == 'all'
44
44
  Requires-Dist: jinja2>=2.11.2; extra == 'all'
@@ -1,27 +1,28 @@
1
- fastapi/__init__.py,sha256=NWz58XArsNliUO7UUgxKRpARzhzW3iOSh-6UA38tcsg,1080
2
- fastapi/applications.py,sha256=BVJ0f9i-CjOLEH1aKSinBCTpRacm5AfyaBFG5wB5uJk,40237
1
+ fastapi/__init__.py,sha256=Tm2hOQVUqkeQv_OyRPPUyRV0Bhsm0JG1ueUZ9TEMW3s,1087
2
+ fastapi/_compat.py,sha256=yrfYJ1RpV0p4SWnAEaQBiFORlaNlSDNFM2Z0J4ZXf8I,21720
3
+ fastapi/applications.py,sha256=QHZl3DQ-u8epXGpycMPZThp5tKNw-RWf3KOJ8XI5AZw,39670
3
4
  fastapi/background.py,sha256=HtN5_pJJrOdalSbuGSMKJAPNWUU5h7rY_BXXubu7-IQ,76
4
5
  fastapi/concurrency.py,sha256=h7ZhZG8cEiVx6an1txcB2RKpjW6_xmHwFo9E3vUiMQA,1468
5
- fastapi/datastructures.py,sha256=oW6xuU0C-sBwbcyXI-MlBO0tSS4BSPB2lYUa1yCw8-A,1905
6
- fastapi/encoders.py,sha256=UaRHIlxyt4vSzV93dCIz9sLykxH4Xbmp7cALTK1-hnk,5962
6
+ fastapi/datastructures.py,sha256=iWyfPvU6gZuFPHUC1RzRQP6VnLqYWnD75no5uLIxB48,2793
7
+ fastapi/encoders.py,sha256=YdNUJ2s_kbvfaJS-QwE2dUDoXH75QM_k9fghp1DJcaw,8049
7
8
  fastapi/exception_handlers.py,sha256=MBrIOA-ugjJDivIi4rSsUJBdTsjuzN76q4yh0q1COKw,1332
8
- fastapi/exceptions.py,sha256=rYONIZZhCPYCrA8XTNMQ07GVsGBSN7LipSLsoFB3JMk,1205
9
+ fastapi/exceptions.py,sha256=B-KRexbd3Vtf_cP_YYY9ZocPGoGn1F2UvJ41Cdi0_3k,1400
9
10
  fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54
10
- fastapi/param_functions.py,sha256=3QrctOwg7QE8b9XOqM29HTDtt7cEq96WhJPIFN703z4,7515
11
- fastapi/params.py,sha256=93bQyDIhTXZHv1vS7TF3GFCJZGP02JHZpA1qu3wJuYE,10699
11
+ fastapi/param_functions.py,sha256=7jn9ImOfZYax9vf7rfCxnI3K7S_cd_tbwF8voBG7WqE,7935
12
+ fastapi/params.py,sha256=ZoDrmquzxwZqoH2zv0KLPiTwSA7qEpnPJD67TYf59e0,12649
12
13
  fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142
14
15
  fastapi/responses.py,sha256=on95e4CfSRyNz7MEjqFuzsP-eW8kHWTxEl_Z-Vzb7lA,1242
15
- fastapi/routing.py,sha256=ENL3MNsSqlqo5Io7AGj0g7reX59PhfwIRsfQTEsTIhc,56490
16
+ fastapi/routing.py,sha256=2r-WPLC_gebnxauKhWDkMpVxNtp9NvJXJPjAo4vY0yk,56711
16
17
  fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69
17
18
  fastapi/templating.py,sha256=4zsuTWgcjcEainMJFAlW6-gnslm6AgOS1SiiDWfmQxk,76
18
19
  fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66
19
- fastapi/types.py,sha256=r6MngTHzkZOP9lzXgduje9yeZe5EInWAzCLuRJlhIuE,118
20
- fastapi/utils.py,sha256=ROfkxh6erG_hGkmTNGE4gD36D_dZ33R5jL8GOjzHGPM,7652
20
+ fastapi/types.py,sha256=WZJ1jvm1MCwIrxxRYxKwtXS9HqcGk0RnCbLzrMZh-lI,428
21
+ fastapi/utils.py,sha256=NuJGGAaFZXGmT1_D7IzZOuXOir4pNotHJtNXDS_7l6A,8032
21
22
  fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222
22
23
  fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- fastapi/dependencies/models.py,sha256=zNbioxICuOeb-9ADDVQ45hUHOC0PBtPVEfVU3f1l_nc,2494
24
- fastapi/dependencies/utils.py,sha256=hDn1Uz6g_CiSrQikwA8WrYs_vH-Og5kG2a1qFFc6ZpA,30908
24
+ fastapi/dependencies/models.py,sha256=-n-YCxzgVBkurQi49qOTooT71v_oeAhHJ-qQFonxh5o,2494
25
+ fastapi/dependencies/utils.py,sha256=ffWJykKesqKxA_YVmrNhKogCF33AfZ2by0Tzfr_JlvY,29721
25
26
  fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58
26
27
  fastapi/middleware/asyncexitstack.py,sha256=LvMyVI1QdmWNWYPZqx295VFavssUfVpUsonPOsMWz1E,1035
27
28
  fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79
@@ -30,18 +31,18 @@ fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs
30
31
  fastapi/middleware/trustedhost.py,sha256=eE5XGRxGa7c5zPnMJDGp3BxaL25k5iVQlhnv-Pk0Pss,109
31
32
  fastapi/middleware/wsgi.py,sha256=Z3Ue-7wni4lUZMvH3G9ek__acgYdJstbnpZX_HQAboY,79
32
33
  fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- fastapi/openapi/constants.py,sha256=mWxYBjED6PU-tQ9X227Qkq2SsW2cv-C1jYFKt63xxEs,107
34
+ fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153
34
35
  fastapi/openapi/docs.py,sha256=JBRaq7EEmeC-xoRSRFj6qZWQxfOZW_jvTw0r-PiKcZ4,6532
35
- fastapi/openapi/models.py,sha256=voJsvf29rdZLIuLlhul3SRCZvMbo6vCpTBNZSk8yRwg,11204
36
- fastapi/openapi/utils.py,sha256=99wU5c3v4jlo39B3YEB7xKBRYE83kcAxP9m3t44uZ2I,18778
36
+ fastapi/openapi/models.py,sha256=5ddjP5Zt9uw7osLKCEJRCCTEwpP-4YPAnyM3a-HvCD8,13995
37
+ fastapi/openapi/utils.py,sha256=14SKsXYmWUpO-HTXaVg5YX_n1Zh8Egs60-msJUwP1JU,19346
37
38
  fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881
38
39
  fastapi/security/api_key.py,sha256=92kxZjj9OuIvQCUpLszP9qlILRgx6hCh1x-bZdhmQDU,2939
39
40
  fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141
40
41
  fastapi/security/http.py,sha256=VbTm1k6t6EjJAnCnYVquSOmSK7fATdKRgq0-TgC7FnQ,5964
41
- fastapi/security/oauth2.py,sha256=I0DyRHEmfn_Up8vpYl3H8EV0dTdl5T1S3ib8EtRqfMI,8360
42
+ fastapi/security/oauth2.py,sha256=fXQdWuTtUKSZ9Lyrj9fDuQoXAmXTd9AVFDrrwStJKX0,8579
42
43
  fastapi/security/open_id_connect_url.py,sha256=GKK84g6OZbOFCEZJyd27pGjpaClGxeZrYOemUzyhfbU,1141
43
44
  fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293
44
- fastapi-0.97.0.dist-info/METADATA,sha256=Ey8iBuM5nPduODfzkZ8I5f0WCk6EUA4K-S8Zesstbso,23107
45
- fastapi-0.97.0.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
46
- fastapi-0.97.0.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
47
- fastapi-0.97.0.dist-info/RECORD,,
45
+ fastapi-0.100.0b1.dist-info/METADATA,sha256=ylm5qTc3E-Qlaurbx_NcPHO-T9ONJpPLrZJpEKKcCS8,23110
46
+ fastapi-0.100.0b1.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
47
+ fastapi-0.100.0b1.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
48
+ fastapi-0.100.0b1.dist-info/RECORD,,