Skip to main content

High-performance DAG execution engine with true parallel execution, built in Rust with Python bindings

Project description

pygraph-sp Python Package

Python bindings for the graph-sp DAG execution engine with true parallel execution.

For complete documentation, visit the main repository.

Installation

pip install pygraph-sp

Quick Start

import pygraphsp as gs

# Create a graph
graph = gs.Graph()

# Define functions
def data_source(inputs):
    return {"output": [1, 2, 3, 4, 5]}

def multiply_by_2(inputs):
    return {"output": [x * 2 for x in inputs["input"]]}

# Add nodes with simplified API
graph.add(
    data_source,
    label="Data Source",
    outputs=["output"]
)

graph.add(
    multiply_by_2,
    label="Multiply by 2",
    inputs=["input"],
    outputs=["output"]
)

# Auto-connect based on matching port names
graph.auto_connect()

# Execute
executor = gs.Executor()
result = executor.execute(graph)

print(result.get_output("multiply_by_2", "output"))  # [2, 4, 6, 8, 10]

Examples

This directory contains complete Python examples:

  • simple_pipeline.py: Basic 3-node pipeline with the new simplified API
  • parallel_execution.py: Fan-out/fan-in with 3 parallel branches (44% speedup)
  • variants_demo.py: Hyperparameter sweeps and parameter variations
  • port_mapping_demo.py: Advanced port mapping with broadcast/impl names
  • complex_objects.py: Nested objects, JSON, and lists
  • branching_example.py: Branch creation and management

Running Examples

cd python_examples

# Simple pipeline with new API
python simple_pipeline.py

# Parallel execution (shows speedup)
python parallel_execution.py

# Hyperparameter sweeps
python variants_demo.py

Features

  • True Parallel Execution: Independent nodes run concurrently (44% faster)
  • 🔌 Simplified API: graph.add(function, label=, inputs=, outputs=)
  • 🎯 Auto-Connect: Automatically connects nodes with matching port names
  • 🔄 Variants & Sweeps: Built-in hyperparameter sweep support
  • 📊 Rich Data Types: Primitives, lists, nested dicts, JSON, binary data
  • Cycle Detection: Built-in DAG validation

API Overview

Creating Graphs (New Simplified API)

import pygraphsp as gs

# Create a new graph
graph = gs.Graph()

# Define your function
def my_processor(inputs):
    # inputs is a dict with your port names as keys
    value = inputs["input_data"]
    return {"result": value * 2}

# Add node with simplified API
graph.add(
    my_processor,           # Your function
    label="My Processor",   # Display name (optional)
    inputs=["input_data"],  # List of input port names
    outputs=["result"]      # List of output port names
)

# Auto-connect nodes with matching port names
graph.auto_connect()

# Or manually connect if needed
# graph.add_edge("source_fn", "data", "my_processor", "input_data")

# Validate graph (checks for cycles)
graph.validate()

Note: For advanced cases where parameter names differ from port names, see port_mapping_demo.py for explicit mapping examples.

Executing Graphs

# Create executor
executor = gs.Executor()

# Execute graph (automatically parallelizes independent nodes)
result = executor.execute(graph)

# Get outputs
output_value = result.get_output("my_processor", "result")
print(f"Result: {output_value}")

# Check success
if result.is_success():
    print("✓ Execution successful!")

Graph Analysis

# Analyze graph structure
analysis = gs.Inspector.analyze(graph)
print(f"Nodes: {analysis.node_count}")
print(f"Depth: {analysis.depth}")
print(f"Width: {analysis.width}")

# Generate visualization
mermaid = gs.Inspector.to_mermaid(graph)
print(mermaid)

Variants & Parameter Sweeps

# Create parameter variations
def learning_rate_gen(i):
    rates = [0.001, 0.01, 0.1]
    return gs.PortData(rates[i])

variant_branches = graph.create_variants(
    name_prefix="lr",
    count=3,
    param_name="learning_rate",
    variant_function=learning_rate_gen,
    parallel=True
)

# Merge results from all variants
graph.merge_branches(
    node_id="best_model",
    branches=variant_branches,
    port="accuracy"
)

See variants_demo.py for complete examples.

Data Types

All Python types are automatically converted:

Python Type graph-sp Type
int Int
float Float
str String
bool Bool
None None
list List
dict Map
JSON-serializable Json
bytes Bytes

Complex Data Structures

# Nested objects work seamlessly
user = {
    "name": "Alice",
    "age": 30,
    "address": {
        "city": "NYC",
        "zip": "10001"
    },
    "hobbies": ["reading", "coding", "hiking"]
}

# Lists of any type
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True, None]

# JSON structures
product = {
    "id": "laptop-001",
    "specs": {
        "cpu": "Intel i7",
        "ram": "16GB"
    },
    "available": True,
    "price": 999.99
}

