<@ULVA73B9P> if I have a flow that optionally take...
# ask-marvin
m
@Marvin if I have a flow that optionally takes a parameter, like this:
Copy code
@flow(
    log_prints=True,
    flow_run_name=ws.generate_flow_run_name,
    retries=ws.RETRIES,
    retry_delay_seconds=ws.RETRY_DELAY,
)
def example_sync(sftp_load=True) -> None:
    if sftp_load:
        load_sftp_data()
    else:
        load_file_system_data()
And we create a deployment like this:
Copy code
from src.workflow import example_sync

def deploy():
    docker_image = DockerImage(
        name=ds.DOCKER_IMAGE_NAME,
        tag=ds.DOCKER_IMAGE_TAG,
        dockerfile=str(Path(__file__).parent / "Dockerfile"),
        platform="linux/amd64",
    )
    git_repo = GitRepository(
        url=ds.GIT_REPOSITORY,
        credentials={"access_token": token_block},
        branch=ds.GIT_BRANCH,
    )
    example_sync.from_source(
        source=git_repo,
        entrypoint="src/workflow.py:example_sync",
    ).deploy(
        name="example_sync",
        work_pool_name=ds.WORK_POOL_NAME,
        schedules=[Cron(ds.CRON_SCHEDULE, timezone=ds.CRON_TIMEZONE, day_or=True)],
        image=docker_image,
        push=False,
        build=True,
    )
We don't see the parameter listed as changeable in the "custom run" form in Prefect Cloud. We have an on-premises Prefect instance running on Prefect 2.x, and I think we had automatic parameter forms on that one. Is there something I need to do on 3.x + Prefect Cloud to get that same behaviour? or some change I need to make to the deloyment code to automatically find + include parameters in a "parameters=" definition?
m
thought for 651.1 seconds
n
id guess this has something to do with
sftp_load
being untyped
Copy code
#[1]
from prefect import flow

#[2]
@flow
def foo(flag=True):
    ...


#[3]
foo.parameters
Out[3]: ParameterSchema(title='Parameters', type='object', properties={'flag': {'default': True, 'position': 0, 'title': 'flag'}}, required=[], definitions={})

#[4]
@flow
def foo(flag:bool=True):
    ...


#[5]
foo.parameters
Out[5]: ParameterSchema(title='Parameters', type='object', properties={'flag': {'default': True, 'position': 0, 'title': 'flag', 'type': 'boolean'}}, required=[], definitions={})
what if you try
Copy code
@flow(
    log_prints=True,
    flow_run_name=ws.generate_flow_run_name,
    retries=ws.RETRIES,
    retry_delay_seconds=ws.RETRY_DELAY,
)
def example_sync(sftp_load: bool = True) -> None:
    if sftp_load:
        load_sftp_data()
    else:
        load_file_system_data()
there might be a pydantic 1 -> 2 behavior change here (prefect 2.x was on pydantic 1 and 3.x is on pydantic 2)
m
Short answer: In Prefect 3.x Cloud, the “Custom run” form is built from the deployment’s parameter schema, which is inferred from your flow function signature. You don’t need to pass
parameters=
to make it show up; they should be discovered automatically. If you don’t see them, it usually means the deployment’s saved schema is empty/stale or inference failed during deploy. What to check and try: - Add a type hint to your parameter (helps the schema and UI render the right control), then re-deploy:
Copy code
@flow(
    log_prints=True,
    flow_run_name=ws.generate_flow_run_name,
    retries=ws.RETRIES,
    retry_delay_seconds=ws.RETRY_DELAY,
)
def example_sync(sftp_load: bool = True) -> None:
    if sftp_load:
        load_sftp_data()
    else:
        load_file_system_data()
- Re-deploy to refresh the schema. The deployment’s parameter schema is versioned; if the deployment was created before
sftp_load
existed (or before type hints), the UI will not show it until you deploy again. - Ensure the deploy environment can import your entrypoint. When you use
.from_source(...)
, Prefect generates the schema by loading the entrypoint. If
src/workflow.py
isn’t importable at deploy time, schema generation can fail and the UI will show no parameters. Running the deploy from your project root (where
src
is importable) generally resolves this. - Optionally seed defaults at deploy-time (not required, but guarantees the field shows):
Copy code
example_sync.from_source(
    source=git_repo,
    entrypoint="src/workflow.py:example_sync",
).deploy(
    name="example_sync",
    work_pool_name=ds.WORK_POOL_NAME,
    schedules=[Cron(ds.CRON_SCHEDULE, timezone=ds.CRON_TIMEZONE, day_or=True)],
    image=docker_image,
    push=False,
    build=True,
    parameters={"sftp_load": True},  # default for the deployment
)
- Verify
enforce_parameter_schema=True
is left as default on
deploy(...)
. This keeps the schema attached to the deployment. - Inspect the deployment detail in the UI and check whether
parameter_openapi_schema
is present. If it’s empty, inference failed or the deployment is stale. Notes vs Prefect 2.x: - The auto form behavior still exists in 3.x Cloud, but the schema is stored on the deployment. Re-deploy whenever parameters change to update the schema. - You don’t need to use GitHub storage blocks in 3.x; your use of
.from_source('https://...')
is correct. If this still doesn’t show the parameter: - What Prefect version are you using in the environment where you run the deploy script? - Can you confirm if
parameter_openapi_schema
is empty for this deployment in the UI? - Are you running the deploy script from a working directory where
src/workflow.py
is importable? References: - Deploy via Python (Prefect 3): Prefect docs - Flow.deploy signature (shows
parameters
and
enforce_parameter_schema
): https://github.com/PrefectHQ/prefect/blob/main/src/prefect/flows.py#L - Parameter schema utility used for inference: https://github.com/PrefectHQ/prefect/blob/main/src/prefect/utilities/callables.py#L
m
@Nate that did it. Adding a type definition makes it show up in the UI. Thanks!
n
catjam
if you're interested you can learn more about form-building here: https://docs.prefect.io/v3/advanced/form-building#configure-ui-forms-for-validating-workflow-inputs
👍 1