Technology /

Traversal 0.1.0 · MIT

Python functions.
Connected.

A small graph engine for work that branches, waits, and joins. Write the functions. Traversal handles their dependencies and concurrent execution.

Free and open source. Rust core. No service to run.

A dependency graph branches from fetch into parse and inspect. Report joins both branches before save can run.
Independent work moves together.Dependent work waits.

Ordinary PythonFunctions and existing tools

Rust schedulingReady queues and dependency state

Local historyOpt-in SQLite on your machine

Explicit reuseYour keys. Inspectable decisions.

A graph, without a framework

Keep your functions.
Connect the work.

A node is a function call. Pass one node’s result into another to define a dependency. Request an output, and Traversal runs the work needed to produce it.

The two branches below can run together. The total waits for both.

Read the complete API →
report.pyPython + Traversal
from traversal import Graph

graph = Graph("report")
source = graph.add("source", lambda: 5)
left = graph.add("left", lambda n: n * 2, source)
right = graph.add("right", lambda n: n + 3, source)
total = graph.add("total", sum, [left, right])

plan = graph.compile(total)
report = plan.run(max_concurrency=2)
report.raise_for_status()
print(report.outputs["total"])  # 18
4 nodes succeeded total → 18

Execution you can inspect

Know what can run.
Know what happened.

01

Start when the inputs are ready

Independent branches overlap up to your concurrency limit. Completion releases dependents immediately. Async functions use the event loop; blocking calls use threads.

02

Find the last attempt, or the last success

Opt into a local history store for run IDs, node outcomes, and timestamps. Inspect failures by node. Incomplete work stays visible; a read never silently declares a run abandoned.

03

Reuse with a reason

Declare repeat-safe computations with explicit cache keys. Preview which results can be reused. Resume creates a linked run and asks for a decision before repeating previously started, undeclared work.

A little memory. On your machine.

The next run starts
with context.

Keep durable run metadata in SQLite. Persist JSON results only for tasks that opt into caching. No account, hosted collector, or automatic telemetry.

History and recovery details ↗
plan.explain_run(previous=run_id)Illustrative output
sourcereuseCompatible persisted result
normalizereuseCompatible persisted result
publishdecisionPreviously started; repeat safety undeclared

Unknown external effects are never silently replayed.

Get started

One install.
Your next graph.

Install in your project’s Python environment. Supported wheels include the native engine, so you don’t need Rust installed.

python -m pip install traversal==0.1.0

CPython 3.11–3.14 · Linux x86_64 (glibc 2.28+) · macOS Apple Silicon · Windows x86_64. Other platforms require a source build and are not part of the tested wheel matrix.

A focused component.

Traversal owns graph structure, node readiness, execution state, local history, and explicit reuse. Your Python handles APIs, files, and business logic. Your scheduler decides when a run starts.

Blocking threads still obey Python’s GIL and need their own I/O timeouts. Cache keys are caller-maintained; results must be finite JSON values to persist. Cancellation cannot undo an external action. There are no distributed workers or exactly-once guarantees.

Read the supported behavior and limits →