Parallel Execution

The executor automatically identifies and parallelizes independent branches:

import pygraphsp as gs
import time

# Fan-out pattern: 3 branches run in parallel
#
#         source
#        /  |  \
#     slow fast medium    <- Execute concurrently!
#        \  |  /
#        merger
#
# Sequential time: 900ms (500 + 100 + 300)
# Parallel time: 500ms (max branch time)
# Speedup: 44% faster!

graph = gs.Graph()

def source_fn(inputs):
    return {"value": 100}

def slow_branch(inputs):
    time.sleep(0.5)  # 500ms
    return {"a": inputs["input"] * 2}

def fast_branch(inputs):
    time.sleep(0.1)  # 100ms
    return {"b": inputs["input"] + 50}

def medium_branch(inputs):
    time.sleep(0.3)  # 300ms
    return {"c": inputs["input"] // 2}

def merger(inputs):
    return {"result": inputs["a"] + inputs["b"] + inputs["c"]}

# Add nodes with simplified API
graph.add(source_fn, label="Source", outputs=["value"])
graph.add(slow_branch, label="Slow", inputs=["input"], outputs=["a"])
graph.add(fast_branch, label="Fast", inputs=["input"], outputs=["b"])
graph.add(medium_branch, label="Medium", inputs=["input"], outputs=["c"])
graph.add(merger, label="Merger", inputs=["a", "b", "c"], outputs=["result"])

# Auto-connect based on matching port names
graph.auto_connect()

# Execute - branches run in parallel!
executor = gs.Executor()
result = executor.execute(graph)
print(result.get_output("merger", "result"))  # 300

Building from Source

If you want to build from source instead of using PyPI:

# Clone repository
git clone https://github.com/briday1/graph-sp.git
cd graph-sp

# Install maturin
pip install maturin

# Build and install
maturin develop --release --features python

Documentation

  • Full Documentation: https://github.com/briday1/graph-sp
  • Port Data Types: See docs/PORT_DATA_TYPES.md in the repository
  • Expected Output: See EXPECTED_OUTPUT.md in this directory

Performance

Measured with the parallel_execution.py example:

  • Sequential execution: ~900ms
  • Parallel execution: ~502ms
  • Speedup: 44% faster

The executor uses Rust's tokio runtime for true concurrent execution while properly managing Python's GIL.

License

MIT License

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pygraph_sp-2026.1.1.tar.gz (70.2 kB view details)

Uploaded Source

Built Distributions

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

pygraph_sp-2026.1.1-cp312-cp312-win_amd64.whl (388.5 kB view details)

Uploaded CPython 3.12Windows x86-64

pygraph_sp-2026.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (605.7 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

pygraph_sp-2026.1.1-cp312-cp312-macosx_11_0_arm64.whl (522.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file pygraph_sp-2026.1.1.tar.gz.

File metadata

  • Download URL: pygraph_sp-2026.1.1.tar.gz
  • Upload date:
  • Size: 70.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pygraph_sp-2026.1.1.tar.gz
Algorithm Hash digest
SHA256 12bea1b87e43475f512e3728f53e39e34dbf0db0588a78e4aaee6be51444d1c2
MD5 d6c9e73b2fbfb2beba7843715cf3a8ab
BLAKE2b-256 91bd06bd8d9a89bca4fbf45e744db3530b41b1ef42b0532221b073727c513431

See more details on using hashes here.

File details

Details for the file pygraph_sp-2026.1.1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for pygraph_sp-2026.1.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f75d39f188909a47a1736a0a3f30bc96f89ce2528faa10c602c7bf7a11d7aa51
MD5 17e080db185f1786a80fd8732a7467e2
BLAKE2b-256 3578edc1f4a1e6e493912add1acbd10984dd4caf2a9d236d9d3c567b1903e52c

See more details on using hashes here.

File details

Details for the file pygraph_sp-2026.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pygraph_sp-2026.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b432af09f15f637d6e0a902777f29e45c9ceca1f48f61836ca91e3e70b12eb90
MD5 e93682d65ffb6918a808d461fd9a1bab
BLAKE2b-256 47d3fa39d0388b1b39f65ad2a4496b02ca9bd910f1263d9d6a76c9c40b9f4134

See more details on using hashes here.

File details

Details for the file pygraph_sp-2026.1.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pygraph_sp-2026.1.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 174f158de2266b374729c2653f4576d8c07ace4993d3c6fb4fc1e488e6467dc9
MD5 2bc9087009fd497e041945f6d5a29e37
BLAKE2b-256 4648726a219b4d109b03d9d6210ad27bcef138dc9070c1c8767ca2a28cc79718

See more details on using hashes here.

Supported by

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