Skip to main content

Minimal state machine

Project description

docs

Read the Docs

tests

Travis-CI Build Status
Coverage Status

package

PyPI Package latest release PyPI Wheel Supported versions Supported implementations

Minimal state machine

  • Free software: BSD license

import fsm

class MyTasks(fsm.FiniteStateMachineMixin):
    """An example to test the state machine.

    Contains transitions to everywhere, nowhere and specific states.
    """

    state_machine = {
        'created': '__all__',
        'pending': ('running',),
        'running': ('success', 'failed'),
        'success': None,
        'failed': ('retry',),
        'retry': ('pending', 'retry'),
    }

    def __init__(self, state):
        """Initialize setting a state."""
        self.state = state

    def on_before_pending(self):
        print("I'm going to a pending state")
In [4]: m = MyTasks(state='created')

In [5]: m.change_state('pending')
I'm going to a pending state
Out[5]: 'pending'
In [6]: m.change_state('failed')  # Let's try to transition to an invalid state
---------------------------------------------------------------------------
InvalidTransition                         Traceback (most recent call last)
<ipython-input-6-71d2461eee74> in <module>()
----> 1 m.change_state('failed')

~/pyfsm/src/fsm/fsm.py in change_state(self, next_state, **kwargs)
    90             msg = "The transition from {0} to {1} is not valid".format(previous_state,
    91                                                                        next_state)
---> 92             raise InvalidTransition(msg)
    93
    94         name = 'pre_{0}'.format(next_state)

InvalidTransition: The transition from pending to failed is not valid

Installation

pip install fsmpy

Usage

  1. Define in a class the state_machine

  2. Initialize state, either with a value, using __init__ or as a django field

  3. Add hooks:

Method

Description

on_before_change_state

Before transitioning to the state

on_change_state

After transitioning to the state, if no failure, runs for every state

pre_<state_name>

Runs before a particular state, where state_name is the specified name in the state_machine

post_<state_name>

Runs after a particular state, where state_name is the specified name in the state_machine

This hooks will receive any extra argument given to change_state

E.g:

Running m.change_state('pending', name='john') will trigger pre_pending(name='john')

Django integration

import fsm
from django.db import models


class MyModel(models.Model, fsm.FiniteStateMachineMixin):
    """An example to test the state machine.

    Contains transitions to everywhere, nowhere and specific states.
    """

    CHOICES = (
        ('created', 'CREATED'),
        ('pending', 'PENDING'),
        ('running', 'RUNNING'),
        ('success', 'SUCCESS'),
        ('failed', 'FAILED'),
        ('retry', 'RETRY'),
    )

    state_machine = {
        'created': '__all__',
        'pending': ('running',),
        'running': ('success', 'failed'),
        'success': None,
        'failed': ('retry',),
        'retry': ('pending', 'retry'),
    }

    state = models.CharField(max_length=30, choices=CHOICES, default='created')

    def on_change_state(self, previous_state, next_state, **kwargs):
        self.save()

Django Rest Framework

If you are using serializers, they usually perform the save, so saving inside on_change_state is not necessary.

One simple solution is to do this:

class MySerializer(serializers.ModelSerializer):

    def update(self, instance, validated_data):
        new_state = validated_data.get('state', instance.state)
        try:
            instance.change_state(new_state)
        except fsm.InvalidTransition:
            raise serializers.ValidationError("Invalid transition")
        instance = super().update(instance, validated_data)
        return instance

Documentation

https://pyfsm.readthedocs.org/

Development

To run the tests run:

tox

Note, to combine the coverage data from all the tox environments run:

Windows

set PYTEST_ADDOPTS=--cov-append
tox

Other

PYTEST_ADDOPTS=--cov-append tox

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

fsmpy-2.1.0.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

fsmpy-2.1.0-py2.py3-none-any.whl (5.8 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file fsmpy-2.1.0.tar.gz.

File metadata

  • Download URL: fsmpy-2.1.0.tar.gz
  • Upload date:
  • Size: 6.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.7.6 Linux/5.4.0-72-generic

File hashes

Hashes for fsmpy-2.1.0.tar.gz
Algorithm Hash digest
SHA256 be81b809d1ce4cf7647f4293897e9656e2e8b12f7f303f5b678ac921c3bbfb4d
MD5 9cdfcc14e460513b19cd52e44c68847f
BLAKE2b-256 25b03f7229c149d2fcf6b93fb42d67e2e22ba023b1f4859b837e2b1d569117de

See more details on using hashes here.

File details

Details for the file fsmpy-2.1.0-py2.py3-none-any.whl.

File metadata

  • Download URL: fsmpy-2.1.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 5.8 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.7.6 Linux/5.4.0-72-generic

File hashes

Hashes for fsmpy-2.1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 fb16c0f5376afa868b1946c90205a2ff8fd877a7d8636e2574b5b6b6823fdd99
MD5 e2dfcc9d794f24453d9196d682f7a002
BLAKE2b-256 51e0f579621301175dfe016dcb7678e83a09ca58e8bb96882d05094d37d78454

See more details on using hashes here.

Supported by

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