fastapi 0.118.3__py3-none-any.whl → 0.119.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.

@@ -23,11 +23,11 @@ import anyio
23
23
  from fastapi import params
24
24
  from fastapi._compat import (
25
25
  PYDANTIC_V2,
26
- ErrorWrapper,
27
26
  ModelField,
28
27
  RequiredParam,
29
28
  Undefined,
30
- _regenerate_error_with_loc,
29
+ _is_error_wrapper,
30
+ _is_model_class,
31
31
  copy_field_info,
32
32
  create_body_model,
33
33
  evaluate_forwardref,
@@ -43,10 +43,12 @@ from fastapi._compat import (
43
43
  is_uploadfile_or_nonable_uploadfile_annotation,
44
44
  is_uploadfile_sequence_annotation,
45
45
  lenient_issubclass,
46
+ may_v1,
46
47
  sequence_types,
47
48
  serialize_sequence_value,
48
49
  value_is_sequence,
49
50
  )
51
+ from fastapi._compat.shared import annotation_is_pydantic_v1
50
52
  from fastapi.background import BackgroundTasks
51
53
  from fastapi.concurrency import (
52
54
  asynccontextmanager,
@@ -74,6 +76,8 @@ from starlette.responses import Response
74
76
  from starlette.websockets import WebSocket
75
77
  from typing_extensions import Annotated, get_args, get_origin
76
78
 
79
+ from .. import temp_pydantic_v1_params
80
+
77
81
  if sys.version_info >= (3, 13): # pragma: no cover
78
82
  from inspect import iscoroutinefunction
79
83
  else: # pragma: no cover
@@ -219,7 +223,7 @@ def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
219
223
  if not fields:
220
224
  return fields
221
225
  first_field = fields[0]
222
- if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
226
+ if len(fields) == 1 and _is_model_class(first_field.type_):
223
227
  fields_to_extract = get_cached_model_fields(first_field.type_)
224
228
  return fields_to_extract
225
229
  return fields
@@ -315,7 +319,9 @@ def get_dependant(
315
319
  )
316
320
  continue
317
321
  assert param_details.field is not None
318
- if isinstance(param_details.field.field_info, params.Body):
322
+ if isinstance(
323
+ param_details.field.field_info, (params.Body, temp_pydantic_v1_params.Body)
324
+ ):
319
325
  dependant.body_params.append(param_details.field)
320
326
  else:
321
327
  add_param_to_fields(field=param_details.field, dependant=dependant)
@@ -374,28 +380,38 @@ def analyze_param(
374
380
  fastapi_annotations = [
375
381
  arg
376
382
  for arg in annotated_args[1:]
377
- if isinstance(arg, (FieldInfo, params.Depends))
383
+ if isinstance(arg, (FieldInfo, may_v1.FieldInfo, params.Depends))
378
384
  ]
379
385
  fastapi_specific_annotations = [
380
386
  arg
381
387
  for arg in fastapi_annotations
382
- if isinstance(arg, (params.Param, params.Body, params.Depends))
388
+ if isinstance(
389
+ arg,
390
+ (
391
+ params.Param,
392
+ temp_pydantic_v1_params.Param,
393
+ params.Body,
394
+ temp_pydantic_v1_params.Body,
395
+ params.Depends,
396
+ ),
397
+ )
383
398
  ]
384
399
  if fastapi_specific_annotations:
385
- fastapi_annotation: Union[FieldInfo, params.Depends, None] = (
386
- fastapi_specific_annotations[-1]
387
- )
400
+ fastapi_annotation: Union[
401
+ FieldInfo, may_v1.FieldInfo, params.Depends, None
402
+ ] = fastapi_specific_annotations[-1]
388
403
  else:
389
404
  fastapi_annotation = None
390
405
  # Set default for Annotated FieldInfo
391
- if isinstance(fastapi_annotation, FieldInfo):
406
+ if isinstance(fastapi_annotation, (FieldInfo, may_v1.FieldInfo)):
392
407
  # Copy `field_info` because we mutate `field_info.default` below.
393
408
  field_info = copy_field_info(
394
409
  field_info=fastapi_annotation, annotation=use_annotation
395
410
  )
396
- assert (
397
- field_info.default is Undefined or field_info.default is RequiredParam
398
- ), (
411
+ assert field_info.default in {
412
+ Undefined,
413
+ may_v1.Undefined,
414
+ } or field_info.default in {RequiredParam, may_v1.RequiredParam}, (
399
415
  f"`{field_info.__class__.__name__}` default value cannot be set in"
400
416
  f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
401
417
  )
@@ -419,14 +435,15 @@ def analyze_param(
419
435
  )
420
436
  depends = value
421
437
  # Get FieldInfo from default value
422
- elif isinstance(value, FieldInfo):
438
+ elif isinstance(value, (FieldInfo, may_v1.FieldInfo)):
423
439
  assert field_info is None, (
424
440
  "Cannot specify FastAPI annotations in `Annotated` and default value"
425
441
  f" together for {param_name!r}"
426
442
  )
427
443
  field_info = value
428
444
  if PYDANTIC_V2:
429
- field_info.annotation = type_annotation
445
+ if isinstance(field_info, FieldInfo):
446
+ field_info.annotation = type_annotation
430
447
 
431
448
  # Get Depends from type annotation
432
449
  if depends is not None and depends.dependency is None:
@@ -463,7 +480,14 @@ def analyze_param(
463
480
  ) or is_uploadfile_sequence_annotation(type_annotation):
464
481
  field_info = params.File(annotation=use_annotation, default=default_value)
465
482
  elif not field_annotation_is_scalar(annotation=type_annotation):
466
- field_info = params.Body(annotation=use_annotation, default=default_value)
483
+ if annotation_is_pydantic_v1(use_annotation):
484
+ field_info = temp_pydantic_v1_params.Body(
485
+ annotation=use_annotation, default=default_value
486
+ )
487
+ else:
488
+ field_info = params.Body(
489
+ annotation=use_annotation, default=default_value
490
+ )
467
491
  else:
468
492
  field_info = params.Query(annotation=use_annotation, default=default_value)
469
493
 
@@ -472,12 +496,14 @@ def analyze_param(
472
496
  if field_info is not None:
473
497
  # Handle field_info.in_
474
498
  if is_path_param:
475
- assert isinstance(field_info, params.Path), (
499
+ assert isinstance(
500
+ field_info, (params.Path, temp_pydantic_v1_params.Path)
501
+ ), (
476
502
  f"Cannot use `{field_info.__class__.__name__}` for path param"
477
503
  f" {param_name!r}"
478
504
  )
479
505
  elif (
480
- isinstance(field_info, params.Param)
506
+ isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param))
481
507
  and getattr(field_info, "in_", None) is None
482
508
  ):
483
509
  field_info.in_ = params.ParamTypes.query
@@ -486,7 +512,7 @@ def analyze_param(
486
512
  field_info,
487
513
  param_name,
488
514
  )
489
- if isinstance(field_info, params.Form):
515
+ if isinstance(field_info, (params.Form, temp_pydantic_v1_params.Form)):
490
516
  ensure_multipart_is_installed()
491
517
  if not field_info.alias and getattr(field_info, "convert_underscores", None):
492
518
  alias = param_name.replace("_", "-")
@@ -498,19 +524,20 @@ def analyze_param(
498
524
  type_=use_annotation_from_field_info,
499
525
  default=field_info.default,
500
526
  alias=alias,
501
- required=field_info.default in (RequiredParam, Undefined),
527
+ required=field_info.default
528
+ in (RequiredParam, may_v1.RequiredParam, Undefined),
502
529
  field_info=field_info,
503
530
  )
504
531
  if is_path_param:
505
532
  assert is_scalar_field(field=field), (
506
533
  "Path params must be of one of the supported types"
507
534
  )
508
- elif isinstance(field_info, params.Query):
535
+ elif isinstance(field_info, (params.Query, temp_pydantic_v1_params.Query)):
509
536
  assert (
510
537
  is_scalar_field(field)
511
538
  or is_scalar_sequence_field(field)
512
539
  or (
513
- lenient_issubclass(field.type_, BaseModel)
540
+ _is_model_class(field.type_)
514
541
  # For Pydantic v1
515
542
  and getattr(field, "shape", 1) == 1
516
543
  )
@@ -712,10 +739,10 @@ def _validate_value_with_model_field(
712
739
  else:
713
740
  return deepcopy(field.default), []
714
741
  v_, errors_ = field.validate(value, values, loc=loc)
715
- if isinstance(errors_, ErrorWrapper):
742
+ if _is_error_wrapper(errors_): # type: ignore[arg-type]
716
743
  return None, [errors_]
717
744
  elif isinstance(errors_, list):
718
- new_errors = _regenerate_error_with_loc(errors=errors_, loc_prefix=())
745
+ new_errors = may_v1._regenerate_error_with_loc(errors=errors_, loc_prefix=())
719
746
  return None, new_errors
720
747
  else:
721
748
  return v_, []
@@ -732,7 +759,7 @@ def _get_multidict_value(
732
759
  if (
733
760
  value is None
734
761
  or (
735
- isinstance(field.field_info, params.Form)
762
+ isinstance(field.field_info, (params.Form, temp_pydantic_v1_params.Form))
736
763
  and isinstance(value, str) # For type checks
737
764
  and value == ""
738
765
  )
@@ -798,7 +825,7 @@ def request_params_to_args(
798
825
 
799
826
  if single_not_embedded_field:
800
827
  field_info = first_field.field_info
801
- assert isinstance(field_info, params.Param), (
828
+ assert isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param)), (
802
829
  "Params must be subclasses of Param"
803
830
  )
804
831
  loc: Tuple[str, ...] = (field_info.in_.value,)
@@ -810,7 +837,7 @@ def request_params_to_args(
810
837
  for field in fields:
811
838
  value = _get_multidict_value(field, received_params)
812
839
  field_info = field.field_info
813
- assert isinstance(field_info, params.Param), (
840
+ assert isinstance(field_info, (params.Param, temp_pydantic_v1_params.Param)), (
814
841
  "Params must be subclasses of Param"
815
842
  )
816
843
  loc = (field_info.in_.value, field.alias)
@@ -837,7 +864,7 @@ def is_union_of_base_models(field_type: Any) -> bool:
837
864
  union_args = get_args(field_type)
838
865
 
839
866
  for arg in union_args:
840
- if not lenient_issubclass(arg, BaseModel):
867
+ if not _is_model_class(arg):
841
868
  return False
842
869
 
843
870
  return True
@@ -859,8 +886,8 @@ def _should_embed_body_fields(fields: List[ModelField]) -> bool:
859
886
  # If it's a Form (or File) field, it has to be a BaseModel (or a union of BaseModels) to be top level
860
887
  # otherwise it has to be embedded, so that the key value pair can be extracted
861
888
  if (
862
- isinstance(first_field.field_info, params.Form)
863
- and not lenient_issubclass(first_field.type_, BaseModel)
889
+ isinstance(first_field.field_info, (params.Form, temp_pydantic_v1_params.Form))
890
+ and not _is_model_class(first_field.type_)
864
891
  and not is_union_of_base_models(first_field.type_)
865
892
  ):
866
893
  return True
@@ -877,14 +904,14 @@ async def _extract_form_body(
877
904
  value = _get_multidict_value(field, received_body)
878
905
  field_info = field.field_info
879
906
  if (
880
- isinstance(field_info, params.File)
907
+ isinstance(field_info, (params.File, temp_pydantic_v1_params.File))
881
908
  and is_bytes_field(field)
882
909
  and isinstance(value, UploadFile)
883
910
  ):
884
911
  value = await value.read()
885
912
  elif (
886
913
  is_bytes_sequence_field(field)
887
- and isinstance(field_info, params.File)
914
+ and isinstance(field_info, (params.File, temp_pydantic_v1_params.File))
888
915
  and value_is_sequence(value)
889
916
  ):
890
917
  # For types
@@ -925,7 +952,7 @@ async def request_body_to_args(
925
952
 
926
953
  if (
927
954
  single_not_embedded_field
928
- and lenient_issubclass(first_field.type_, BaseModel)
955
+ and _is_model_class(first_field.type_)
929
956
  and isinstance(received_body, FormData)
930
957
  ):
931
958
  fields_to_extract = get_cached_model_fields(first_field.type_)
@@ -990,15 +1017,28 @@ def get_body_field(
990
1017
  BodyFieldInfo_kwargs["default"] = None
991
1018
  if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
992
1019
  BodyFieldInfo: Type[params.Body] = params.File
1020
+ elif any(
1021
+ isinstance(f.field_info, temp_pydantic_v1_params.File)
1022
+ for f in flat_dependant.body_params
1023
+ ):
1024
+ BodyFieldInfo: Type[temp_pydantic_v1_params.Body] = temp_pydantic_v1_params.File # type: ignore[no-redef]
993
1025
  elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
994
1026
  BodyFieldInfo = params.Form
1027
+ elif any(
1028
+ isinstance(f.field_info, temp_pydantic_v1_params.Form)
1029
+ for f in flat_dependant.body_params
1030
+ ):
1031
+ BodyFieldInfo = temp_pydantic_v1_params.Form # type: ignore[assignment]
995
1032
  else:
996
- BodyFieldInfo = params.Body
1033
+ if annotation_is_pydantic_v1(BodyModel):
1034
+ BodyFieldInfo = temp_pydantic_v1_params.Body # type: ignore[assignment]
1035
+ else:
1036
+ BodyFieldInfo = params.Body
997
1037
 
998
1038
  body_param_media_types = [
999
1039
  f.field_info.media_type
1000
1040
  for f in flat_dependant.body_params
1001
- if isinstance(f.field_info, params.Body)
1041
+ if isinstance(f.field_info, (params.Body, temp_pydantic_v1_params.Body))
1002
1042
  ]
1003
1043
  if len(set(body_param_media_types)) == 1:
1004
1044
  BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0]
fastapi/encoders.py CHANGED
@@ -17,6 +17,7 @@ from types import GeneratorType
17
17
  from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
18
18
  from uuid import UUID
19
19
 
20
+ from fastapi._compat import may_v1
20
21
  from fastapi.types import IncEx
21
22
  from pydantic import BaseModel
22
23
  from pydantic.color import Color
@@ -24,7 +25,7 @@ from pydantic.networks import AnyUrl, NameEmail
24
25
  from pydantic.types import SecretBytes, SecretStr
25
26
  from typing_extensions import Annotated, Doc
26
27
 
27
- from ._compat import PYDANTIC_V2, UndefinedType, Url, _model_dump
28
+ from ._compat import Url, _is_undefined, _model_dump
28
29
 
29
30
 
30
31
  # Taken from Pydantic v1 as is
@@ -58,6 +59,7 @@ def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
58
59
  ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
59
60
  bytes: lambda o: o.decode(),
60
61
  Color: str,
62
+ may_v1.Color: str,
61
63
  datetime.date: isoformat,
62
64
  datetime.datetime: isoformat,
63
65
  datetime.time: isoformat,
@@ -74,14 +76,19 @@ ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
74
76
  IPv6Interface: str,
75
77
  IPv6Network: str,
76
78
  NameEmail: str,
79
+ may_v1.NameEmail: str,
77
80
  Path: str,
78
81
  Pattern: lambda o: o.pattern,
79
82
  SecretBytes: str,
83
+ may_v1.SecretBytes: str,
80
84
  SecretStr: str,
85
+ may_v1.SecretStr: str,
81
86
  set: list,
82
87
  UUID: str,
83
88
  Url: str,
89
+ may_v1.Url: str,
84
90
  AnyUrl: str,
91
+ may_v1.AnyUrl: str,
85
92
  }
86
93
 
87
94
 
@@ -213,10 +220,10 @@ def jsonable_encoder(
213
220
  include = set(include)
214
221
  if exclude is not None and not isinstance(exclude, (set, dict)):
215
222
  exclude = set(exclude)
216
- if isinstance(obj, BaseModel):
223
+ if isinstance(obj, (BaseModel, may_v1.BaseModel)):
217
224
  # TODO: remove when deprecating Pydantic v1
218
225
  encoders: Dict[Any, Any] = {}
219
- if not PYDANTIC_V2:
226
+ if isinstance(obj, may_v1.BaseModel):
220
227
  encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
221
228
  if custom_encoder:
222
229
  encoders = {**encoders, **custom_encoder}
@@ -260,7 +267,7 @@ def jsonable_encoder(
260
267
  return str(obj)
261
268
  if isinstance(obj, (str, int, float, type(None))):
262
269
  return obj
263
- if isinstance(obj, UndefinedType):
270
+ if _is_undefined(obj):
264
271
  return None
265
272
  if isinstance(obj, dict):
266
273
  encoded_dict = {}
fastapi/openapi/utils.py CHANGED
@@ -5,7 +5,6 @@ from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union,
5
5
 
6
6
  from fastapi import routing
7
7
  from fastapi._compat import (
8
- GenerateJsonSchema,
9
8
  JsonSchemaValue,
10
9
  ModelField,
11
10
  Undefined,
@@ -22,7 +21,7 @@ from fastapi.dependencies.utils import (
22
21
  get_flat_params,
23
22
  )
24
23
  from fastapi.encoders import jsonable_encoder
25
- from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
24
+ from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX
26
25
  from fastapi.openapi.models import OpenAPI
27
26
  from fastapi.params import Body, ParamTypes
28
27
  from fastapi.responses import Response
@@ -37,6 +36,8 @@ from starlette.responses import JSONResponse
37
36
  from starlette.routing import BaseRoute
38
37
  from typing_extensions import Literal
39
38
 
39
+ from .._compat import _is_model_field
40
+
40
41
  validation_error_definition = {
41
42
  "title": "ValidationError",
42
43
  "type": "object",
@@ -94,7 +95,6 @@ def get_openapi_security_definitions(
94
95
  def _get_openapi_operation_parameters(
95
96
  *,
96
97
  dependant: Dependant,
97
- schema_generator: GenerateJsonSchema,
98
98
  model_name_map: ModelNameMap,
99
99
  field_mapping: Dict[
100
100
  Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
@@ -128,7 +128,6 @@ def _get_openapi_operation_parameters(
128
128
  continue
129
129
  param_schema = get_schema_from_model_field(
130
130
  field=param,
131
- schema_generator=schema_generator,
132
131
  model_name_map=model_name_map,
133
132
  field_mapping=field_mapping,
134
133
  separate_input_output_schemas=separate_input_output_schemas,
@@ -169,7 +168,6 @@ def _get_openapi_operation_parameters(
169
168
  def get_openapi_operation_request_body(
170
169
  *,
171
170
  body_field: Optional[ModelField],
172
- schema_generator: GenerateJsonSchema,
173
171
  model_name_map: ModelNameMap,
174
172
  field_mapping: Dict[
175
173
  Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
@@ -178,10 +176,9 @@ def get_openapi_operation_request_body(
178
176
  ) -> Optional[Dict[str, Any]]:
179
177
  if not body_field:
180
178
  return None
181
- assert isinstance(body_field, ModelField)
179
+ assert _is_model_field(body_field)
182
180
  body_schema = get_schema_from_model_field(
183
181
  field=body_field,
184
- schema_generator=schema_generator,
185
182
  model_name_map=model_name_map,
186
183
  field_mapping=field_mapping,
187
184
  separate_input_output_schemas=separate_input_output_schemas,
@@ -254,7 +251,6 @@ def get_openapi_path(
254
251
  *,
255
252
  route: routing.APIRoute,
256
253
  operation_ids: Set[str],
257
- schema_generator: GenerateJsonSchema,
258
254
  model_name_map: ModelNameMap,
259
255
  field_mapping: Dict[
260
256
  Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
@@ -287,7 +283,6 @@ def get_openapi_path(
287
283
  security_schemes.update(security_definitions)
288
284
  operation_parameters = _get_openapi_operation_parameters(
289
285
  dependant=route.dependant,
290
- schema_generator=schema_generator,
291
286
  model_name_map=model_name_map,
292
287
  field_mapping=field_mapping,
293
288
  separate_input_output_schemas=separate_input_output_schemas,
@@ -309,7 +304,6 @@ def get_openapi_path(
309
304
  if method in METHODS_WITH_BODY:
310
305
  request_body_oai = get_openapi_operation_request_body(
311
306
  body_field=route.body_field,
312
- schema_generator=schema_generator,
313
307
  model_name_map=model_name_map,
314
308
  field_mapping=field_mapping,
315
309
  separate_input_output_schemas=separate_input_output_schemas,
@@ -327,7 +321,6 @@ def get_openapi_path(
327
321
  ) = get_openapi_path(
328
322
  route=callback,
329
323
  operation_ids=operation_ids,
330
- schema_generator=schema_generator,
331
324
  model_name_map=model_name_map,
332
325
  field_mapping=field_mapping,
333
326
  separate_input_output_schemas=separate_input_output_schemas,
@@ -358,7 +351,6 @@ def get_openapi_path(
358
351
  if route.response_field:
359
352
  response_schema = get_schema_from_model_field(
360
353
  field=route.response_field,
361
- schema_generator=schema_generator,
362
354
  model_name_map=model_name_map,
363
355
  field_mapping=field_mapping,
364
356
  separate_input_output_schemas=separate_input_output_schemas,
@@ -392,7 +384,6 @@ def get_openapi_path(
392
384
  if field:
393
385
  additional_field_schema = get_schema_from_model_field(
394
386
  field=field,
395
- schema_generator=schema_generator,
396
387
  model_name_map=model_name_map,
397
388
  field_mapping=field_mapping,
398
389
  separate_input_output_schemas=separate_input_output_schemas,
@@ -454,7 +445,7 @@ def get_fields_from_routes(
454
445
  route, routing.APIRoute
455
446
  ):
456
447
  if route.body_field:
457
- assert isinstance(route.body_field, ModelField), (
448
+ assert _is_model_field(route.body_field), (
458
449
  "A request body must be a Pydantic Field"
459
450
  )
460
451
  body_fields_from_routes.append(route.body_field)
@@ -510,10 +501,8 @@ def get_openapi(
510
501
  operation_ids: Set[str] = set()
511
502
  all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
512
503
  model_name_map = get_compat_model_name_map(all_fields)
513
- schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE)
514
504
  field_mapping, definitions = get_definitions(
515
505
  fields=all_fields,
516
- schema_generator=schema_generator,
517
506
  model_name_map=model_name_map,
518
507
  separate_input_output_schemas=separate_input_output_schemas,
519
508
  )
@@ -522,7 +511,6 @@ def get_openapi(
522
511
  result = get_openapi_path(
523
512
  route=route,
524
513
  operation_ids=operation_ids,
525
- schema_generator=schema_generator,
526
514
  model_name_map=model_name_map,
527
515
  field_mapping=field_mapping,
528
516
  separate_input_output_schemas=separate_input_output_schemas,
@@ -542,7 +530,6 @@ def get_openapi(
542
530
  result = get_openapi_path(
543
531
  route=webhook,
544
532
  operation_ids=operation_ids,
545
- schema_generator=schema_generator,
546
533
  model_name_map=model_name_map,
547
534
  field_mapping=field_mapping,
548
535
  separate_input_output_schemas=separate_input_output_schemas,
fastapi/routing.py CHANGED
@@ -24,7 +24,7 @@ from typing import (
24
24
  Union,
25
25
  )
26
26
 
27
- from fastapi import params
27
+ from fastapi import params, temp_pydantic_v1_params
28
28
  from fastapi._compat import (
29
29
  ModelField,
30
30
  Undefined,
@@ -307,7 +307,9 @@ def get_request_handler(
307
307
  ) -> Callable[[Request], Coroutine[Any, Any, Response]]:
308
308
  assert dependant.call is not None, "dependant.call must be a function"
309
309
  is_coroutine = iscoroutinefunction(dependant.call)
310
- is_body_form = body_field and isinstance(body_field.field_info, params.Form)
310
+ is_body_form = body_field and isinstance(
311
+ body_field.field_info, (params.Form, temp_pydantic_v1_params.Form)
312
+ )
311
313
  if isinstance(response_class, DefaultPlaceholder):
312
314
  actual_response_class: Type[Response] = response_class.value
313
315
  else: