Skip to main content

A simple event driven state machine

Project description

Event State Machine

https://github.com/fedegonzalezit/event_statemachine/actions/workflows/test.yml/badge.svg?branch=develop Documentation Status Coverage report https://img.shields.io/pypi/v/event_statemachine.svg

A simple event driven state machine

Welcome to Event StateMachine. I always struggled to find a simple statemachine that could be used in a python project. So I decided to create my own, it’s simple but useful. The desing is based on transitions more than states, so you can define a transition from a state to another and the event that triggers it.

Getting started

To install Event StateMachine, run this command in your terminal:

$ pip install event_statemachine

Let’s implement this simple turnstile example:

Turnstile example

Define your state machine:

from event_statemachine import StateMachine
from event_statemachine import transition
from event_statemachine import event_condition


class Turnstile(StateMachine):
    @transition("Locked -> Unlocked")
    @event_condition(
        lambda self: self.evt.get("action") == "coin"
        and self.evt.get("coin") == "valid"
    )
    def on_coin(self):
        print("Unlocking turnstile")

    @transition("Locked -> Locked")
    @event_condition(
        lambda self: self.evt.get("action") == "coin"
        and self.evt.get("coin") == "invalid"
    )
    def on_coin_invalid(self):
        print("Invalid coin, try again")

    @transition("Unlocked -> Unlocked")
    @event_condition(lambda self: self.evt.get("action") == "coin")
    def on_unlocked_coin(self):
        print("turnstile already unlocked, returning coin")

    @transition("Unlocked -> Locked")
    @event_condition(lambda self: self.evt.get("action") == "push")
    def on_push(self):
        print("Locking turnstile")

Initialize your state machine:

turnstile = Turnstile(initial_state="Locked")

Send events to your state machine:

evt = {"action": "push"}
sm.run_state(evt)  # Do nothing

evt = {"action": "coin", "coin": "invalid"}
sm.run_state(evt)  # Print: Invalid coin, try again

evt = {"action": "coin", "coin": "valid"}
sm.run_state(evt)  # Print: Unlocking turnstile

evt = {"action": "coin", "coin": "valid"}
sm.run_state(evt)  # Print: turnstile already unlocked, returning coin

evt = {"action": "push"}
sm.run_state(evt)  # Print: Locking turnstile

Features

  • Define your transitions using @transition decorator

  • Each transition can have a condition to be executed using @event_condition decorator.

  • You can get the context of the state maching using the method get_context() and load it using the method set_context(). This allows you to use an stateless architecture and save the context of the state machine in a database.

  • You can override the methods on_entry and on_exit in the SM. This code will be executed always at the beginning and at the end of each transition respectively.

  • Using the decorators @on_state_entry and @on_state_exit you can archieve the same as the previous point but for each state.

History

0.0.1 (2023-09-26)

  • First release on PyPI.

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

event_statemachine-0.0.3.tar.gz (153.4 kB view hashes)

Uploaded Source

Built Distribution

event_statemachine-0.0.3-py2.py3-none-any.whl (7.1 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page