Skip to content

Overview

PERSEUS has its own implementation of a state machine, available in perseus.state_machine. Every project holds its own state machine, which allows for fully customizable project workflows for every single project.

The states inside a state machine are represented by a string id which connects to a specific state in the custom states directory.

To describe the behavior of a state machine, you need to define a path. A path can contain three different elements:

  • A single state, represented by the id and possibly a condition
  • A choice, which holds multiple paths where one is selected based on the conditions
  • A fork, which holds multiple paths where all paths are processed simultaneously

To allow for state transitions, states can fire events, possibly containing one or more values to match conditions.

To save a state machine in the database, PERSEUS provides a JSON encoder as well as a JSON decoder:

import json
from perseus.state_machine.StateMachine import StateMachine
from perseus.state_machine.StateMachineJSONDecoder import StateMachineJSONDecoder
from perseus.state_machine.StateMachineJSONEncoder import StateMachineJSONEncoder
...
state_machine: StateMachine = StateMachine(...)
state_machine_json: str = json.dumps(state_machine, cls=StateMachineJSONEncoder)
another_state_machine: StateMachine = json.loads(state_machine_json, cls=StateMachineJSONDecoder)

Please notice the following limitations necessary to ensure a proper working state machine:

  • Paths, choices and forks MUST contain at least one element
  • Choices and forks SHOULD contain two or more elements
  • The first element of a path MUST be a state
  • The first element in the top-level path of a state machine MUST NOT have any condition other than None
  • The first elements in paths of a fork MUST NOT have any condition other than None
  • The first elements in paths of a choice MUST NOT overlap and MUST be unique
  • Choices and forks MUST NOT have any condition other than None themselves
  • Choices and / or forks MUST have a state in between them and MUST NOT be connected directly