...I am so confused. I have a Deployment that sudd...
# ask-community
j
...I am so confused. I have a Deployment that suddenly stopped working. The problem is that the function is receiving arguments in the wrong order, apparently. The thing is, nobody edited that deployment, the YAML spec lists params in the correct order, and even if I try to submit the run args as JSON with the ordering manually fixed up... at runtime, the passed arguments are still out of order in the same way. The Custom parameters form doesn't help it either. Stranger yet, I don't see any reason why the ordering changed. It seems to be an arbitrary ordering, not alphanumeric or anything. And for that matter... why are arguments seemingly passed to functions positionally rather than as kwargs???
n
hi @Jan Malek - sorry to hear you're having trouble. can you show the signature of the flow that you're encountering this with? also, the version of prefect that your deployment is trying to use would be helpful
j
Copy code
@flow_if_api_reachable(name="RAW|QuoteDB|run_job", on_failure=[notify_failure_slack])
@sync_compatible
async def run_job(
    config_name: Optional[str],
    table_type: Optional[str] = None,
    use_dask: bool = True,
    db_username_secret_block_key: Optional[str] = None,
    db_password_secret_block_key: Optional[str] = None,
)
Prefect Version:
2.13.4
n
hmm, would you mind sharing the implementation
flow_if_api_reachable
? i dont see anything weird yet
j
Copy code
def flow_if_api_reachable(*flow_args, **flow_kwargs):
    """Applies a @prefect.flow() decorator with specified args if and only if
    the Prefect API specified by the envvars/config is reachable. Otherwise,
    the underlying function is unmodified.

    args/kwargs are passed to the flow decorator as-is, except for:
    flow_run_name which is defaulted to a standardized generator (but is overrideable)
    timeout_seconds which defaults to 24 hrs to avoid runaway tasks (also overrideable)
    """
    fixed_kwargs = flow_kwargs.copy()

    flowrun_name_gen = flow_kwargs.get("flow_run_name") or generate_flow_name
    fixed_kwargs["flow_run_name"] = flowrun_name_gen

    # Default timeout to 24hrs by default if not set - if None, works the same as base flow()
    timeout_seconds = flow_kwargs.get("timeout_seconds", NotImplemented)  # None is valid and shouldn't be erased
    fixed_kwargs["timeout_seconds"] = (3600 * 24) if timeout_seconds is NotImplemented else timeout_seconds

    flow_decorator = flow(*flow_args, **fixed_kwargs)

    decowrapper = decorate_if(prefect_api_url_reachable, flow_decorator)
    return decowrapper
TL;DR it just wraps
flow()
with a preflight check that pings the API and sees if it's available; if not, skips the decoration
this is a utility we're mainly using to assist with migrating legacy code - so that it continues to run on its normal (Cron) schedule even if the Prefect API is down/unreachable
n
makes sense to me. i don’t yet see anything that would cause args to get jumbled, i’ll have to experiment more later with that