<@ULVA73B9P> I want to use a pydantic base model t...
# ask-marvin
t
@Marvin I want to use a pydantic base model to constrain my flow inputs. However, when writing the following:
Copy code
class MyParamsModel(BaseModel)
   foo: str
   bar: int

@flow
def my_flow(params: MyParamsModel):
   ...
Then, when running the flow with
my_flow(foo="foo", bar=42)
, then I receive an error saying the input is missing a required argument "params". Can you confirm the only way to do this is to restructure my input and feed the flow the following:
{"params": {"foo": "foo", "bar": 42}}
?
m
thought for 184.8 seconds
Short answer: you’re seeing normal Python behavior. With this signature:
Copy code
from pydantic import BaseModel
from prefect import flow

class MyParamsModel(BaseModel):
    foo: str
    bar: int

@flow
def my_flow(params: MyParamsModel):
    ...
Python expects a single argument named
params
. Prefect does not auto-unpack Pydantic model fields into top-level kwargs. That’s why
my_flow(foo="foo", bar=42)
errors. Your options: - Keep the single model parameter - Calling in Python:
Copy code
my_flow(params=MyParamsModel(foo="foo", bar=42))
    # or let Prefect/Pydantic construct it from a dict
    my_flow(params={"foo": "foo", "bar": 42})
- From a deployment/UI/API: pass a nested parameters dict:
Copy code
{
  "params": {
    "foo": "foo",
    "bar": 42
  }
}
- Expose individual parameters if you want top-level kwargs
Copy code
@flow
  def my_flow(foo: str, bar: int):
      params = MyParamsModel(foo=foo, bar=bar)
      ...
So, yes: with your current signature, you must provide a single
params
argument (either a
MyParamsModel
instance or a dict). If you prefer
my_flow(foo=..., bar=...)
, change the flow signature to take those fields directly. Refs: - Flows in Prefect 3 - Deployment parameters via prefect.yaml
1