How to Build a Mock ML Pipeline with Prefect in Python
Create a lightweight Prefect flow with mock preprocessing, training, and evaluation tasks to prototype an ML pipeline end-to-end.
pip install prefect
Python code
33 linesfrom prefect import task, flow
from datetime import datetime
@task
def preprocess_data(raw_value: float) -> float:
"""Mock preprocessing: normalize the input value."""
return raw_value / 100.0
@task
def train_model(features: float) -> dict:
"""Mock training: return a fake model artifact."""
return {"model_type": "linear", "trained_on": datetime.now().isoformat(), "metric": features * 0.95}
@task
def evaluate_model(model: dict) -> str:
"""Mock evaluation: produce a short report."""
return f"Model {model['model_type']} scored {model['metric']:.2f} (trained {model['trained_on']})"
@flow(name="mock_ml_pipeline")
def ml_flow(raw_input: float = 42.0):
processed = preprocess_data(raw_input)
model = train_model(processed)
report = evaluate_model(model)
print(report)
return report
if __name__ == "__main__":
ml_flow(42.0)
Output
Model linear scored 0.40 (trained 2025-03-15T10:30:00.123456)
How it works
This code uses Prefect decorators @task and @flow to turn ordinary Python functions into orchestrated units. Each task encapsulates a stage of an ML pipeline — preprocessing, training, and evaluation — and the flow chains them together by calling the tasks directly. Prefect automatically captures the execution graph, retries, and logging, so you can switch these mock functions with real implementations later. The datetime.now().isoformat() call inside train_model gives a realistic timestamp artifact to mimic actual model metadata.
Common mistakes
- Forgetting to include `if __name__ == '__main__':` when running the flow as a script
- Assuming Prefect tasks are plain Python functions — they return `PrefectFuture` objects outside a flow context
- Not pinning the Prefect version in requirements, causing API breakage between 2.x and 3.x
Variations
- Use `@task(retries=2)` to add automatic retry logic to a real model training call
- Wrap the flow in `with Flow('name') as flow:` for Prefect 1.x syntax
Real-world use cases
- Prototyping a data science pipeline before investing in heavy training infrastructure, letting you validate the orchestration logic quickly.
- Running scheduled batch inference jobs where each step (preprocess, predict, evaluate) is a Prefect task with retries and logging.
- Stubbing external services like model registries or feature stores during integration tests of your pipeline code.
Sponsored
More from ML engineering pipelines
- Bayesian Optimization in Python: A Simplified Mock Implementation medium
- Build a Data Helper Class in Python for ML Pipelines easy
- Build a Mock Random Forest Classifier in Python easy
- Champion Challenger Deployment Mock in Python easy
- Compare Model A vs Model B Metrics in Python easy
- Create a Minimal Great Expectations Suite Mock in Python easy
Keep learning
Related tutorials and quizzes for this topic.