Converts validated data from the Pydantic model into (args, kwargs), suitable for calling the original function.
(self, data: BaseModel)
| 42 | as it increases the likelihood of correct JSON input.""" |
| 43 | |
| 44 | def to_call_args(self, data: BaseModel) -> tuple[list[Any], dict[str, Any]]: |
| 45 | """ |
| 46 | Converts validated data from the Pydantic model into (args, kwargs), suitable for calling |
| 47 | the original function. |
| 48 | """ |
| 49 | positional_args: list[Any] = [] |
| 50 | keyword_args: dict[str, Any] = {} |
| 51 | seen_var_positional = False |
| 52 | |
| 53 | # Use enumerate() so we can skip the first parameter if it's context. |
| 54 | for idx, (name, param) in enumerate(self.signature.parameters.items()): |
| 55 | # If the function takes a RunContextWrapper and this is the first parameter, skip it. |
| 56 | if self.takes_context and idx == 0: |
| 57 | continue |
| 58 | |
| 59 | value = getattr(data, name, None) |
| 60 | if param.kind == param.VAR_POSITIONAL: |
| 61 | # e.g. *args: extend positional args and mark that *args is now seen |
| 62 | positional_args.extend(value or []) |
| 63 | seen_var_positional = True |
| 64 | elif param.kind == param.VAR_KEYWORD: |
| 65 | # e.g. **kwargs handling |
| 66 | keyword_args.update(value or {}) |
| 67 | elif param.kind in (param.POSITIONAL_ONLY, param.POSITIONAL_OR_KEYWORD): |
| 68 | # Before *args, add to positional args. After *args, add to keyword args. |
| 69 | if not seen_var_positional: |
| 70 | positional_args.append(value) |
| 71 | else: |
| 72 | keyword_args[name] = value |
| 73 | else: |
| 74 | # For KEYWORD_ONLY parameters, always use keyword args. |
| 75 | keyword_args[name] = value |
| 76 | return positional_args, keyword_args |
| 77 | |
| 78 | |
| 79 | @dataclass |