Quickstart¶
A minimal machine¶
import asyncio
from statem import Signal, StateMachine
config = {
"idle": {"on": {"START": {"target": "running", "guard": "can_start"}}},
"running": {"on": {"STOP": "idle"}},
}
def can_start(ctx, signal) -> bool:
return True
async def main() -> None:
machine = StateMachine.from_dict(config, guard_dict={"can_start": can_start})
state = await machine.run(state_name="idle", events=Signal(event="START"), session={})
print(state)
asyncio.run(main())
Output:
running
Walking through what happened:
StateMachine.from_dict(config, guard_dict={...})validatesconfigagainst theStateConfigschema, registers thecan_startguard, and checks every guard/action referenced inconfigis registered (sinceguard_dictwas supplied).machine.run(state_name="idle", events=Signal(event="START"), session={})starts in"idle", dispatches aSTARTsignal, evaluates thecan_startguard, and — since it passes — transitions to"running".The final state name is returned as a plain string.
Fuller examples¶
See the Examples page for two full, runnable scripts shown in-line: a bakery
process (examples/bread.py) and a richer bank-teller bot (examples/bank.py) that exercises
every hook the engine has, including error_state recovering from a real exception.
See the Guide for what each config field (on, always, entry, exit,
error_state) does, Streaming for the AG-UI stream() API, and the
API Reference for the full public surface.