Skip to main content

SynaFlow 🌊🧠

📖 Full documentation: humansoftware.github.io/synaflow

Write plain Python functions. SynaFlow builds the pipeline for you.

PyPI License Python

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 (itemitems, user_listusers).

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

synaflow-0.22.0.tar.gz (241.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

synaflow-0.22.0-py3-none-any.whl (53.2 kB view details)

Uploaded Python 3

File details

Details for the file synaflow-0.22.0.tar.gz.

File metadata

  • Download URL: synaflow-0.22.0.tar.gz
  • Upload date:
  • Size: 241.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for synaflow-0.22.0.tar.gz
Algorithm Hash digest
SHA256 ec3f4469f214a1c22426e57a3021cb878a3c45f8f279c524cf781fb793a61b1d
MD5 03b9768f8d84cfa75ed28e4be14c9de1
BLAKE2b-256 92ea064770201e7690cc460cbe54e85b7ffb9a527d0d8ec942a047541cab4385

See more details on using hashes here.

Provenance

The following attestation bundles were made for synaflow-0.22.0.tar.gz:

Publisher: release.yml on humansoftware/synaflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file synaflow-0.22.0-py3-none-any.whl.

File metadata

  • Download URL: synaflow-0.22.0-py3-none-any.whl
  • Upload date:
  • Size: 53.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for synaflow-0.22.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d04da428d0488a35ca8f06e449185a0fe339aaa67e56ee323b61ad3fe13e15b1
MD5 084ad873ba10bee437d6963c3e62a9f3
BLAKE2b-256 746c28892ab0e7abf6c5d8c9376392494a7cf2138285d0310cf3ec6810fee334

See more details on using hashes here.

Provenance

The following attestation bundles were made for synaflow-0.22.0-py3-none-any.whl:

Publisher: release.yml on humansoftware/synaflow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page