Architecture¶
FlowerPower is an orchestration and configuration layer on top of Hamilton. Hamilton lets you define a data pipeline as a DAG of plain Python functions: each function is a node, and its arguments declare dependencies. FlowerPower adds project structure, YAML-driven configuration, execution plumbing, and lifecycle management so that Hamilton pipelines can be organized, configured, and run as production projects.
What FlowerPower adds to Hamilton¶
In a pure Hamilton workflow you import modules into a Driver and call execute(). FlowerPower keeps that model but wraps it in conventions:
- Projects — a directory layout (
conf/,pipelines/,hooks/) that separates configuration from code. - Configuration —
project.ymlplus per-pipeline YAML files, merged with environment overrides and runtimeRunConfig. - Execution — a runtime stack that handles sync and async drivers, adapters, retries, logging, and executors.
- I/O & visualization — helpers for importing/exporting pipelines, rendering DAGs, and working with remote filesystems.
You still write Hamilton functions. FlowerPower discovers them, wires them into a driver, and runs them.
Core components¶
graph TD
A[FlowerPowerProject] -->|owns| B(PipelineManager)
B -->|manages| C[PipelineConfigManager]
B -->|discovers/creates| D[PipelineRegistry / PipelineCreator]
B -->|executes| E[PipelineExecutor]
B -->|visualizes| F[PipelineVisualizer]
B -->|imports/exports| G[PipelineIOManager]
E -->|runs| H[Pipeline]
H -->|drives| I[Hamilton Driver]
H -->|via| J[PipelineRunner]
J -->|uses| K[ExecutionContextBuilder]
J -->|uses| L[RetryManager]
J -->|uses| M[Telemetry / Logging helpers]
K -->|creates| N[Hamilton Executor]
K -->|resolves| O[Adapters]
subgraph FlowerPower
A
B
C
D
E
F
G
H
J
K
L
M
O
end
subgraph Hamilton
I
N
end
FlowerPowerProject¶
The public entry point. It creates or loads a project directory and exposes a pipeline_manager that does the real work. Use FlowerPowerProject.new() to scaffold a project and FlowerPowerProject.load() to open an existing one.
PipelineManager¶
The operational hub. It is initialized with a base directory and an optional fsspec filesystem, then loads the project configuration and exposes the sub-managers listed below.
| Property / method | Responsibility |
|---|---|
creator |
Scaffolds new pipelines. |
registry |
Lists, loads, and deletes pipelines; manages hooks. |
executor |
Runs a pipeline synchronously or asynchronously. |
visualizer |
Renders or saves pipeline DAGs. |
io |
Imports/exports pipeline definitions. |
pipelines |
List of discovered pipeline names. |
summary |
Dictionary summarizing the project pipelines. |
The manager does not run the DAG directly; it delegates to a Pipeline instance, which owns a PipelineRunner.
Execution runtime stack¶
When you call project.run("my_pipeline"), the request flows through a small stack of dedicated helpers so the pipeline object itself stays focused on configuration.
PipelineRunner¶
PipelineRunner is the facade for a single execution. It:
- Clones and merges the pipeline's default
RunConfigwith any runtime kwargs. - Resolves the Python modules that contain the Hamilton functions (including
additional_modules). - Reloads modules when
reload=True. - Delegates to
ExecutionContextBuilderfor adapters and executors. - Wraps the actual Hamilton call in
RetryManager.
It has symmetric run() and run_async() paths.
ExecutionContextBuilder¶
Builds the concrete context needed for a Hamilton execution: a Hamilton executor, an optional shutdown/cleanup callback, and the list of adapters to apply. It resolves configuration from three sources in priority order:
- Runtime
RunConfig. - Per-pipeline
conf/pipelines/<name>.yml. - Project-wide
conf/project.yml.
It also handles Ray shutdown hooks when the Ray adapter is enabled and configured to shut down on completion.
RetryManager¶
Implements exponential backoff with jitter. It retries the pipeline execution on configured exceptions, calls optional success/failure callbacks, and logs each attempt. The same logic is used for both sync and async runs.
Telemetry and logging helpers¶
initialize_telemetry() and ensure_logging_initialized() are used to avoid import-time side effects and to make log-level overrides predictable. Logging is set up once per process and reused thereafter.
Layered configuration system¶
Configuration is merged in strict precedence, highest first:
- Runtime kwargs /
RunConfig— values passed torun()or built withRunConfigBuilder. - Environment overlays — variables prefixed with
FP_PIPELINE__*orFP_PROJECT__*using double-underscore nested paths (for example,FP_PIPELINE__RUN__LOG_LEVEL=DEBUG). Values are JSON-coerced when possible. - YAML after environment interpolation —
${VAR},${VAR:-default},${VAR-default},${VAR:?err}, and$${...}escapes are expanded. Valid JSON strings become typed values. - Global shims —
FP_LOG_LEVEL,FP_EXECUTOR,FP_EXECUTOR_MAX_WORKERS,FP_EXECUTOR_NUM_CPUS,FP_MAX_RETRIES,FP_RETRY_DELAY,FP_JITTER_FACTORare used only when the corresponding specific key is absent. - Code defaults — struct defaults on
RunConfigand related configuration classes.
Tip
For a deeper look at overrides, environment variables, and adapter configuration, see Advanced configuration.
Filesystem abstraction¶
FlowerPower uses fsspeckit for filesystem access, so the same project can live on local disk, S3, GCS, or another fsspec-compatible backend. The storage_options passed to FlowerPowerProject or PipelineManager are forwarded to the filesystem constructor, and a local cache is configured automatically when remote storage is used.
Security¶
FlowerPower validates path fragments before using them to build filesystem paths. Functions such as validate_file_path, validate_pipeline_name, and validate_directory_fragment reject directory-traversal patterns like ../../../etc/passwd. A SecurityError is raised on violations, keeping project and pipeline names bounded to the intended directory tree.
Summary¶
FlowerPower does not replace Hamilton; it operationalizes it. You write plain Python functions that Hamilton turns into a DAG. FlowerPower provides the project scaffold, the configuration hierarchy, the execution runtime, and the lifecycle utilities that turn a notebook script into a maintainable, configurable pipeline project.