fastapi 0.114.2__py3-none-any.whl → 0.115.1__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 CHANGED
@@ -1,6 +1,6 @@
1
1
  """FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
2
2
 
3
- __version__ = "0.114.2"
3
+ __version__ = "0.115.1"
4
4
 
5
5
  from starlette import status as status
6
6
 
fastapi/_compat.py CHANGED
@@ -71,7 +71,7 @@ if PYDANTIC_V2:
71
71
  general_plain_validator_function as with_info_plain_validator_function, # noqa: F401
72
72
  )
73
73
 
74
- Required = PydanticUndefined
74
+ RequiredParam = PydanticUndefined
75
75
  Undefined = PydanticUndefined
76
76
  UndefinedType = PydanticUndefinedType
77
77
  evaluate_forwardref = eval_type_lenient
@@ -313,9 +313,10 @@ else:
313
313
  from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
314
314
  ModelField as ModelField, # noqa: F401
315
315
  )
316
- from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
317
- Required as Required, # noqa: F401
318
- )
316
+
317
+ # Keeping old "Required" functionality from Pydantic V1, without
318
+ # shadowing typing.Required.
319
+ RequiredParam: Any = Ellipsis # type: ignore[no-redef]
319
320
  from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
320
321
  Undefined as Undefined,
321
322
  )
@@ -24,7 +24,7 @@ from fastapi._compat import (
24
24
  PYDANTIC_V2,
25
25
  ErrorWrapper,
26
26
  ModelField,
27
- Required,
27
+ RequiredParam,
28
28
  Undefined,
29
29
  _regenerate_error_with_loc,
30
30
  copy_field_info,
@@ -91,14 +91,14 @@ multipart_incorrect_install_error = (
91
91
  def ensure_multipart_is_installed() -> None:
92
92
  try:
93
93
  # __version__ is available in both multiparts, and can be mocked
94
- from multipart import __version__ # type: ignore
94
+ from multipart import __version__
95
95
 
96
96
  assert __version__
97
97
  try:
98
98
  # parse_options_header is only available in the right multipart
99
- from multipart.multipart import parse_options_header # type: ignore
99
+ from multipart.multipart import parse_options_header
100
100
 
101
- assert parse_options_header
101
+ assert parse_options_header # type: ignore[truthy-function]
102
102
  except ImportError:
103
103
  logger.error(multipart_incorrect_install_error)
104
104
  raise RuntimeError(multipart_incorrect_install_error) from None
@@ -201,14 +201,23 @@ def get_flat_dependant(
201
201
  return flat_dependant
202
202
 
203
203
 
204
+ def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
205
+ if not fields:
206
+ return fields
207
+ first_field = fields[0]
208
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
209
+ fields_to_extract = get_cached_model_fields(first_field.type_)
210
+ return fields_to_extract
211
+ return fields
212
+
213
+
204
214
  def get_flat_params(dependant: Dependant) -> List[ModelField]:
205
215
  flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
206
- return (
207
- flat_dependant.path_params
208
- + flat_dependant.query_params
209
- + flat_dependant.header_params
210
- + flat_dependant.cookie_params
211
- )
216
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
217
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
218
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
219
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
220
+ return path_params + query_params + header_params + cookie_params
212
221
 
213
222
 
214
223
  def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
@@ -368,7 +377,9 @@ def analyze_param(
368
377
  field_info = copy_field_info(
369
378
  field_info=fastapi_annotation, annotation=use_annotation
370
379
  )
371
- assert field_info.default is Undefined or field_info.default is Required, (
380
+ assert (
381
+ field_info.default is Undefined or field_info.default is RequiredParam
382
+ ), (
372
383
  f"`{field_info.__class__.__name__}` default value cannot be set in"
373
384
  f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
374
385
  )
@@ -376,7 +387,7 @@ def analyze_param(
376
387
  assert not is_path_param, "Path parameters cannot have default values"
377
388
  field_info.default = value
378
389
  else:
379
- field_info.default = Required
390
+ field_info.default = RequiredParam
380
391
  # Get Annotated Depends
381
392
  elif isinstance(fastapi_annotation, params.Depends):
382
393
  depends = fastapi_annotation
@@ -425,9 +436,9 @@ def analyze_param(
425
436
  ), f"Cannot specify FastAPI annotation for type {type_annotation!r}"
426
437
  # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
427
438
  elif field_info is None and depends is None:
428
- default_value = value if value is not inspect.Signature.empty else Required
439
+ default_value = value if value is not inspect.Signature.empty else RequiredParam
429
440
  if is_path_param:
430
- # We might check here that `default_value is Required`, but the fact is that the same
441
+ # We might check here that `default_value is RequiredParam`, but the fact is that the same
431
442
  # parameter might sometimes be a path parameter and sometimes not. See
432
443
  # `tests/test_infer_param_optionality.py` for an example.
433
444
  field_info = params.Path(annotation=use_annotation)
@@ -471,7 +482,7 @@ def analyze_param(
471
482
  type_=use_annotation_from_field_info,
472
483
  default=field_info.default,
473
484
  alias=alias,
474
- required=field_info.default in (Required, Undefined),
485
+ required=field_info.default in (RequiredParam, Undefined),
475
486
  field_info=field_info,
476
487
  )
477
488
  if is_path_param:
@@ -479,7 +490,15 @@ def analyze_param(
479
490
  field=field
480
491
  ), "Path params must be of one of the supported types"
481
492
  elif isinstance(field_info, params.Query):
482
- assert is_scalar_field(field) or is_scalar_sequence_field(field)
493
+ assert (
494
+ is_scalar_field(field)
495
+ or is_scalar_sequence_field(field)
496
+ or (
497
+ lenient_issubclass(field.type_, BaseModel)
498
+ # For Pydantic v1
499
+ and getattr(field, "shape", 1) == 1
500
+ )
501
+ )
483
502
 
484
503
  return ParamDetails(type_annotation=type_annotation, depends=depends, field=field)
485
504
 
@@ -686,11 +705,14 @@ def _validate_value_with_model_field(
686
705
  return v_, []
687
706
 
688
707
 
689
- def _get_multidict_value(field: ModelField, values: Mapping[str, Any]) -> Any:
708
+ def _get_multidict_value(
709
+ field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None
710
+ ) -> Any:
711
+ alias = alias or field.alias
690
712
  if is_sequence_field(field) and isinstance(values, (ImmutableMultiDict, Headers)):
691
- value = values.getlist(field.alias)
713
+ value = values.getlist(alias)
692
714
  else:
693
- value = values.get(field.alias, None)
715
+ value = values.get(alias, None)
694
716
  if (
695
717
  value is None
696
718
  or (
@@ -712,7 +734,55 @@ def request_params_to_args(
712
734
  received_params: Union[Mapping[str, Any], QueryParams, Headers],
713
735
  ) -> Tuple[Dict[str, Any], List[Any]]:
714
736
  values: Dict[str, Any] = {}
715
- errors = []
737
+ errors: List[Dict[str, Any]] = []
738
+
739
+ if not fields:
740
+ return values, errors
741
+
742
+ first_field = fields[0]
743
+ fields_to_extract = fields
744
+ single_not_embedded_field = False
745
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
746
+ fields_to_extract = get_cached_model_fields(first_field.type_)
747
+ single_not_embedded_field = True
748
+
749
+ params_to_process: Dict[str, Any] = {}
750
+
751
+ processed_keys = set()
752
+
753
+ for field in fields_to_extract:
754
+ alias = None
755
+ if isinstance(received_params, Headers):
756
+ # Handle fields extracted from a Pydantic Model for a header, each field
757
+ # doesn't have a FieldInfo of type Header with the default convert_underscores=True
758
+ convert_underscores = getattr(field.field_info, "convert_underscores", True)
759
+ if convert_underscores:
760
+ alias = (
761
+ field.alias
762
+ if field.alias != field.name
763
+ else field.name.replace("_", "-")
764
+ )
765
+ value = _get_multidict_value(field, received_params, alias=alias)
766
+ if value is not None:
767
+ params_to_process[field.name] = value
768
+ processed_keys.add(alias or field.alias)
769
+ processed_keys.add(field.name)
770
+
771
+ for key, value in received_params.items():
772
+ if key not in processed_keys:
773
+ params_to_process[key] = value
774
+
775
+ if single_not_embedded_field:
776
+ field_info = first_field.field_info
777
+ assert isinstance(
778
+ field_info, params.Param
779
+ ), "Params must be subclasses of Param"
780
+ loc: Tuple[str, ...] = (field_info.in_.value,)
781
+ v_, errors_ = _validate_value_with_model_field(
782
+ field=first_field, value=params_to_process, values=values, loc=loc
783
+ )
784
+ return {first_field.name: v_}, errors_
785
+
716
786
  for field in fields:
717
787
  value = _get_multidict_value(field, received_params)
718
788
  field_info = field.field_info
fastapi/openapi/utils.py CHANGED
@@ -16,11 +16,15 @@ from fastapi._compat import (
16
16
  )
17
17
  from fastapi.datastructures import DefaultPlaceholder
18
18
  from fastapi.dependencies.models import Dependant
19
- from fastapi.dependencies.utils import get_flat_dependant, get_flat_params
19
+ from fastapi.dependencies.utils import (
20
+ _get_flat_fields_from_params,
21
+ get_flat_dependant,
22
+ get_flat_params,
23
+ )
20
24
  from fastapi.encoders import jsonable_encoder
21
25
  from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
22
26
  from fastapi.openapi.models import OpenAPI
23
- from fastapi.params import Body, Param
27
+ from fastapi.params import Body, ParamTypes
24
28
  from fastapi.responses import Response
25
29
  from fastapi.types import ModelNameMap
26
30
  from fastapi.utils import (
@@ -87,9 +91,9 @@ def get_openapi_security_definitions(
87
91
  return security_definitions, operation_security
88
92
 
89
93
 
90
- def get_openapi_operation_parameters(
94
+ def _get_openapi_operation_parameters(
91
95
  *,
92
- all_route_params: Sequence[ModelField],
96
+ dependant: Dependant,
93
97
  schema_generator: GenerateJsonSchema,
94
98
  model_name_map: ModelNameMap,
95
99
  field_mapping: Dict[
@@ -98,33 +102,47 @@ def get_openapi_operation_parameters(
98
102
  separate_input_output_schemas: bool = True,
99
103
  ) -> List[Dict[str, Any]]:
100
104
  parameters = []
101
- for param in all_route_params:
102
- field_info = param.field_info
103
- field_info = cast(Param, field_info)
104
- if not field_info.include_in_schema:
105
- continue
106
- param_schema = get_schema_from_model_field(
107
- field=param,
108
- schema_generator=schema_generator,
109
- model_name_map=model_name_map,
110
- field_mapping=field_mapping,
111
- separate_input_output_schemas=separate_input_output_schemas,
112
- )
113
- parameter = {
114
- "name": param.alias,
115
- "in": field_info.in_.value,
116
- "required": param.required,
117
- "schema": param_schema,
118
- }
119
- if field_info.description:
120
- parameter["description"] = field_info.description
121
- if field_info.openapi_examples:
122
- parameter["examples"] = jsonable_encoder(field_info.openapi_examples)
123
- elif field_info.example != Undefined:
124
- parameter["example"] = jsonable_encoder(field_info.example)
125
- if field_info.deprecated:
126
- parameter["deprecated"] = True
127
- parameters.append(parameter)
105
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
106
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
107
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
108
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
109
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
110
+ parameter_groups = [
111
+ (ParamTypes.path, path_params),
112
+ (ParamTypes.query, query_params),
113
+ (ParamTypes.header, header_params),
114
+ (ParamTypes.cookie, cookie_params),
115
+ ]
116
+ for param_type, param_group in parameter_groups:
117
+ for param in param_group:
118
+ field_info = param.field_info
119
+ # field_info = cast(Param, field_info)
120
+ if not getattr(field_info, "include_in_schema", True):
121
+ continue
122
+ param_schema = get_schema_from_model_field(
123
+ field=param,
124
+ schema_generator=schema_generator,
125
+ model_name_map=model_name_map,
126
+ field_mapping=field_mapping,
127
+ separate_input_output_schemas=separate_input_output_schemas,
128
+ )
129
+ parameter = {
130
+ "name": param.alias,
131
+ "in": param_type.value,
132
+ "required": param.required,
133
+ "schema": param_schema,
134
+ }
135
+ if field_info.description:
136
+ parameter["description"] = field_info.description
137
+ openapi_examples = getattr(field_info, "openapi_examples", None)
138
+ example = getattr(field_info, "example", None)
139
+ if openapi_examples:
140
+ parameter["examples"] = jsonable_encoder(openapi_examples)
141
+ elif example != Undefined:
142
+ parameter["example"] = jsonable_encoder(example)
143
+ if getattr(field_info, "deprecated", None):
144
+ parameter["deprecated"] = True
145
+ parameters.append(parameter)
128
146
  return parameters
129
147
 
130
148
 
@@ -247,9 +265,8 @@ def get_openapi_path(
247
265
  operation.setdefault("security", []).extend(operation_security)
248
266
  if security_definitions:
249
267
  security_schemes.update(security_definitions)
250
- all_route_params = get_flat_params(route.dependant)
251
- operation_parameters = get_openapi_operation_parameters(
252
- all_route_params=all_route_params,
268
+ operation_parameters = _get_openapi_operation_parameters(
269
+ dependant=route.dependant,
253
270
  schema_generator=schema_generator,
254
271
  model_name_map=model_name_map,
255
272
  field_mapping=field_mapping,
@@ -379,6 +396,7 @@ def get_openapi_path(
379
396
  deep_dict_update(openapi_response, process_response)
380
397
  openapi_response["description"] = description
381
398
  http422 = str(HTTP_422_UNPROCESSABLE_ENTITY)
399
+ all_route_params = get_flat_params(route.dependant)
382
400
  if (all_route_params or route.body_field) and not any(
383
401
  status in operation["responses"]
384
402
  for status in [http422, "4XX", "default"]
fastapi/routing.py CHANGED
@@ -541,7 +541,9 @@ class APIRoute(routing.Route):
541
541
  additional_status_code
542
542
  ), f"Status code {additional_status_code} must not have a response body"
543
543
  response_name = f"Response_{additional_status_code}_{self.unique_id}"
544
- response_field = create_model_field(name=response_name, type_=model)
544
+ response_field = create_model_field(
545
+ name=response_name, type_=model, mode="serialization"
546
+ )
545
547
  response_fields[additional_status_code] = response_field
546
548
  if response_fields:
547
549
  self.response_fields: Dict[Union[int, str], ModelField] = response_fields
fastapi/security/http.py CHANGED
@@ -277,7 +277,7 @@ class HTTPBearer(HTTPBase):
277
277
  bool,
278
278
  Doc(
279
279
  """
