Skip to content

Flows and parameters

from datetime import date
from cereyan import flow

@flow(run_name="etl-{day}", tags=["example"])
def etl(day: date, full: bool = False) -> str:
    return f"{day} full={full}"

assert etl(day="2026-01-02", full="yes") == "2026-01-02 full=True"

A flow is a decorated function. Calling it starts a run: the tasks it calls are recorded as task runs, its logs are stored, and it ends in a terminal state. Offline the run is recorded in the local store. While a server holds the store, the call hands the run to the server and streams the logs back. A flow's identity is (project, name); see App and projects.

Parameters come from type hints

Values arrive from the decorator call, the CLI (--param day=2026-01-02), the API and the UI run form (JSON), a schedule's defaults, or a backfill. Whatever the source, they are coerced to the declared types before the body runs, and a value that does not coerce raises ParameterError (exit code 3 on the CLI, 422 on the API) before anything is recorded as started.

Hint Accepted values
str, int, float The type, or a string that parses
bool true, 1, yes, on, y, t and their negatives, case-insensitive
date, datetime ISO 8601 strings
timedelta Seconds, MM:SS, or HH:MM:SS
Optional[T], T | None null or None, else coerced as T
list[T], dict[str, T] JSON on the CLI; elements coerced as T
Literal[...] One of the listed values
Enum The member's value, or its name
dataclasses A JSON object; fields coerced by their hints

Any other hint is opaque: the value passes through unchanged and the schema describes it as untyped. The schema derived from the hints drives the UI's run form and is exposed by the API as parameter_schema.

Naming runs

Runs get a random adjective-animal name unless the flow sets run_name: a str.format template over the parameters, or a callable receiving them as keyword arguments. Names need not be unique.

What a flow can declare

Concern Options Where
When it runs schedule, schedules Schedules
Reliability retries, retry_delay, timeout_seconds, crash_retries Retry, time out and survive crashes
Hooks on_completion, on_failure, on_crashed, on_cancellation Run code on state changes
Concurrency max_concurrent, on_overlap, resources, priority, disable_after Resources and concurrency
Dependencies after, batch_key Dependencies
Backfills bulk_complete Backfills
Execution runner, isolated, log_prints Tasks, Engines and the home directory
Display name, description, tags, group App and projects

The full option list with types and defaults is in the Python API reference.

The flow object

@flow returns a Flow, not the function. It is still callable, and it exposes what was derived: parameters, schema, project, name, tags, and options. Use it in tests to call the flow directly or to read its schema.