A workflow framework for Python. Build AI agents, data pipelines, and orchestration flows with nodes, graphs, and a shared store.
Project description
orbyt
A workflow framework for Python. Build AI agents, data pipelines, and orchestration flows with nodes, graphs, and a shared store.
Install
pip install orbyt
Quick Start
from orbyt import Flow, SharedStore, Result, new_node, run, DEFAULT_ACTION
# Create nodes
fetch = (
new_node()
.with_name("fetch")
.with_exec_func(lambda r: Result({"users": ["Alice", "Bob", "Charlie"]}))
.with_post_func(lambda shared, p, e: shared.set("data", e.value) or DEFAULT_ACTION)
)
transform = (
new_node()
.with_name("transform")
.with_prep_func(lambda shared: Result(shared.get_dict("data")))
.with_exec_func(lambda r: Result([name.upper() for name in r.must_dict()["users"]]))
.with_post_func(lambda shared, p, e: shared.set("result", e.value) or DEFAULT_ACTION)
)
# Connect into a flow
flow = Flow(fetch)
flow.connect(fetch, DEFAULT_ACTION, transform)
# Run
shared = SharedStore()
flow.run_flow(shared)
print(shared.get_list("result")) # ['ALICE', 'BOB', 'CHARLIE']
Core Concepts
Nodes
Every node runs three phases: prep (read inputs) → exec (do the work, retryable) → post (write results, return an action).
node = (
new_node()
.with_max_retries(3)
.with_wait(1.0)
.with_prep_func(lambda shared: Result(shared.get_string("input")))
.with_exec_func(lambda r: Result(r.must_string().upper()))
.with_post_func(lambda shared, p, e: shared.set("output", e.value) or DEFAULT_ACTION)
)
Or subclass for stateful nodes:
class MyNode(BaseNode):
def __init__(self):
super().__init__(max_retries=3, wait=0.5)
def prep(self, shared):
return shared.get_string("input")
def exec(self, prep_result):
return prep_result.upper()
def post(self, shared, prep_result, exec_result):
shared.set("output", exec_result)
return DEFAULT_ACTION
Flows
Connect nodes with action-based routing to build directed graphs:
flow = Flow(start_node)
flow.connect(start_node, "success", next_node)
flow.connect(start_node, "error", error_node)
flow.connect(next_node, DEFAULT_ACTION, final_node)
flow.run_flow(shared)
Flows implement the Node interface - nest them inside other flows.
SharedStore
Thread-safe key-value store with typed getters:
shared = SharedStore()
shared.set("count", 42)
shared.get_int("count") # 42
shared.get_int_or("missing", -1) # -1
shared.bind("user", UserModel) # pydantic or dataclass
Batch Processing
Process lists of items with configurable concurrency:
from orbyt import new_batch_node
batch = (
new_batch_node()
.with_batch_concurrency(5)
.with_batch_error_handling(True)
.with_prep_func(lambda shared: [Result(url) for url in shared.get_list("urls")])
.with_exec_func(lambda r: Result(fetch(r.must_string())))
.with_post_func(lambda shared, items, results: ...)
)
Retry + Fallback
node = (
new_node()
.with_max_retries(3)
.with_wait(1.0)
.with_exec_func(call_flaky_api)
.with_exec_fallback_func(lambda prep, err: {"status": "cached"})
)
Async
Every primitive has an async counterpart. Phase functions may be sync or async, and async flows can contain plain sync nodes — each phase is awaited only when it returns a coroutine.
import asyncio
from orbyt import AsyncFlow, new_async_node, run_async, Result, SharedStore, DEFAULT_ACTION
fetch = (
new_async_node()
.with_name("fetch")
.with_exec_func(async_fetch_users) # a coroutine function
.with_post_func(lambda s, p, e: s.set("data", e.value) or DEFAULT_ACTION)
)
flow = AsyncFlow(fetch, max_steps=50) # max_steps guards against runaway cycles
flow.connect(fetch, DEFAULT_ACTION, transform)
await flow.run_flow(SharedStore())
run_async mirrors run (retries sleep via asyncio.sleep, same fallback
behavior). new_async_batch_node() runs items concurrently with an
asyncio.Semaphore instead of a thread pool — the right model for I/O-bound
work. AsyncFlow.max_steps turns infinite loops into a loud RuntimeError.
Mermaid Graph Export
flow = Flow(node_a, name="My Flow")
flow.connect(node_a, DEFAULT_ACTION, node_b)
print(flow.to_mermaid())
API Reference
Core Types
| Type | Description |
|---|---|
Node |
Abstract base class - implement prep, exec, post |
BaseNode |
Default implementation with retry/batch config |
CustomNode |
Node with function fields |
NodeBuilder |
Fluent builder from new_node() |
Flow |
Directed graph of nodes (also a Node) |
SharedStore |
Thread-safe key-value store |
Result |
Value wrapper with typed accessors |
BatchNode |
Node for processing lists |
WorkerPool |
Fixed-size thread pool |
AsyncNode |
Abstract async node - async prep/exec/post |
AsyncBaseNode |
Default async node with retry/batch config |
AsyncFlow |
Async directed graph (also an AsyncNode); max_steps loop guard |
AsyncBatchNode |
Async list processing, concurrency via asyncio.Semaphore |
Factory Functions
| Function | Description |
|---|---|
new_node() |
Create a NodeBuilder |
new_batch_node() |
Create a BatchNodeBuilder |
run(node, shared) |
Execute a node through prep→exec→post |
new_async_node() |
Create an AsyncNodeBuilder |
new_async_batch_node() |
Create an AsyncBatchNodeBuilder |
run_async(node, shared) |
Await a node through prep→exec→post (sync nodes too) |
to_slice(v) |
Convert any value to list |
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file open_orbyt-0.1.0.tar.gz.
File metadata
- Download URL: open_orbyt-0.1.0.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6f42a43087f16345497b2bb54ac12625cc46319c665e20ec2584718df2b8298
|
|
| MD5 |
34721d9830ca4a85cbaebf7a46c55277
|
|
| BLAKE2b-256 |
3cf165d1a2a9103cc13dba956a830bf0e3d07a62cd7d40578e2c786662f81bad
|
Provenance
The following attestation bundles were made for open_orbyt-0.1.0.tar.gz:
Publisher:
publish.yml on erickweyunga/orbyt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
open_orbyt-0.1.0.tar.gz -
Subject digest:
b6f42a43087f16345497b2bb54ac12625cc46319c665e20ec2584718df2b8298 - Sigstore transparency entry: 2009481435
- Sigstore integration time:
-
Permalink:
erickweyunga/orbyt@79cb4e8eda151932b71f2a2eedeaa35d9b76d09a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/erickweyunga
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@79cb4e8eda151932b71f2a2eedeaa35d9b76d09a -
Trigger Event:
release
-
Statement type:
File details
Details for the file open_orbyt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: open_orbyt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f7017ca962bb8e85564934eaad83fb1a5bc9d9a8b906f9f8d3d1e7e52a9ff88
|
|
| MD5 |
b4e2a9969c04d0946da53c002b4df7c3
|
|
| BLAKE2b-256 |
19cb5f4711f724d60a3e638fb9fb20f63b170e7d05929ae74f51cc502cd5de0d
|
Provenance
The following attestation bundles were made for open_orbyt-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on erickweyunga/orbyt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
open_orbyt-0.1.0-py3-none-any.whl -
Subject digest:
3f7017ca962bb8e85564934eaad83fb1a5bc9d9a8b906f9f8d3d1e7e52a9ff88 - Sigstore transparency entry: 2009481513
- Sigstore integration time:
-
Permalink:
erickweyunga/orbyt@79cb4e8eda151932b71f2a2eedeaa35d9b76d09a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/erickweyunga
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@79cb4e8eda151932b71f2a2eedeaa35d9b76d09a -
Trigger Event:
release
-
Statement type: