Lightweight, decorator-based implementation of a Finite State Machine
Project description
Finite State Machine
Lightweight, decorator-based Python implementation of a Finite State Machine.
Table of Contents
Installation
pip install finite-state-machine
Usage
Subclass StateMachine
and set the state
instance variable:
from finite_state_machine import StateMachine, transition
class LightSwitch(StateMachine):
def __init__(self):
self.state = "off"
super().__init__()
The transition
decorator can be used to specify valid state transitions
with an optional parameter for conditions
.
States can be of type: string
, int
, bool
, Enum
, or IntEnum
.
Can specify a single sate or a list of states for the source
parameter;
can only specify a single state as the target
target.
All condition functions need to return True
for the transition to occur,
else a ConditionsNotMet
exception will be raised.
Condition functions require the same positional position and
keyword arguments present in the transition function.
@transition(source="off", target="on", conditions=[light_is_off])
def turn_on(self):
# specify side effects
def light_is_off(machine):
return machine.state == "off"
Can also specify an on_error
parameter to handle situations
where the transition function raises an exception:
@transition(source="off", target="on", on_error="failed")
def turn_on(self):
raise ValueError
Example
from finite_state_machine import StateMachine, transition
class Turnstile(StateMachine):
initial_state = "close"
def __init__(self):
self.state = self.initial_state
super().__init__()
@transition(source=["close", "open"], target="open")
def insert_coin(self):
pass
@transition(source="open", target="close")
def pass_thru(self):
pass
REPL
In [2]: turnstile = Turnstile()
In [3]: turnstile.state
Out[3]: 'close'
In [4]: turnstile.insert_coin()
In [5]: turnstile.state
Out[5]: 'open'
In [6]: turnstile.insert_coin()
In [7]: turnstile.state
Out[7]: 'open'
In [8]: turnstile.pass_thru()
In [9]: turnstile.state
Out[9]: 'close'
In [10]: turnstile.pass_thru()
---------------------------------------------------------------------------
InvalidStartState Traceback (most recent call last)
<ipython-input-10-6abc6f4be1cd> in <module>
----> 1 turnstile.pass_thru()
~/state_machine.py in _wrapper(*args, **kwargs)
32
33 if self.state not in source:
---> 34 raise InvalidStartState
35
36 for condition in conditions:
InvalidStartState:
The examples folder contains additional workflows.
State Diagram
State Machine workflows can be visualized using a state diagram.
finite-state-machine
generates diagrams using
Mermaid Markdown syntax,
which can be viewed using the
Mermaid Live Editor.
Use the fsm_draw_state_diagram
command and point to
State Machine workflow class
that inheritences from StateMachine
.
# class parameter is required
$ fsm_draw_state_diagram --class examples.turnstile:Turnstile
# initial_state parameter is optional
$ fsm_draw_state_diagram --class examples.turnstile:Turnstile --initial_state close
Contributing
- Clone repo
- Create a virtual environment
pip install -r requirements_dev.txt
- Install pre-commit
- Set up pre-commit hooks in repo:
pre-commit install
To install a package locally for development, run:
flit install [--symlink] [--python path/to/python]
Running Tests
pytest
Inspiration
This project is inspired by django-fsm. I wanted a decorator-based state machine without having to use Django.
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 finite-state-machine-0.5.0.tar.gz
.
File metadata
- Download URL: finite-state-machine-0.5.0.tar.gz
- Upload date:
- Size: 2.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.23.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | ac08e609315e1c8ee1b374ddfb275820efb1cf8ea0a58c47699dfc8bee36f8a1 |
|
MD5 | 338ef280808fab9f7ad9090cfdf267dd |
|
BLAKE2b-256 | c982cdf07d9673999c8c03c0e8405d8be57b6b8efb36c57fe45db8164c51eff7 |
File details
Details for the file finite_state_machine-0.5.0-py3-none-any.whl
.
File metadata
- Download URL: finite_state_machine-0.5.0-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: python-requests/2.23.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9ad1e513e672f3ffda2ef06cb0504c9e1621ea7b13ab9d3ceefa77f88c12399c |
|
MD5 | cc4f5f7c9de475799adad04187ba794a |
|
BLAKE2b-256 | bc4457f4908755d25aa8400ec773c0a7f43178a9cc2daa7a1f7dcdb753edb7ab |