Skip to main content

Annotation-driven, Thread-safe, transition-focused Finite State Machines.

Project description

Fineas

State machine implementations that are:

  • Simple
  • Decorator-Based
  • Transition-Focused
  • Thread-Safe
import fineas


@fineas.state_machine(initial_state='new', store_history=True)
class TestMachine:
   def __init__(self):
      self.config = None

   @fineas.transition(
      source=['new', 'invalid_configuration'],
      dest='configured',
      error_state='invalid_configuration')
   def got_config(self, config):
      # validate config
      self.config = config

   @fineas.transition(source='configured', dest='scheduled')
   def ready(self):
      pass

   @fineas.transition(
      source='scheduled',
      dest='scheduled',
      error_state='canceled',
      failed_state='retry')
   def run(self, fail_transition):
      # do work
      status = self._do_work()

      if not status:
         fail_transition()

   @fineas.transition(
      source='retry',
      dest='run',
      error_state='canceled',
      failed_state='too_many_failures'
   )
   def try_again(self, times, fail_transition):
      for i in range(times):
         if self._do_work():
            return
      fail_transition()

   @fineas.transition(
      source=['retry', 'too_many_failures'],
      dest='cancelled'
   )
   def abandon(self):
      pass

   @fineas.transition(
      source='too_many_failures',
      dest='configured'
   )
   def reconfigure(self, config):
      self.config = config

   def _do_work(self):
      pass


t = TestMachine()
t.got_config(None)
t.ready()
try:
   t.run()
except fineas.TransitionException as t:
   # handle trying to transition from an invalid state
   pass
t.try_again(3)
t.abandon()


print(t.history)

print(t.state)

Quickstart

  1. Decorate a class with @fineas.state_machine(initial_state='new'). You must pass a value for initial_state.
  2. Define a method that implements the work required to transition form one or more source states to a single destination state. Decorate that method with @fineas.transition(source='new', dest='ready').
  3. That's it! Each instance of your decorated class is its own state machine. You may check its current state with its state attribute, and, if you've enabled record_history, you can access its transition history with its history attribute.

Overview

To turn each instance of a class into a state machine, simply decorate it with @fineas.state_machine(). You must pass an initial_state value to @fineas.state_machine(). This will be the state every instance of your type starts in. You can also enable recording state transitions with the record_history flag; this is useful while developing finite state machines.

Every transition in your state machine is represented by a method inside the class you decorated with @fineas.state_machihe(). To turn a method into a transition, decorate it with @fineas.transition() and supply one or more source states for the transition, and exactly one destination state. You can also define a state to transition to if an exception is raised inside your method (there is also a flag to enable or disable re-raising that exception). If your method accepts a parameter named fail_transition, its value will be a callable your method can invoke to cause the transition to fail while still allowing your method to return a value to its caller. You may also pass a fail_state parameter to the decorator, and when fail_transition is invoked, your instance will be transitioned to the given state.

When any method decorated with @fineas.transistion() is called, the following steps happen:

  1. Acquire a lock over the receiving instance.
  2. Fineas validates that the receiving instance's state is in the sources passed to @fineas.transition()
    • If it is not, a TransitionException is raised.
  3. The decorated method is invoked, passing fail_transistion if able.
  4. If the decorated method raises an exception:
    • If error_state was passed, immediately transition to that state.
    • If reraise_error is True, re-raise the exception.
    • Return.
  5. If fail_transition was called:
    • If 'fail_state' was passed, immediately transition to that state.
  6. If no exception was raised and fail_transition was not called, transition to the destination state and return the value returned by the decorated method.

Requirements

Python 3.6 or higher

wrapt 1.12.x

Release Notes

0.9 (07 March, 2021):

  • Initial Release

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

Fineas-0.1.0.tar.gz (4.8 kB view details)

Uploaded Source

Built Distributions

fineas-0.1.0-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

Fineas-0.1.0-py3-none-any.whl (5.3 kB view details)

Uploaded Python 3

File details

Details for the file Fineas-0.1.0.tar.gz.

File metadata

  • Download URL: Fineas-0.1.0.tar.gz
  • Upload date:
  • Size: 4.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.1

File hashes

Hashes for Fineas-0.1.0.tar.gz
Algorithm Hash digest
SHA256 735891da0cb19aa345a1608e6312c7b95ab538e70bdbbaf3ecf57e3c102b1a6d
MD5 5c8d1a521bac424a2d5653742a65cbf8
BLAKE2b-256 c14cd6b016622996c0ec850b518bce14212f2c6afca8f209ea63904d0360e9dc

See more details on using hashes here.

File details

Details for the file fineas-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fineas-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.10.2 Windows/10

File hashes

Hashes for fineas-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 735e7ce2ff59b9aac8f57febd8d965aadf8bb89d1803656cfe2782aaae36a903
MD5 d4b5bb29b4e0994c0eb73d6e4a1e4a13
BLAKE2b-256 6d0c48ec3e1010903fefaffe82e398a4664f80a6d3a8f9f8107cfc7d403bf89d

See more details on using hashes here.

File details

Details for the file Fineas-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: Fineas-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.1

File hashes

Hashes for Fineas-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b83727cf0f055c04a01cc171721a5d9e6626c7344821a7b86a04219cdf09e39e
MD5 ddf471d8f0bbe4b4eb5f91e59473d6cf
BLAKE2b-256 df0fb8994e42444dab6e685ab4a51c13bb23ab334ff145ad9e8cc09f614006d5

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 Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page