β‘ Dynamic Workflows
What you'll learn
How to create steps that generate sub-pipelines at runtime based on intermediate results β inspired by Flyte's dynamic-node handler.
Dynamic workflows let a single step produce an entire DAG at runtime. The generated sub-pipeline is expanded and executed inline, giving you the power to build data-driven, runtime-configurable pipelines.
Why Dynamic Workflows?
| Static Pipelines | Dynamic Workflows |
|---|---|
| Fixed number of steps | Steps generated at runtime |
| All branches known upfront | Branches depend on data |
| Rigid structure | Flexible, data-driven |
Use when: The shape of your pipeline depends on data you only have at execution time.
Basic Usage
How It Works
sequenceDiagram
participant Parent as Parent Pipeline
participant Dynamic as @dynamic step
participant Sub as Sub-Pipeline
Parent->>Dynamic: Execute with runtime data
Dynamic->>Dynamic: Generate Pipeline object
Dynamic->>Sub: Build & run sub-pipeline
Sub-->>Dynamic: DynamicWorkflowResult
Dynamic-->>Parent: Return results to parent
- The parent pipeline calls the
@dynamicfunction like any other step - The function builds and returns a
Pipelineobject - FlowyML executes that sub-pipeline inline
- Results are wrapped in a
DynamicWorkflowResultand returned to the parent
Real-World Examples
Data-Driven Feature Engineering
Conditional Fan-Out
Multi-Model Training
Direct Results (Non-Pipeline Return)
If the dynamic function returns a non-Pipeline value, it's treated as a direct result β no sub-pipeline is created:
DynamicWorkflowResult API
| Attribute | Type | Description |
|---|---|---|
sub_pipeline |
Pipeline \| None |
The generated sub-pipeline (if any) |
results |
Any |
Aggregated results from execution |
expanded |
bool |
True if a sub-pipeline was created and run |
Decorator Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str \| None |
Function name | Custom step name |
outputs |
list[str] |
[] |
Output names exposed to parent |
inputs |
list[str] |
[] |
Input names consumed from parent |
Best Practices
Keep dynamic functions focused
A dynamic step should build one logical sub-pipeline. If you need multiple expansions, use separate @dynamic steps.
Testing
Test dynamic functions by calling them directly β they return a Pipeline object you can inspect without running.
Avoid deep nesting
Dynamic workflows can themselves contain dynamic steps, but deep nesting makes debugging difficult. Prefer flat compositions.