Python finite state machine library with declarative API for sync and async applications
npx @tessl/cli install tessl/pypi-python-statemachine@2.5.00
# Python StateMachine
1
2
A comprehensive and intuitive finite state machine library designed for both synchronous and asynchronous Python applications. It offers a pythonic and expressive API for implementing state machines with basic components (States, Events, Transitions), action handlers, conditional transitions with guards and validators, and full async/await support.
3
4
## Package Information
5
6
- **Package Name**: python-statemachine
7
- **Language**: Python
8
- **Installation**: `pip install python-statemachine`
9
- **Optional Dependencies**: `pip install python-statemachine[diagrams]` (for Graphviz diagram generation)
10
11
## Core Imports
12
13
```python
14
from statemachine import StateMachine, State, Event
15
```
16
17
For exceptions:
18
19
```python
20
from statemachine.exceptions import TransitionNotAllowed, InvalidStateValue
21
```
22
23
For mixins and integration:
24
25
```python
26
from statemachine.mixins import MachineMixin
27
```
28
29
For diagram generation:
30
31
```python
32
from statemachine.contrib.diagram import DotGraphMachine
33
```
34
35
## Basic Usage
36
37
```python
38
from statemachine import StateMachine, State
39
40
class TrafficLightMachine(StateMachine):
41
"A traffic light state machine"
42
43
# Define states
44
green = State(initial=True)
45
yellow = State()
46
red = State()
47
48
# Define transitions
49
cycle = (
50
green.to(yellow)
51
| yellow.to(red)
52
| red.to(green)
53
)
54
55
# Define actions
56
def before_cycle(self, event: str, source: State, target: State, message: str = ""):
57
message = ". " + message if message else ""
58
return f"Running {event} from {source.id} to {target.id}{message}"
59
60
def on_enter_red(self):
61
print("Don't move.")
62
63
def on_exit_red(self):
64
print("Go ahead!")
65
66
# Create and use the state machine
67
sm = TrafficLightMachine()
68
69
# Send events
70
result = sm.send("cycle") # Returns: "Running cycle from green to yellow"
71
sm.cycle() # Alternative way to trigger event
72
73
# Check current state
74
print(sm.current_state.id) # "yellow"
75
print(sm.yellow.is_active) # True
76
77
# Iterate over states and events
78
state_ids = [s.id for s in sm.states] # ['green', 'yellow', 'red']
79
event_ids = [e.id for e in sm.events] # ['cycle']
80
```
81
82
## Architecture
83
84
The python-statemachine library follows a decoupled design that separates state machine logic from domain models:
85
86
- **StateMachine**: Main class that orchestrates states, events, and transitions
87
- **State**: Individual states with entry/exit actions and transition definitions
88
- **Event**: Triggers that initiate state transitions
89
- **Transition**: Connection between states with conditions and actions
90
- **Engines**: Execution engines for sync (SyncEngine) and async (AsyncEngine) support
91
- **Model Integration**: Optional integration with external domain objects via mixins
92
93
This design enables controlled state transitions with comprehensive testing coverage, correctness guarantees through compile-time validations, and flexible integration patterns for workflow management, order processing, and any application requiring robust state-driven behavior.
94
95
## Capabilities
96
97
### Core State Machine and States
98
99
Fundamental state machine functionality including StateMachine class definition, State objects with initial/final flags, state transitions, and basic state management operations.
100
101
```python { .api }
102
class StateMachine:
103
def __init__(self, model=None, state_field: str = "state", start_value=None, rtc: bool = True, allow_event_without_transition: bool = False, listeners=None): ...
104
def send(self, event: str, *args, **kwargs): ...
105
@property
106
def current_state(self) -> State: ...
107
@property
108
def states(self) -> States: ...
109
@property
110
def events(self) -> list: ...
111
112
class State:
113
def __init__(self, name: str = None, value=None, initial: bool = False, final: bool = False, enter=None, exit=None): ...
114
def to(self, *states, **kwargs) -> TransitionList: ...
115
def from_(self, *states, **kwargs) -> TransitionList: ...
116
@property
117
def is_active(self) -> bool: ...
118
```
119
120
[Core State Machine](./core-statemachine.md)
121
122
### Events and Transitions
123
124
Event handling and state transition management including event triggers, transition definitions with conditions, guards and validators, and transition lifecycle callbacks.
125
126
```python { .api }
127
class Event(str):
128
def __init__(self, name: str = None): ...
129
@property
130
def transitions(self) -> TransitionList: ...
131
132
class Transition:
133
def __init__(self, source: State, target: State, event=None, internal: bool = False, validators=None, cond=None, unless=None, on=None, before=None, after=None): ...
134
```
135
136
[Events and Transitions](./events-transitions.md)
137
138
### Actions and Callbacks
139
140
Lifecycle hooks, action handlers, callback registration, and dependency injection for state machine events including entry/exit actions, transition callbacks, and custom event handlers.
141
142
```python { .api }
143
def before_{event}(self, event: str, source: State, target: State, **kwargs): ...
144
def after_{event}(self, event: str, source: State, target: State, **kwargs): ...
145
def on_enter_{state}(self, **kwargs): ...
146
def on_exit_{state}(self, **kwargs): ...
147
```
148
149
[Actions and Callbacks](./actions-callbacks.md)
150
151
### Exceptions and Error Handling
152
153
Error scenarios, exception types, and error handling patterns including transition validation errors, invalid state values, and configuration errors.
154
155
```python { .api }
156
class StateMachineError(Exception): ...
157
class TransitionNotAllowed(StateMachineError): ...
158
class InvalidStateValue(StateMachineError): ...
159
class InvalidDefinition(StateMachineError): ...
160
```
161
162
[Exceptions and Error Handling](./exceptions.md)
163
164
### Mixins and Integration
165
166
Domain model integration patterns, mixin classes for automatic state machine binding, and framework integration including Django support and model field binding.
167
168
```python { .api }
169
class MachineMixin:
170
state_field_name: str = "state"
171
state_machine_name: str = None
172
state_machine_attr: str = "statemachine"
173
bind_events_as_methods: bool = False
174
```
175
176
[Mixins and Integration](./mixins-integration.md)
177
178
### Diagram Generation
179
180
Graphical representation and visualization features including Graphviz diagram generation, state machine visualization, and diagram customization options.
181
182
```python { .api }
183
class DotGraphMachine:
184
def __init__(self, machine: StateMachine): ...
185
def create_digraph(self) -> pydot.Dot: ...
186
187
def quickchart_write_svg(sm: StateMachine, path: str): ...
188
```
189
190
[Diagram Generation](./diagrams.md)
191
192
### Utilities and Data Classes
193
194
Additional utility classes, data structures, and helper functions that support state machine operations including event data handling, model integration, and internal state management.
195
196
```python { .api }
197
@dataclass
198
class TriggerData:
199
machine: StateMachine
200
event: Event
201
args: tuple = field(default_factory=tuple)
202
kwargs: dict = field(default_factory=dict)
203
204
class Events:
205
def add(self, events): ...
206
def match(self, event: str) -> bool: ...
207
208
def qualname(cls) -> str: ...
209
def ensure_iterable(obj): ...
210
```
211
212
[Utilities and Data Classes](./utilities.md)