Skip to main content

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 open_orbyt

The PyPI distribution is open_orbyt; the import package is orbyt:

import 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

Contributing

Contributions are welcome — issues, ideas, and pull requests.

The repo is a uv workspace (packages/orbyt is the library; examples/ and docs/ are members). Set up and check out a copy:

git clone https://github.com/erickweyunga/orbyt
cd orbyt
uv sync --all-packages     # install the workspace + dev tools
uv run pytest              # run the test suite
uvx pyrefly check packages/orbyt   # type-check

Guidelines:

  • Keep the library's single runtime dependency (pydantic) — no new ones in packages/orbyt.
  • Match the surrounding style; every public API carries a docstring.
  • Add tests for new behaviour and keep the suite green.
  • Open the PR against main.

License

MIT

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

open_orbyt-0.1.1.tar.gz (26.7 kB view details)

Uploaded Source

Built Distribution

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

open_orbyt-0.1.1-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file open_orbyt-0.1.1.tar.gz.

File metadata

  • Download URL: open_orbyt-0.1.1.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for open_orbyt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 65da9853e0aab652776309f5d485f90bc59fc7aed273266a81b0e887f3e4d62f
MD5 5f95ec9d9d05ce3278c39e0a7d8c2ac9
BLAKE2b-256 320f4aa14e419fe28ded4574de1c995f34470c91cbb17385a83f0bf1ec6b5ae8

See more details on using hashes here.

Provenance

The following attestation bundles were made for open_orbyt-0.1.1.tar.gz:

Publisher: publish.yml on erickweyunga/orbyt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file open_orbyt-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: open_orbyt-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 27.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for open_orbyt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 44e831133e5340cb95c712efd339cfc951552a7d56b59c158d0bf0b641019cac
MD5 839c9bb06ce659d8879901a8701d92a4
BLAKE2b-256 9f6c6a671dbd864fd5c62f5a22e0e0d4c95a18c468088728b223bcc109a33436

See more details on using hashes here.

Provenance

The following attestation bundles were made for open_orbyt-0.1.1-py3-none-any.whl:

Publisher: publish.yml on erickweyunga/orbyt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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