SynaFlow 🌊🧠
📖 Full documentation: humansoftware.github.io/synaflow
Write plain Python functions. SynaFlow builds the pipeline for you.
SynaFlow is a lightweight, pure-Python pipeline engine that uses Type Hints to automatically wire and execute Directed Acyclic Graphs (DAGs) with lockstep streaming and optional bounded handoff.
Why the name? Synapse + Flow. Just like synapses automatically wire neurons together, SynaFlow automatically wires your functions together based on their types. "Flow" represents the lazy, streaming nature of how data moves through those connections.
Quickstart
from collections.abc import Generator, Iterator
from typing import NamedTuple
from synaflow import pipeline, step, run
class Params(NamedTuple):
count: int
def producer(count: int) -> Generator[int, None, None]:
yield from range(count)
def transformer(producer: Iterator[int]) -> Generator[int, None, None]:
for val in producer:
yield val * 10
def consumer(transformer: Iterator[int]) -> None:
for x in transformer:
print(f"Consumed: {x}")
p = pipeline(
name="example",
params=Params,
steps=[
step("producer", fn=producer),
step("transformer", fn=transformer),
step("consumer", fn=consumer),
],
)
run(p, Params(count=5))
Three functions, three step() calls, zero manual wiring. SynaFlow reads the
type hints and wires the DAG automatically.
What makes it different
Type-hint wiring
Parameter names match producer names — SynaFlow connects them automatically.
Singular/plural/suffix synonyms work too (item → items, user_list → users).
Lazy streaming with bounded handoff
SynaFlow streams lazily by default. Multiple consumers can stay lockstep, one
consumer can stay lazy while another materializes, and when you need a bounded
window between stages you can set max_in_flight on the producing step.
This is especially useful for I/O-bound pipelines where one step starts work and the next resolves it, such as HTTP requests, RPC calls, or object-store reads.
Static validation at build time
Type errors, missing dependencies, circular graphs, mode conflicts — all caught
when pipeline(...) is called. Materialization decisions are compiled into the
Dag too: mode resolution, per-dependency eager materialization, and the
resolved materializer callables are frozen before run() starts. If it
compiles, it's valid. No runtime surprises.
Runtime overrides on top of the compiled contract
When you need test-time swaps without patching module globals, pass
ExecutionOverrides to run() or async_run() and replace only compiled
runtime dependencies such as materializers or observers. Use
PIPELINE_SCOPE for pipeline-level observers. The DAG shape and semantics stay
fixed; only the runtime callable changes.
from synaflow import ExecutionOverrides, Observer, PIPELINE_SCOPE, Scope
overrides = ExecutionOverrides.empty(p)
sub = Scope("payments")
overrides.resources["db"] = FakeDatabase()
overrides.observers[PIPELINE_SCOPE] = [Observer(noop_metrics)]
overrides.observers[sub.scope("validate")] = [Observer(test_recorder)]
overrides.materializers[sub.scope("normalize")] = list
For included sub-pipelines, Scope(...) is the public helper for addressing
compiled step keys without hardcoding "payments__validate" by hand.
Declared resources={...} are production factories. They are called when a
step is injected. ExecutionOverrides.resources is optional and only replaces
that provider when you want a different runtime value.
See also: docs/user_docs/advanced/testability.md
Build your own runner
The DAG compiles to a deterministic JSON contract. Write custom runners or auto-generate native DAGs for Airflow, Prefect, or Dagster.
How it compares
| SynaFlow | Hamilton | Airflow / Prefect / Dagster | |
|---|---|---|---|
| Auto wiring | ✅ type hints + smart binding | ✅ type hints (exact names) | ❌ explicit A >> B |
| Lazy streaming | ✅ lockstep + bounded handoff | ❌ DataFrame-centric | ❌ task-based |
| Smart binding | ✅ singular/plural/suffix | ❌ | ❌ |
| Scope | In-process micro | Feature engineering | Cluster orchestration |
| DAG export | ✅ JSON | ✅ | ✅ |
| Sync/async parity | ✅ identical | ❌ | ✅ |
Detailed comparisons: Hamilton · Java Streams · LINQ
Installation
pip install synaflow
Documentation
Start here: humansoftware.github.io/synaflow
| Section | Description |
|---|---|
| Tutorial | 5-level step-by-step guide building a pipeline from scratch |
| Core Concepts | How the DAG is wired, lockstep flow, max in flight, build vs run, event-based processing |
| Advanced | Testability, resource factories, runtime overrides, custom materializers, observers, and export guidance |
| Examples | Every corpus pipeline with auto-generated diagrams and source code |
| Comparisons | Detailed comparisons with Hamilton, Java Streams, and LINQ |
| Design Philosophy | Architectural decisions, contracts, and design rationale |
License
MIT License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file synaflow-0.27.0.tar.gz.
File metadata
- Download URL: synaflow-0.27.0.tar.gz
- Upload date:
- Size: 293.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
230ad285a476a8662002d8c81afffc42faf928f64f901a8ebf6c46767a3755f6
|
|
| MD5 |
637ccafe8bcfa0611854ed7ab5037859
|
|
| BLAKE2b-256 |
abd0ae91bbe6f81b00d25170822a2c89605908eaec21c2eef49ca4729970c5ec
|
Provenance
The following attestation bundles were made for synaflow-0.27.0.tar.gz:
Publisher:
release.yml on humansoftware/synaflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
synaflow-0.27.0.tar.gz -
Subject digest:
230ad285a476a8662002d8c81afffc42faf928f64f901a8ebf6c46767a3755f6 - Sigstore transparency entry: 2133446333
- Sigstore integration time:
-
Permalink:
humansoftware/synaflow@267a1301fbc52ab5ab0c4b8268e751f8b5f1885d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/humansoftware
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@267a1301fbc52ab5ab0c4b8268e751f8b5f1885d -
Trigger Event:
push
-
Statement type:
File details
Details for the file synaflow-0.27.0-py3-none-any.whl.
File metadata
- Download URL: synaflow-0.27.0-py3-none-any.whl
- Upload date:
- Size: 73.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b25b416dabbcd795cc505f45c6ecb2933bfa4939ef43d2e0f301e43e3f00a9e
|
|
| MD5 |
2eab6e70e0462e30ca1b782c43707ec3
|
|
| BLAKE2b-256 |
a9e6ca2e4c4fdbbdcbc419dcab3a78fa1aed910855670e7bc4c99d07fb225017
|
Provenance
The following attestation bundles were made for synaflow-0.27.0-py3-none-any.whl:
Publisher:
release.yml on humansoftware/synaflow
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
synaflow-0.27.0-py3-none-any.whl -
Subject digest:
4b25b416dabbcd795cc505f45c6ecb2933bfa4939ef43d2e0f301e43e3f00a9e - Sigstore transparency entry: 2133446408
- Sigstore integration time:
-
Permalink:
humansoftware/synaflow@267a1301fbc52ab5ab0c4b8268e751f8b5f1885d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/humansoftware
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@267a1301fbc52ab5ab0c4b8268e751f8b5f1885d -
Trigger Event:
push
-
Statement type: