Skip to main content

yieldgraph

Build interruptible, generator-driven ETL pipelines as directed graphs — in pure Python.

CI Python 3.14+ License: MIT Docs


What is yieldgraph?

yieldgraph lets you compose data-processing pipelines by connecting plain Python callables into a directed graph. Each callable becomes a Node. Nodes are linked by Edges — lightweight queues that carry data tuples downstream. Call graph.run() and the pipeline does the rest.

There is no framework to learn. Your business logic stays in ordinary Python functions. yieldgraph just wires them together and gets out of the way.


Features

  • Pure Python, zero runtime dependencies — stdlib only; loguru is optional.
  • Generator-native — yield zero, one, or many results per input; everything stays lazy.
  • Cooperative cancellation — set graph.cancelled = True or press Ctrl+C; the pipeline stops cleanly at the next yield.
  • Fan-out branching — attach multiple downstream chains to any node with a single add_chain call.
  • Threaded mode — flip YIELDGRAPH_THREADED=1 to run all nodes concurrently; edges become thread-safe blocking queues automatically.
  • Built-in observability — every node exposes n_consumed, n_produced, errors, and a progress fraction you can poll at any time.

Installation

pip install yieldgraph

From source:

git clone https://github.com/j4ggr/yieldgraph.git
cd yieldgraph
pip install -e .

Quick start

from yieldgraph import Graph

def source(graph):
    """Emit raw records — receives the Graph instance as first argument."""
    for row in [
        {"name": "Alice", "score": 95},
        {"name": "Bob",   "score": 72},
        {"name": "Carol", "score": 88},
    ]:
        yield row

def grade(record):
    """Add a pass/fail label to each record."""
    record["grade"] = "pass" if record["score"] >= 85 else "fail"
    yield record

def format_output(record):
    """Format as a human-readable string."""
    yield f"{record['name']}: {record['grade']} ({record['score']})"

g = Graph()
g.add_chain(source, grade, format_output)
g.run()

for row in g.output:
    print(row[0])
# Alice: pass (95)
# Bob: fail (72)
# Carol: pass (88)

Fan-out — multiple downstream chains

def source(graph):
    for x in range(1, 6):
        yield x

def store_db(x):
    yield f"db:{x}"

def send_queue(x):
    yield f"mq:{x}"

g = Graph()
g.add_chain(source, store_db)    # chain 1
g.add_chain(source, send_queue)  # chain 2 — same source, parallel branch
g.run()

print(g.output)
# [('db:1',), ('db:2',), ..., ('mq:1',), ('mq:2',), ...]

Cooperative cancellation

def source(graph):
    for i in range(1_000_000):
        if i >= 5:
            graph.cancelled = True   # stop cleanly after this item
            return
        yield i

g = Graph()
g.add_chain(source, process)
g.run()

print(len(g.output))   # 5
print(g.cancelled)     # True

Threaded execution

YIELDGRAPH_THREADED=1 python my_pipeline.py

Or in Python before the run:

import os
os.environ["YIELDGRAPH_THREADED"] = "1"

g = Graph()
g.add_chain(fetch_from_api, transform, write_to_db)
g.run()

Error handling

Exceptions raised inside a node are caught per-item and stored — they never abort the pipeline. Inspect them after the run:

g.run()

for name, node in g.nodes.items():
    if node.n_errors:
        print(f"{name}: {node.n_errors} error(s)")
        for err in node.errors:
            print(f"  {type(err).__name__}: {err}")

if g.succeeded:
    print(f"Done — {len(g.output)} rows produced")

Status & progress

Expression Type Description
g.output list[tuple] All tuples emitted by terminal nodes
g.succeeded bool Finished without errors
g.has_output bool Finished and produced at least one row
g.error str Graph-level error description (empty on success)
g.step str Human-readable label of the currently executing node
g.progress int 0–100 % progress of the current node
g.cancelled bool Whether the run was cancelled
g.finished bool Whether run() has returned

Documentation

Full guides and API reference at https://j4ggr.github.io/yieldgraph/


Development

# Install dev dependencies
pdm install -G test -G doc

# Run tests
pdm run pytest

# Build docs locally
pdm run mkdocs serve

License

MIT

Metadata

Release files for yieldgraph 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for yieldgraph 0.4.0
File Size Uploaded
yieldgraph-0.4.0.tar.gz 34.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for yieldgraph 0.4.0
File Interpreter ABI Platform
yieldgraph-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 60.4 kB

Release files / yieldgraph-0.4.0.tar.gz

Download URL yieldgraph-0.4.0.tar.gz
Size 34.2 kB
Tags Source
SHA-256 checksum
How to use checksums
64fe64b5584ebee32c41eaf4110547d91d5c9c222b25e70f4b54a3cf36bc7884
BLAKE2b-256 checksum
How to use checksums
b25d464128979ef7a9654a1537a56c46823de31997875ec516f9679648f140f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.28.0 CPython/3.12.3 Windows/11

Release files / yieldgraph-0.4.0-py3-none-any.whl

Download URL yieldgraph-0.4.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d95125e8f5963251523693f6ec159a82ef79f51d3f132e0dec03f7dd5cb0a0b3
BLAKE2b-256 checksum
How to use checksums
1367cfc9d92778fc62b1b39df25ca6dc6cd95009d4f3adc8d549058c84648f05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.28.0 CPython/3.12.3 Windows/11

Release history Release notifications | RSS feed

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page