Skip to content

Basic Usage

Common operations with nodes and executors.

Creating Nodes

Simple Node

from grafo import Node

async def my_task():
    return "result"

node = Node(coroutine=my_task, uuid="task_1")

Node with Parameters

async def add_numbers(a: int, b: int):
    return a + b

node = Node(
    coroutine=add_numbers,
    uuid="adder",
    kwargs=dict(a=5, b=3),
    timeout=30  # Optional timeout in seconds (default: 60)
)

Connecting Nodes

Basic Connection

await parent.connect(child)

Multiple Children (Parallel)

await parent.connect(child_a)
await parent.connect(child_b)
await parent.connect(child_c)
# All children run in parallel after parent completes

Multiple Parents (Fan-in)

await parent_a.connect(child, forward="param_a")
await parent_b.connect(child, forward="param_b")
# Child waits for BOTH parents before running

Executing Trees

Basic Execution

from grafo import TreeExecutor

executor = TreeExecutor(uuid="My Tree", roots=[root_node])
await executor.run()

# Access results
print(root_node.output)

Multiple Roots

executor = TreeExecutor(
    uuid="Multi-Root",
    roots=[root_a, root_b, root_c]
)
await executor.run()
# All roots start simultaneously

Accessing Results

await executor.run()

result = node.output  # Individual node output
runtime = node.metadata.runtime  # Execution time in seconds
level = node.metadata.level  # Tree depth (0 for roots)

TreeExecutor Return Value

The TreeExecutor.run() method returns a list of Node objects in the order they executed. This allows you to inspect all nodes after execution, including their outputs and metadata. For example:

results = await executor.run()
for node in results:
    print(f"{node.uuid}: {node.output}")

Disconnecting Nodes

# Disconnect specific child
await parent.disconnect(child)

# Redirect to new children
await parent.redirect([new_child_a, new_child_b])

Next Steps