Idriss Bellil
07/31/2025, 6:18 PMsource_fetch: SourceFetchSpec | str,
Marvin
07/31/2025, 6:18 PMMarvin
07/31/2025, 6:19 PMsource_fetch: SourceFetchSpec | str
. This is because:
1. Prefect uses Pydantic internally for parameter validation, which has robust support for Union types
2. When you pass either a string or a Pydantic object through a deployment, Pydantic will:
- Accept the string if it's a valid string
- Accept and validate the Pydantic object if one is provided
- Raise a validation error if the provided value doesn't match either type
Here's a practical example to illustrate:
python
from prefect import flow
from pydantic import BaseModel
class SourceFetchSpec(BaseModel):
url: str
branch: str = "main"
@flow
def my_flow(source_fetch: SourceFetchSpec | str):
if isinstance(source_fetch, str):
print(f"Got string: {source_fetch}")
else:
print(f"Got SourceFetchSpec: {source_fetch.url}, {source_fetch.branch}")
# These will both work:
my_flow("<https://github.com/org/repo>")
my_flow(SourceFetchSpec(url="<https://github.com/org/repo>"))
When creating a deployment, you can specify either type in your parameters, and Prefect will handle the validation appropriately:
python
flow.from_source(...).deploy(
name="str-param",
parameters={"source_fetch": "<https://github.com/org/repo>"}
)
# Or with a Pydantic model (will be serialized/deserialized automatically)
flow.from_source(...).deploy(
name="pydantic-param",
parameters={"source_fetch": {"url": "<https://github.com/org/repo>", "branch": "main"}}
)
The only thing to keep in mind is that when passing a Pydantic model through a deployment, it should be provided as a dictionary that matches the model's structure, as shown in the second deployment example above. Prefect will automatically handle the conversion between the dictionary and your Pydantic model.