Skip to main content

Damn simple finite state machine

Project description

dsm

Damn simple finite state machine

Build Status

About

DSM is a observable simple finite state machine implementation for Python. Transitions may be programmed declaratively or imperatively. Inputs and state changes are emitting observable events.

Requirements

  • Python 2.7, 3.5, 3.6
  • observable
  • six for compatibility between Python 2 and Python 3

Installation

pip install dsm

Usage

Django integration

It is possible to integrate dsm with Django models by declaring a StateMachineField.

from django.db import models
from dsm.fields import StateMachineField


class Order(models.Model):
    status = StateMachineField(
        transitions=(
            ('new', ['confirmed'], 'processing'),
            ('processing', ['cancel'], 'cancelled'),
            ('processing', ['send'], 'sending'),
            ('sending', ['deliver'], 'finished'),
        ),
        max_length=16,
        choices=(
            ('new', _('New')),
            ('processing', _('Processing')),
            ('sending', _('Sending')),
            ('finished', _('Finished')),
            ('canceled', _('Cancelled')),
        ),
        db_index=True,
        default='new'
    )

Now you can create an Order and check it's status:

>>> order = Order.objects.create()
>>> order.status
new
>>> type(order.status)
dsm.fields.MachineState

The string representation of status field is same as state name provided in transitions declaration, but internally there is always dsm.fields.MachineState instance.

Declarative

FSM declaration:

import string
import dsm

class SumatorMachine(dsm.StateMachine):
    class Meta:
        initial = 'init'
        transitions = (
            ('init', list(string.digits), 'digit_enter'),
            ('digit_enter', list(string.digits), 'digit_enter'),
            ('digit_enter', '=', 'summarize'),
        )

Usage:

Initialization:

fsm = SumatorMachine()

Processing one value:

fsm.process(value)

Processing multiple values:

fsm.process_many(iterable)

Gathering the current state:

>>> fsm.state
'summarize'

Resetting to the intial state:

fsm.reset()

Listening on events:

fsm.when('state', func)

Events example:

>>> the_sum = 0

>>> def add_digit(x): global the_sum; the_sum += int(x)
>>> def reset(x): global the_sum; the_sum = 0

>>> fsm = SumatorMachine()
>>> fsm.when('digit_enter', add_digit)
>>> fsm.when('init', reset)

>>> fsm.process_many('666=')
'summarize'

>>> the_sum
18

Events example (class based):

>>> class Sumator(object):
...     def __init__(self):
...         self.total = 0
...         self.fsm = SumatorMachine()
...         self.fsm.when('digit_enter', self.add)
...         self.fsm.when('init', self.reset)
...
...     def add(self, x):
...         self.total += int(x)
...
...     def reset(self, x):
...         self.total = 0
...
...     def summarize(self, values):
...         self.fsm.reset()
...         self.fsm.process_many(values+'=')
...         return self.total

>>> s = Sumator()
>>> s.summarize('666')
18

Imperative

import string
import dsm

fsm = dsm.StateMachine(
        initial='init',
        transitions=dsm.Transitions((
                ('init', list(string.digits), 'digit_enter'),
                ('digit_enter', list(string.digits), 'digit_enter'),
                ('digit_enter', '=', 'summarize'),
            ))
        )

License

BSD

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for dsm, version 0.5.2
Filename, size File type Python version Upload date Hashes
Filename, size dsm-0.5.2-py3-none-any.whl (8.2 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size dsm-0.5.2.tar.gz (5.4 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page