C.W.K.
Stream
Lesson 04 of 05 · published

Prefect — The Pythonic Alternative

~11 min · prefect, flows, orchestration

Level 0Curious Reader
0 XP0/47 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Orchestration that feels like a library

Prefect (3.x as of April 2026) optimizes for one thing: "this should feel like Python, not a platform." Flows are decorated Python functions. Tasks are decorated Python functions. You run them locally with python flow.py, and the same code can be deployed to Prefect Cloud or a self-hosted server with no rewrites.

What Prefect emphasizes vs the others

  • Native async/await. Tasks can be coroutines. Concurrency is first-class.
  • Hybrid execution. Prefect Cloud orchestrates; your code runs on your infrastructure (so secrets and data never leave your network).
  • Less ceremony for small projects. A single Python file is a deployable flow.
  • Stateful flows. Tasks can communicate via results that automatically cache and replay on retry.

Code

A Prefect flow — Pythonic, async-friendly, deployable as-is·python
import pandas as pd
from prefect import flow, task, get_run_logger

@task(retries=3, retry_delay_seconds=30)
def extract(ds: str) -> pd.DataFrame:
    log = get_run_logger()
    df = pd.read_csv(f'source/orders_{ds}.csv', dtype=str)
    log.info('extracted %d rows', len(df))
    return df

@task
def transform(raw: pd.DataFrame) -> pd.DataFrame:
    return (raw
        .assign(amount_usd=lambda d: pd.to_numeric(d['amount_usd']))
        .dropna(subset=['amount_usd']))

@task
def load(clean: pd.DataFrame, ds: str) -> str:
    path = f'warehouse/orders/date={ds}/part-0.parquet'
    clean.to_parquet(path, index=False)
    return path

@flow(name='orders_pipeline')
def orders_pipeline(ds: str = '2026-04-30') -> str:
    raw = extract(ds)
    clean = transform(raw)
    return load(clean, ds)

if __name__ == '__main__':
    orders_pipeline('2026-04-30')

External links

Exercise

pip install prefect in a fresh venv. Copy the orders flow above. Run python flow.py — it executes locally. Then prefect server start in another terminal, open the UI at localhost:4200, and run again — same code, now visible in the UI. The point: the deployment is mostly a config flip, not a rewrite.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.