Skip to main content

Finite State Machine Banner

Finite State Machine

Latest Release Supports Python 3.6+ License: MIT Code Style: Black

Build Status codecov

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

  1. Clone repo
  2. Create a virtual environment
  3. pip install -r requirements_dev.txt
  4. Install pre-commit
  5. 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.

Metadata

Release files for finite-state-machine 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for finite-state-machine 0.5.0
File Size Uploaded
finite-state-machine-0.5.0.tar.gz 2.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for finite-state-machine 0.5.0
File Interpreter ABI Platform
finite_state_machine-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 2.4 MB

Release files / finite-state-machine-0.5.0.tar.gz

Download URL finite-state-machine-0.5.0.tar.gz
Size 2.4 MB
Tags Source
SHA-256 checksum
How to use checksums
ac08e609315e1c8ee1b374ddfb275820efb1cf8ea0a58c47699dfc8bee36f8a1
BLAKE2b-256 checksum
How to use checksums
c982cdf07d9673999c8c03c0e8405d8be57b6b8efb36c57fe45db8164c51eff7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.23.0

Release files / finite_state_machine-0.5.0-py3-none-any.whl

Download URL finite_state_machine-0.5.0-py3-none-any.whl
Size 7.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ad1e513e672f3ffda2ef06cb0504c9e1621ea7b13ab9d3ceefa77f88c12399c
BLAKE2b-256 checksum
How to use checksums
bc4457f4908755d25aa8400ec773c0a7f43178a9cc2daa7a1f7dcdb753edb7ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via python-requests/2.23.0

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page