A simple stupid, declarative finite state machine for Python.
Project description
simplestate
Simplestate helps developers create and manage finite state machines in the simplest way possible—focusing solely on states and transitions, leaving out complex event systems.
Features
- Focus on states and transitions.
- Minimalistic and easy to use.
- Supports entering-state handlers for additional functionality.
Installation
To install simplestate,
use poetry:
poetry add simplestate
use pip:
pip install simplestate
Usage Example
Here's a basic example of using simplestate:
m[state
] + action
>> next_state
from simplestate import StateMachine
m = StateMachine("loading") # Define the machine with an initial state
m["loading"] + "error" >> "failed" # Transition from loading to failed on "error"
m["loading"] + "ok" >> "success" # Transition from loading to success on "ok"
m["?"] + "back" >> "loading" # Any state transitions to loading on "back"
# Start the machine
m.start() # adjust inital state by this m.start(at_state="ok")
assert m.current == "loading"
# Trigger transitions
m.handle("ok")
assert m.current == "success"
m.handle("back")
assert m.current == "loading"
m.handle("back")
assert m.current == "loading"
# Trigger transitions with context
m.handle("error", error="Something went wrong")
assert m.current == "failed"
Why Simplestate?
The goal of simplestate is to keep finite state machines simple and focused. By eliminating complex event systems, you can easily manage states and transitions while keeping the code testable and maintainable.
Event Handling on State Entry
Simplestate allows event handling when entering a state using .add_callbacks()
. These callbacks take previous
and an optional **input_context
.
# Add handlers for entering states
m.add_callbacks({
"loading": lambda previous: print(f"{previous} >> loading"),
"failed": lambda previous, **input_context: print(f"{previous} >> failed: {input_context['error']}"),
"success": lambda previous: print(f"{previous} >> success"),
})
FAQ
Q: How can I handle state exit events?
A: You can use the entering handler for the next state to handle actions when leaving the previous state.
def on_state_x(previous, **input_context):
if previous == "a":
do_this()
elif previous == "b":
do_that()
Q: Can I represent the state machine as a class?
A: Yes! Think of simplestate as a state manager. You can compose it within your own class for handling side effects:
class TrafficLight:
def __init__(self):
m = StateMachine("red")
m["red"] + "next" >> "green"
m["green"] + "next" >> "yellow"
m["yellow"] + "next" >> "red"
m.start()
self.machine = m
def display(self) -> str:
return self.machine.current
def next(self) -> None:
self.machine.handle("next")
if __name__ == '__main__':
light = TrafficLight()
while True:
state = light.display()
print(state)
# pause for a few seconds
match state:
case "red" | "green":
time.sleep(30)
case "yellow":
time.sleep(5)
# transition
light.next()
Tests
To run the tests:
poetry install --with test
poetry run pytest
Contribution
Contributions are welcome! Feel free to open an issue or submit a pull request.
- Install devcontainer
- Open this project in dev container
- Run
poetry shell
- Run
poetry install --with test
- Run
poetry run pytest
License
This project is licensed under a free, open-source license.
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
File details
Details for the file simplestate-0.1.5.tar.gz
.
File metadata
- Download URL: simplestate-0.1.5.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.19
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c07ee32da4220184d6718c245ef7ad642141741adb1f44282c3d98e494df713e |
|
MD5 | 8bf8e0257e48c20b4bf087a0663032ae |
|
BLAKE2b-256 | d92d01f0b32ad2d7d30dab90431b3cf0026679a8532a6ea46498c3efd2ac8864 |
File details
Details for the file simplestate-0.1.5-py3-none-any.whl
.
File metadata
- Download URL: simplestate-0.1.5-py3-none-any.whl
- Upload date:
- Size: 8.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.9.19
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | bea93fbcaa758588257c79c56a28293ee753512e771971dcf10032d48b4d3993 |
|
MD5 | cf9beb125c55ed04617b4b227d1b0ac5 |
|
BLAKE2b-256 | 513fcb92fa4c159528531fdd74eac0f88453f5fac1f6ccd4cb7799b16da38c83 |