@@ -436,40 +436,93 @@ def render_redoc_ui(openapi_json_url: str) -> str:
436436 </html>
437437 """
438438
439+ @staticmethod
440+ def _resolve_pydantic_model (model_class , params , param_name ):
441+ """Resolving parameters for a Pydantic model"""
442+ try :
443+ params_copy = params .copy ()
444+
445+ if hasattr (model_class , "model_fields" ):
446+ for field_name , field_info in model_class .model_fields .items ():
447+ if (
448+ field_name in params_copy
449+ and not isinstance (params_copy [field_name ], list )
450+ and hasattr (field_info , "annotation" )
451+ and typing .get_origin (field_info .annotation ) is list
452+ ):
453+ params_copy [field_name ] = [params_copy [field_name ]]
454+
455+ return model_class (** params_copy )
456+ except Exception as e :
457+ raise ValidationError (
458+ f"Validation error for parameter '{ param_name } '" , str (e )
459+ )
460+
461+ @staticmethod
462+ def _resolve_list_param (param_name , value , annotation ):
463+ """Resolving a list-type parameter"""
464+ args = typing .get_args (annotation )
465+ try :
466+ if args :
467+ return [args [0 ](value )]
468+ else :
469+ return [value ]
470+ except Exception as e :
471+ type_name = args [0 ].__name__ if args else "value"
472+ raise BadRequestError (
473+ f"Error parsing parameter '{ param_name } ' as list item. "
474+ f"Must be a valid { type_name } " ,
475+ str (e ),
476+ )
477+
478+ @staticmethod
479+ def _resolve_scalar_param (param_name , value , annotation ):
480+ """Resolving a scalar parameter"""
481+ try :
482+ return annotation (value )
483+ except Exception as e :
484+ type_name = getattr (annotation , "__name__" , str (annotation ))
485+ raise BadRequestError (
486+ f"Error parsing parameter '{ param_name } '. "
487+ f"Must be a valid { type_name } " ,
488+ str (e ),
489+ )
490+
439491 @staticmethod
440492 def resolve_endpoint_params (
441493 endpoint : Callable , all_params : dict , body : dict
442494 ) -> dict :
495+ """Main method for resolving endpoint parameters"""
443496 sig = inspect .signature (endpoint )
444497 kwargs = {}
498+
445499 for name , param in sig .parameters .items ():
446500 annotation = param .annotation
447501 is_required = param .default is inspect .Parameter .empty
502+
448503 if isinstance (annotation , type ) and issubclass (annotation , BaseModel ):
449- try :
450- params = body if body else all_params
451- kwargs [name ] = annotation (** params )
452- except Exception as e :
453- # Use 422 for Pydantic model validation errors
454- raise ValidationError (
455- f"Validation error for parameter '{ name } '" , str (e )
456- )
457- else :
458- if name in all_params :
459- try :
460- kwargs [name ] = annotation (all_params [name ])
461- except Exception as e :
462- # Use 400 for type conversion errors
463- raise BadRequestError (
464- f"Error parsing parameter '{ name } '. "
465- f"Must be a valid { annotation .__name__ } " ,
466- str (e ),
467- )
468- elif not is_required :
469- kwargs [name ] = param .default
470- else :
471- # Missing a required parameter is 400
504+ kwargs [name ] = BaseRouter ._resolve_pydantic_model (
505+ annotation , body if body else all_params , name
506+ )
507+ continue
508+
509+ if name not in all_params :
510+ if is_required :
472511 raise BadRequestError (f"Missing required parameter: '{ name } '" )
512+ kwargs [name ] = param .default
513+ continue
514+
515+ origin = typing .get_origin (annotation )
516+
517+ if origin is list and not isinstance (all_params [name ], list ):
518+ kwargs [name ] = BaseRouter ._resolve_list_param (
519+ name , all_params [name ], annotation
520+ )
521+ else :
522+ kwargs [name ] = BaseRouter ._resolve_scalar_param (
523+ name , all_params [name ], annotation
524+ )
525+
473526 return kwargs
474527
475528 @property
0 commit comments