Simple Pipeline

The simplest hypergraph workflow: a linear chain of functions where data flows in one direction.

When to Use

  • ETL pipelines (extract → transform → load)

  • Single-pass ML inference (preprocess → predict → postprocess)

  • Data transformations (clean → enrich → validate → save)

Straightforward data flow — functions execute in a single pass.

Basic Pattern

from hypergraph import Graph, node, SyncRunner

@node(output_name="cleaned")
def clean(raw_data: str) -> str:
    """Remove whitespace and normalize."""
    return raw_data.strip().lower()

@node(output_name="features")
def extract_features(cleaned: str) -> dict:
    """Extract features from cleaned text."""
    return {
        "length": len(cleaned),
        "word_count": len(cleaned.split()),
        "has_numbers": any(c.isdigit() for c in cleaned),
    }

@node(output_name="result")
def classify(features: dict) -> str:
    """Classify based on features."""
    if features["word_count"] > 100:
        return "long_form"
    return "short_form"

# Build the pipeline
pipeline = Graph([clean, extract_features, classify])

# Run it
runner = SyncRunner()
result = runner.run(pipeline, {"raw_data": "  Hello World  "})

print(result["cleaned"])   # "hello world"
print(result["features"])  # {"length": 11, "word_count": 2, "has_numbers": False}
print(result["result"])    # "short_form"

How Edges Are Inferred

The magic: output names match input parameters.

  • clean produces "cleaned"

  • extract_features takes cleaned as a parameter → edge created

  • extract_features produces "features"

  • classify takes features as a parameter → edge created

Consistent naming is all it takes — edges are inferred automatically.

Inspecting the Graph

Multiple Inputs

Nodes can have multiple inputs:

Note: top_k has a default value, so it's optional. text and query are required.

Parallel Branches

Independent nodes run in parallel (with AsyncRunner):

Binding Values

Pre-fill some inputs for reuse:

Type Validation

Catch type errors at build time:

What's Next?

When you need conditional logic:

When you need composition:

Last updated