280
- By default, if the HTTP Bearer token not provided (in an
280
+ By default, if the HTTP Bearer token is not provided (in an
281
281
  `Authorization` header), `HTTPBearer` will automatically cancel the
282
282
  request and send the client an error.
283
283
 
@@ -380,7 +380,7 @@ class HTTPDigest(HTTPBase):
380
380
  bool,
381
381
  Doc(
382
382
  """
383
- By default, if the HTTP Digest not provided, `HTTPDigest` will
383
+ By default, if the HTTP Digest is not provided, `HTTPDigest` will
384
384
  automatically cancel the request and send the client an error.
385
385
 
386
386
  If `auto_error` is set to `False`, when the HTTP Digest is not
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastapi
3
- Version: 0.114.2
3
+ Version: 0.115.1
4
4
  Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production
5
5
  Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
6
6
  Classifier: Intended Audience :: Information Technology
@@ -39,12 +39,14 @@ Requires-Python: >=3.8
39
39
  Requires-Dist: starlette<0.39.0,>=0.37.2
40
40
  Requires-Dist: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4
41
41
  Requires-Dist: typing-extensions>=4.8.0
42
+ Provides-Extra: standard
42
43
  Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "standard"
43
44
  Requires-Dist: httpx>=0.23.0; extra == "standard"
44
45
  Requires-Dist: jinja2>=2.11.2; extra == "standard"
45
46
  Requires-Dist: python-multipart>=0.0.7; extra == "standard"
46
47
  Requires-Dist: email-validator>=2.0.0; extra == "standard"
47
48
  Requires-Dist: uvicorn[standard]>=0.12.0; extra == "standard"
49
+ Provides-Extra: all
48
50
  Requires-Dist: fastapi-cli[standard]>=0.0.5; extra == "all"
49
51
  Requires-Dist: httpx>=0.23.0; extra == "all"
50
52
  Requires-Dist: jinja2>=2.11.2; extra == "all"
@@ -57,8 +59,6 @@ Requires-Dist: email-validator>=2.0.0; extra == "all"
57
59
  Requires-Dist: uvicorn[standard]>=0.12.0; extra == "all"
58
60
  Requires-Dist: pydantic-settings>=2.0.0; extra == "all"
59
61
  Requires-Dist: pydantic-extra-types>=2.0.0; extra == "all"
60
- Provides-Extra: standard
61
- Provides-Extra: all
62
62
  Description-Content-Type: text/markdown
63
63
 
64
64
  <p align="center">
@@ -118,7 +118,6 @@ The key features are:
118
118
  <a href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=website" target="_blank" title="Coherence"><img src="https://fastapi.tiangolo.com/img/sponsors/coherence.png"></a>
119
119
  <a href="https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral" target="_blank" title="Simplify Full Stack Development with FastAPI & MongoDB"><img src="https://fastapi.tiangolo.com/img/sponsors/mongodb.png"></a>
120
120
  <a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Scale, Protect, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
121
- <a href="https://fine.dev?ref=fastapibadge" target="_blank" title="Fine's AI FastAPI Workflow: Effortlessly Deploy and Integrate FastAPI into Your Project"><img src="https://fastapi.tiangolo.com/img/sponsors/fine.png"></a>
122
121
  <a href="https://liblab.com?utm_source=fastapi" target="_blank" title="liblab - Generate SDKs from FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/liblab.png"></a>
123
122
  <a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
124
123
  <a href="https://databento.com/" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
@@ -1,10 +1,10 @@
1
- fastapi-0.114.2.dist-info/METADATA,sha256=MWrFpCnfw9bj9yTHhJZ4sB6nWA9MoxTCbHwK3Zg_AG4,27227
2
- fastapi-0.114.2.dist-info/WHEEL,sha256=rSwsxJWe3vzyR5HCwjWXQruDgschpei4h_giTm0dJVE,90
3
- fastapi-0.114.2.dist-info/entry_points.txt,sha256=Nn2-rs4A5_lQZko2b9QqCKQx9Irx0agGbxq3QLgjBxQ,46
4
- fastapi-0.114.2.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
5
- fastapi/__init__.py,sha256=2VfxjcXPXxuL2LFjtc1VHbVyjpHDy_Gz3Dm28lsWC7Y,1081
1
+ fastapi-0.115.1.dist-info/METADATA,sha256=yw4W2DRChFP66VEIdz3pwMF0RNW8zbRQBKy0zPOgnDU,27004
2
+ fastapi-0.115.1.dist-info/WHEEL,sha256=pM0IBB6ZwH3nkEPhtcp50KvKNX-07jYtnb1g1m6Z4Co,90
3
+ fastapi-0.115.1.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61
4
+ fastapi-0.115.1.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
5
+ fastapi/__init__.py,sha256=rtkZiVS1ILuYGg82wGVj3aPh00KApOwKTjJhDLKjbLw,1081
6
6
  fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37
7
- fastapi/_compat.py,sha256=N4y7exHYWpWytEwsDU31YHDXoJRvHxREx2qNS3bF85o,23876
7
+ fastapi/_compat.py,sha256=GJTevkAENKrvtvAGL3zDEmzlXaX9EjFzyRPtSfVRCKs,23921
8
8
  fastapi/applications.py,sha256=Ix-o9pQAWhEDf9J0Q1hZ0nBB1uP72c-Y3oiYzvrwqiM,176316
9
9
  fastapi/background.py,sha256=rouLirxUANrcYC824MSMypXL_Qb2HYg2YZqaiEqbEKI,1768
10
10
  fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418
@@ -12,7 +12,7 @@ fastapi/concurrency.py,sha256=AYLnS4judDUmXsNRICtoKSP0prfYDcS8ehBtYW9JhQQ,1403
12
12
  fastapi/datastructures.py,sha256=b2PEz77XGq-u3Ur1Inwk0AGjOsQZO49yF9C7IPJ15cY,5766
13
13
  fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  fastapi/dependencies/models.py,sha256=Pjl6vx-4nZ5Tta9kJa3-RfQKkXtCpS09-FhMgs9eWNs,1507
15
- fastapi/dependencies/utils.py,sha256=Wy64GYBlQAsYmlPQzKRKo6tWFYBGZ6aLFxnB7qZSCnY,32474
15
+ fastapi/dependencies/utils.py,sha256=os09kCYSbaseQ7MVCdjrZWaTxrpFUTWqDYAYTZ5qt_w,35235
16
16
  fastapi/encoders.py,sha256=LvwYmFeOz4tVwvgBoC5rvZnbr7hZr73KGrU8O7zSptU,11068
17
17
  fastapi/exception_handlers.py,sha256=MBrIOA-ugjJDivIi4rSsUJBdTsjuzN76q4yh0q1COKw,1332
18
18
  fastapi/exceptions.py,sha256=taNixuFEXb67lI1bnX1ubq8y8TseJ4yoPlWjyP0fTzk,4969
@@ -27,17 +27,17 @@ fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153
28
28
  fastapi/openapi/docs.py,sha256=XcQq-ZbQdC5sI0gIGu5MoHK1q-OFaqws7-ORTo6sjY4,10348
29
29
  fastapi/openapi/models.py,sha256=PqkxQiqcEgjKuhfUIWPZPQcyTcubtUCB3vcObLsB7VE,15397
30
- fastapi/openapi/utils.py,sha256=asSbOKDuagDfpByNQvPy7OM0sqOBdUmqh64BH-n-5f0,22286
30
+ fastapi/openapi/utils.py,sha256=vpbAzWpuNaJL_ocBxt4jp0GUUwrDKNB1anyoAx69fhA,23177
31
31
  fastapi/param_functions.py,sha256=uQzNlihlhM80u4Xbstz__D3L3yxpTqLmsC-Hra1WfqE,64018
32
32
  fastapi/params.py,sha256=XC025dCSObp7fXhOPYo-jwXQRGZ9CwlfNRq2cLh_dRk,28186
33
33
  fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142
35
35
  fastapi/responses.py,sha256=QNQQlwpKhQoIPZTTWkpc9d_QGeGZ_aVQPaDV3nQ8m7c,1761
36
- fastapi/routing.py,sha256=LnYhRsafzHporfz4aDUmEk8qDU2tarLZNjHaKy3RB7w,176148
36
+ fastapi/routing.py,sha256=WK06IwZeyRwxkdB4uHZ7JXinxtVOxM8Ke0tqHaDOvYA,176208
37
37
  fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881
38
38
  fastapi/security/api_key.py,sha256=_OqUUjEHG5_MT1IPAhXIGJRCPldTBdSww_DegFy_W8Y,9368
39
39
  fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141
40
- fastapi/security/http.py,sha256=sXw3jvaMPxDmMaGlf5e2ES5TuGXDKXFOigntzUfSqIg,13506
40
+ fastapi/security/http.py,sha256=223bAV_d7NjI57Pzhbd_KlQTYlMyr5MoN1TW80rbxF8,13512
41
41
  fastapi/security/oauth2.py,sha256=lWemX4CLAvanR6-jiQxFtOyHjHbzEnNbpytA_WXgZcw,21583
42
42
  fastapi/security/open_id_connect_url.py,sha256=8vizZ2tGqEp1ur8SwtVgyHJhGAJ5AqahgcvSpaIioDI,2722
43
43
  fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293
@@ -47,4 +47,4 @@ fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66
47
47
  fastapi/types.py,sha256=nFb36sK3DSoqoyo7Miwy3meKK5UdFBgkAgLSzQlUVyI,383
48
48
  fastapi/utils.py,sha256=y8Bj5ttMaI9tS4D60OUgXqKnktBr99NdYUnHHV9LgoY,7948
49
49
  fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222
50
- fastapi-0.114.2.dist-info/RECORD,,
50
+ fastapi-0.115.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: pdm-backend (2.3.3)
2
+ Generator: pdm-backend (2.4.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,3 +1,5 @@
1
1
  [console_scripts]
2
2
  fastapi = fastapi.cli:main
3
3
 
4
+ [gui_scripts]
5
+