State Machine

State Machine module

This module contains the StateMachine class.

This StateMachine class is designed to do 3 specific things:

  • Allow only transitions that are valid for the current state (enforced by the State object).
  • Pass events to the State and let the state handle them. You can pass both transition events as well as events that should trigger something, which you can define yourself. The State class can be extended with handle_...() functions that handle these specific events. You should be careful not to name your transitions the same as your handle_...() functions because an exception will be raised if they collide.
  • Pass actions to the State and let the state handle them. The State class can be extended with action_...() functions that do these specific actions.

The state machine’s __init__() takes a dict argument that contains all states the state machine should support.

The states can have ‘on_enter’ and ‘on_leave’ definitions, which are lists of actions to do when the state is entered or left respectively. These actions have to be defined in the State object for this to work. There should also be a list of ‘allowed_actions’ array defined in each state definition, this array should contain the action names without the prefix ‘action_’. The reason the ‘action_’ is not prefixed is that the prefix string can be changed in a class extension, to e.g.: ‘do_’.

class otrbot.statemachine.statemachine.StateMachine(states_object, ctxt)

This class in not supposed to be used directly, you should extend this class and add the application specific functions to it.

You will most likely require your own definition of the State class as well, to override the definition of the State class the state machine uses, you will need to override the STATE_OBJECT in your state machine class extension.

You should also use super() to initialise the StateMachine object, you will need to pass some arguments too, see below.

Initialise the StateMachine class.

Parameters:
  • states_object (dict) – A dict containing all possible states, its transitions, actions, ‘on_enter’ and ‘on_leave’ actions
  • ctxt (SharedContext) – A shared context that contains the current state context data
Raises:

StateDoesNotExist – Indicates that the state you chose to be the initial state is not in the states_object

STATE_OBJECT

alias of State

action(action, *args, **kwargs)

Run an action using the current state.

Parameters:
  • action (str) – String containing the function name of the action you want to execute
  • args (set) – Arbitrary positional arguments to pass to the action
  • kwargs (dict) – Arbitrary keyword arguments to pass to the action

The action will be handled by the current state which is an instance of State. See State.action() for more information.

state

Return current state.

Returns State:The instance of the current State object.
handle(event, *args, **kwargs)

Handle an event using the current state.

Parameters:
  • event (str) – String containing the event name of the event you want handled by the state.
  • args (set) – Arbitrary positional arguments to pass to the action
  • kwargs (dict) – Arbitrary keyword arguments to pass to the action

The event will be handled by the current state which is an instance of State. See State.handle() for more information.

ctxt

Return the current context.

Returns SharedContext:
 The shared context used by the state machine

State module

This module contains the State class for the StateMachine.

You can extend this class to add action_...() and handle_...() functions. To let the StateMachine use your own custom state class, you need to extend the StateMachine class and override the StateMachine.STATE_OBJECT constant.

class otrbot.statemachine.state.State(name, states_object, ctxt)

This class in not supposed to be used directly, you should extend this class and add the application specific functions to it.

To override the definition of the State classthe state machine uses, you will need to override the STATE_OBJECT in your state machine class extension.

You should also use super() to initialise the State object, you will need to pass some arguments too, see below.

If you want to define different prefixes for the action_...() or handle_...() functions, e.g.: do_...(), you can override the PREFIX_ACTION or the PREFIX_HANDLE class constants.

Initialise the state.

Parameters:
  • name (str) – The name of the current state
  • states_object (dict) – A dict containing all possible states, its transitions, actions, ‘on_enter’ and ‘on_leave’ actions
  • ctxt (SharedContext) – A shared context that contains the current state context data
on_enter()

When the state is entered the “on_enter” actions will be executed.

on_leave()

When the state is left the “on_leave” actions will be executed.

action(action, *args, **kwargs)

Run an action that is defined in the State and prefixed by PREFIX_ACTION.

Parameters:
  • action (str) – Name of the action to run (without prefix)
  • args (set) – Arbitrary positional arguments to pass to the action
  • kwargs (dict) – Arbitrary keyword arguments to pass to the action
Raises:
  • NotImplementedError – If the requested action is not implemented
  • ActionNotAllowed – If the action is not allowed within the current state.
handle(event, *args, **kwargs)

Handle events passed to the State object.

There are 2 types of events that can be handled by state objects:

  • Transition events, which should cause a transition to another state if the transition is allowed.
  • Events that should be handled by the state without transitioning.
Parameters:
  • event (str) – Event name.
  • args (set) – Arbitrary positional arguments to pass to the action
  • kwargs (dict) – Arbitrary keyword arguments to pass to the action
Raises:

CannotHandle – If there is no way to handle the event.

possible_actions

Return all actions that are defined in the State object.

The results of the introspection are cached, if you dynamically modify the object after getting this property the changes will not be reflected by the result.

Returns set:All actions defined in this State object.
transitions

Return transition

Returns dict:All transitions supported by this State object.
ctxt

Return the current context.

Returns SharedContext:
 The shared context used by the state object

Shared Context module

This module contains the SharedContext class.

This SharedContext hold all the data that needs to be shared between the State and the StateMachine objects.

class otrbot.statemachine.context.SharedContext(state=None)

A shared context for the state machine and the state.

Parameters:state (str) – The curent StateMachine state