A lightweight graph-based state machine.
Project description
justgraph
A lightweight graph-based state machine inspired by LangGraph.
from dataclasses import dataclass
from justgraph import State, FieldUpdate, Step, Graph
from justgraph.reducers import Extend, Increment
@dataclass
class ChatState(State):
messages: list[str]
counter: int
graph = Graph([ChatState])
@graph.node("greet")
def greet(state: ChatState) -> list[Step]:
return [Step("log", [
FieldUpdate(ChatState, "messages", Extend(["hello"])),
FieldUpdate(ChatState, "counter", Increment(1)),
])]
@graph.node("log")
def log(state: ChatState) -> list[Step]:
print(state.messages)
return []
graph.set_entry_point("greet")
app = graph.compile()
app.invoke([ChatState(messages=[], counter=0)])
# ['hello']
Features
- Nodes — functions that receive state and return
list[Step] Step(target, updates)— encapsulate routing and data mutations together- No edges — all routing is implicit in return values
- Parallel fan-out — multiple
Steps run branches concurrently - N=1 optimization — linear chains reuse state directly (no copy)
- Depth limit — configurable
max_depthprevents infinite loops - Reducers —
Extend,Increment,Assign,Merge, or custom - Multiple states — nodes can depend on different state types
Context— inspect node name, depth, branch id, and pass runtime config
Context
Every node can optionally receive a Context parameter for introspection:
from justgraph import Context
@graph.node("chat")
def chat(state: ChatState, ctx: Context) -> list[Step]:
print(f" node={ctx.node_name}, depth={ctx.depth}")
print(f" branch={ctx.branch_id}, config={ctx.config}")
return [Step("log")]
The Context object provides: node_name, last_node, depth, max_depth, invoke_id, start_time, branch_id, and config (a dict passed via invoke(…, ctx_config={...})).
Custom Reducers
Subclass Reducer[T] and implement apply(old: T) -> T:
from justgraph import Reducer, FieldUpdate
class Multiply(Reducer[int]):
def __init__(self, factor: int):
self._factor = factor
def apply(self, old: int) -> int:
return old * self._factor
# Use it like any built-in reducer
FieldUpdate(ChatState, "counter", Multiply(3))
Examples
uv run examples/chat.py
uv run examples/conditional.py
Tests
uv run pytest
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
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 justgraph-0.2.2.tar.gz.
File metadata
- Download URL: justgraph-0.2.2.tar.gz
- Upload date:
- Size: 5.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f8debbcb1123eab8b98f30a02edfab0616430395e6b992966d75b8f5fb56bc53
|
|
| MD5 |
cbdea6644b7ff54a9dd2720e544766e6
|
|
| BLAKE2b-256 |
4054fad461747689039f19f300b2da4eb240f448f7f10f59df1064646ad1e54e
|
File details
Details for the file justgraph-0.2.2-py3-none-any.whl.
File metadata
- Download URL: justgraph-0.2.2-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc1cf2dacffe2cb22daa951cdc215edd33f7bc25c48fb6ddcdbb46e333493a33
|
|
| MD5 |
503e893e158ebfb812a309626733bb87
|
|
| BLAKE2b-256 |
7de6a9f84a2457528055ef0131e6139bd8781f96d85a4d5b2a8e790b579c0e2c
|