Skip to main content

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_depth prevents infinite loops
  • ReducersExtend, 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

justgraph-0.2.1.tar.gz (5.0 kB view details)

Uploaded Source

Built Distribution

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

justgraph-0.2.1-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file justgraph-0.2.1.tar.gz.

File metadata

  • Download URL: justgraph-0.2.1.tar.gz
  • Upload date:
  • Size: 5.0 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

Hashes for justgraph-0.2.1.tar.gz
Algorithm Hash digest
SHA256 a9410f3aab5e8e15ef76eeadf0abeee41e5125736c3cf89993c0b88f31af41a3
MD5 4e405c949b6f5ad1e526fd60e133ae60
BLAKE2b-256 3a7922fb1dd98905d926e39bb22f24b4c966b954e033c448f3c84143132039b4

See more details on using hashes here.

File details

Details for the file justgraph-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: justgraph-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 7.0 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

Hashes for justgraph-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0657135c25264d1c862296fb3b033ff01a128ed961e49b56604fea5f913ae41e
MD5 30d655b89a1c8052f4a184f9442b0693
BLAKE2b-256 06d472be88da3a0566e5bcf7802bfd7ab71a5cedf2c18736677978a968d91ff8

See more details on using hashes here.

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