Welcome to pyeds’s documentation!

Indices and tables

Source

Python Event Driven System (PyEDS)

This package provides a means to efficiently write finite state machines (FSM) by hand. The focus was to make the API as simplest as possible since no GUI tools are included to define a FSM.

Module details

Created on Jul 7, 2017

Finite State Machine (FSM)

A finite-state machine (FSM) is a mathematical model of computation. It is an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some external events; the change from one state to another is called a state transition. An FSM is defined by a list of its states, its initial state, and the conditions for each transition.

Event

An event is a notable occurrence at a particular point in time. Events can, but do not necessarily, cause state transitions from one state to another in state machines.

An event can have associated parameters, allowing the event to convey not only the occurrence but also quantitative information about the occurrence.

An event in PyEDS is instanced using class Event.

State

A state is a description of the status of a system that is waiting to execute a transition.

State transition

Switching from one state to another is called state transition. A transition is a set of actions to be executed when a condition is fulfilled or when an event is received.

Module details

Created on Jul 7, 2017

class pyeds.fsm.After(after, event_name)

Send an event to current state machine after a specified number of seconds.

This is a timer object that will send the specified event after period of elapsed time. The timer will start counting at the time of creation.

Args:
  • after (float): Time period in seconds.

  • event_name (str): Name of event.

Example:

In order to send the event called ‘blink’ to itself after 10 seconds do:

fsm.After(10.0, 'blink')
cancel()

Cancel a running timer

handler()

Timeout handler method.

start()

Start the timer.

Use this method to start a cancelled timer or a timer that has been expired.

class pyeds.fsm.DeclareState(state_machine_cls)

This is a decorator which declares a state for a state machine.

Use this decorator class to declare states for a state machine.

Args:
  • state_machine_cls (subclass of StateMachine): A state machine for which the state is declared for.

Raises:
  • AssertError:
    • When state_machine_cls is class StateMachine

    • When state_machine_cls is not a subclass of StateMachine

    • When decorated class is class State

    • When decorated class is not a subclass of State

pyeds.fsm.EVENT_HANDLER_PREFIX = 'on_'

This is default event handler prefix.

This string is prefixed with event name to form event handler name which will be called to process the event.

class pyeds.fsm.Event(name=None)

An event is the only means of communication between state machines. Each event carries name. Based on the event name a handler will be called from current state class which has the same name.

When an event is created and sent to a state machine it’s name is used to decide which method in current state instance should be invoked. The state machine takes the name of the event, it prepends text on_ to the name string and then it looks up to event handler method.

Example:

If an event named toggle is created and sent to a state machine, the target state machine will lookup for a method named on_toggle in the current state instance.

Since the event name directly impacts which state instance method will be called the name of events must follow the Python identifier naming rules.

The associated parameters with an event are:
  • Name of the event: as given to constructor or implicitly defined using class name.

  • Owner of event: state machine which generated this event or None if the event was generated outside a state machine context.

Args:
  • name (str, optional): Name of the event. When not given the event will take the name of the derived Event class and convert it to appropriate format.

execute(handler)

Event handler executor

This method is called by state machine dispatcher to execute event handler in a state.

By default it just delivers itself to event handler:

return handler(self)
format_name(name)

Resource, format the name.

Used by resource instance to format the name of Event. It will convert Event names from CamelCase to camel_case format.

Example:

class MySpecialEvent(fsm.Event):
    pass

new_event = MySpecialEvent() # This event is implicitly
                             # called 'my_special_event'
Args:
  • name (str): Unformatted name of the Event.

Returns:
  • str: Formatted name of the Event.

send(state_machine=None)

Send this event to state machine.

Args:
  • state_machine (None): Send the event to the state machine who created this event. This argument is invalid in case when the owner of event is not a state machine.

  • state_machine (StateMachine): State machine object.

  • state_machine (str): State machine name.

  • state_machine (Channel): Event channel.

Raises:
  • ValueError: When state_machine argument is not supported.

  • LookupError: When state_machine argument is str and there is no state machine with that name.

class pyeds.fsm.Every(every, event_name)

Send an event to current state machine every time a specified number of seconds passes.

This is a timer object that will send the specified event every period of elapsed time. The timer will start counting at the time of creation.

Args:
  • every (float): Time period in seconds.

  • event_name (str): Name of event.

Example:

In order to send the event called ‘blink’ to itself every 10 seconds do:

fsm.Every(10.0, 'blink')
handler()

Timeout handler method.

class pyeds.fsm.Resource(category='obj', name=None, owner=None, is_unique=False, releaser=None)

Resource which is associated with an object.

Args:
  • category (str, optional): Is the category of the resource. The default value is obj.

  • name (str, optional): Is the name of the resource. The default value is None which means that the name will be defined by resource class name.

  • owner (object, optional): Object which is the owner of the resource. The default value is None.

  • is_unique (bool, optional): Defines if this resource should be unique in Resource management. By being unique means that a resource in a given category is the only resource with the specified name. The default value is False.

  • releaser (function): A function which will be called when this resource is being removed.

Attributes:
  • resources (dict): Dictionary contains all resources managed by Resource. It contains additional information like category and name for fast fetching of resource objects.

classmethod add_resource(resource)

Add a resource to resource management.

Args:
  • resource (:obj:’Resource’): Add derived class of Resource to resource management.

Raises:
  • ValueError: When this resource is not a unique resource and is_unique is True.

classmethod filter_resources(category=None, owner=None, name=None)

Get resources filtered by category, owner and name.

Args:
  • category (str, optional): Is the category of the resource. Default is None which means to match any category.

  • owner (object, optional): Object which is the owner of the resource. Default is None which means to match any owner.

  • name (str, optional): Is the name of the resource. Default is None which means to match any name.

Returns:
  • list of Resource: A list containing all resources that match category, owner and name constraints.

classmethod get_resources(category, name)

Get resources specified by category and name.

Args:
  • category (str): Is the category of the resource.

  • name (str): Is the name of the resource.

Returns:
  • list of Resource: A list containing all resources that match category and name constraints.

classmethod remove_all_resources(owner)

Remove all resources associated with an owner.

Args:
  • owner (object): Object which is the owner of the resource.

classmethod remove_resource(resource)

Remove a resource from resource management.

In the process of removal the resource releaser method will be called if it was specified in the constructor initialization.

Args:
  • resource (Resource): A resource to be removed from resource management.

Raises:
  • LookupError: When a resource is not registered to resource management.

class pyeds.fsm.State

This class implements a state.

Each state is represented by a class derived from this class. Every method in state class may handle one particular event. To declare the state, a class must be decorated with DeclareState decorator which requires a subclass of StateMachine as an argument. This decorator binds the state class to the specific FSM class. Also, the new state class must be a subclass of State class:

@fsm.DeclareState(MyFsm)
class MyState(fsm.State):
    pass

Event handler has the following signature:

def on_event_name(self, event):

Where on_event_name corresponds to event name. Event handler gets the event (Event) which has caused this call.

Transitions are started by returning target state class in an event handler:

def on_some_event(self, event):
    do_some_stuff()
    return SomeOtherState # Note: return a class object,
                          # not instance object

Objects created in the current state may be local or non-local to the state. When an object is local it will exist only while the state machine is in the current state. When state machine transitions to any state ( including the current one) all object local to current state will be deleted.

Attributes:
  • super_state (State): The super state of this state. By default is set to None which means that this state has no super state.

property logger

Logger: Logger of the state machine.

on_entry()

State “entry” event handler

This handler gets called by dispatcher when state machine enters this state.

Note:

This event handler does not have event argument.

on_exit()

State “exit” event handler

This handler gets called by dispatcher when state machine exits this state.

Note:

This event handler does not have event argument.

on_init()

State “initialization” event handler

This handler gets called by dispatcher when state machine enters this state and wants to initialize it.

Note:

This event handler does not have event argument.

on_unhandled_event(event)

Un-handled event handler

This handler gets executed in case the state does not handle the event. By default this handler only logs the un-handled event.

Args:
  • event (Event): Event which is not handled.

set_local(resource)

Set a resource as local to this state.

Local object exist only while the state machine is in current state.

Args:
  • resource (Resource): Resource which will be local to this state.

property sm

StateMachine: The state machine who is owner of this state.

class pyeds.fsm.StateMachine(queue_size=64, name=None)

This class implements a state machine.

This class is a controller class of state machine.

State machine instance is the entry point of a state machine which is used to receive events and do the transitions between states. Each state machine must declare it’s own subclass of StateMachine. The simplest way is to just declare an empty class which inherits the class StateMachine:

from pyeds import fsm

class MyFsm(fsm.StateMachine):
    pass
Args:
  • queue_size (int, optional): Is an integer specifying what is the maximum event queue size. If this argument is -1 then unlimited queue size will be used. Default is 64.

  • name (str, optional): Is a string specifying the state machine name. The default value is None which means that the class name is taken as the state machine name.

Attributes:
  • init_state_cls (State, optional): Initial state class. If init_state_cls attribute is set then that state will be initial state. Default is None which means the first declared (registered) state is initial state.

  • logger (Logger, optional): Logger instance used by the state machine. Default is to use logging.getLogger(None).

  • should_autostart (bool, optional): Should machine start at initialization? Default is True.

Raises:
  • AttributeError: If this state machine has no states declared with DeclareState decorator.

  • ValueError: If init_state_cls is not a declared state of this state machine.

Note:

The subclass must call the constructor method.

property depth

int: The depth of state machine states hierarchy

do_start()

Explicitly start the state machine

If attribute should_autostart is False then after the creating the class the state machine will start executing only after calling this function.

do_terminate(timeout=None)

Pend termination of the state machine.

Put a special event into to queue buffer which will signal the state machine to terminate.

Args:
  • timeout (float, optional): When specified it will wait up to timeout seconds. Default is None which means to block indefinitely.

Raises:
  • BufferError: Raised when queue buffer is full and timeout has passed (if given), otherwise, it raises it immediately when full.

Note:

After calling this method the state machine may still run. Use wait() to wait for state machine until it terminates.

event_loop()

Event loop

This method executes the event looper.

Raises:
  • LookupError: If a state returns invalid transition class.

instance_of(state_cls)

Get the instance of state class

Args:
  • state_cls (State): State class

Returns:
  • State: Instance of state_cls class.

Raises:
  • LookupError: If state_cls is not a registered state of the state machine.

on_exception(exc, state, event, msg)

Gets called when un-handled state exception has occurred

Args:
  • exc (Exception): Holds state exception.

  • state (State): State instance where the exception originates.

  • event (Event): Event which was processed in the state.

  • msg (str): Message associated with the exception.

on_start()

Gets called by state machine just before the machine starts

on_terminate()

Gets called by state machine just before the termination

send(event, block=True, timeout=None)

Send an event to the state machine.

The event is put to state machine queue and then the event_loop() method will process the queued event.

Args:
  • event (Event): Event object to send to this machine.

  • block (bool, optional): If event queue is full should this method block? Default is True which means the method will block.

  • timeout (float, optional): If block is True then wait up to timeout seconds. This argument is disregarded when block is False. Default is None which means to block indefinitely.

Raises:
  • BufferError: Raised when queue buffer is full and timeout has passed (if given), otherwise, it raises it immediately when full.

property state

State: Instance of current state

property states

list of str: List of names of registered states

wait(timeout=None)

Wait until the state machine terminates.

Args:
  • timeout (float, optional): How many seconds to wait for termination. The default is None which means to wait indefinitely.

pyeds.fsm.current()

Returns the currently executing state machine.

Returns:
  • StateMachine: Which state machine is currently executing.

  • None: When this function is called outside of a state machine code context.

Generic library

This module contains definitions for generic usage.

Module details

Created on Jul 22, 2017

class pyeds.lib.Immutable

Immutable object

An immutable object (unchangeable object) is an object whose state cannot be modified after it is created.

When trying to modify an attribute that is already set the AttributeError will be raised.

Coordinator

Coordinator provides interface for following classes:
  • Task: A class that provides simultaneous processing.

  • Timer: A time delay.

  • Queue: A data queue.

Following functions are provided:
  • current: Returns the current thread of execution.

By default the Python standard library is used for this functionality.

Module details

Created on Jul 22, 2017

class pyeds.coordinator.Provider(Task, Timer, Lock, Queue, current)
property Lock

Alias for field number 2

property Queue

Alias for field number 3

property Task

Alias for field number 0

property Timer

Alias for field number 1

property current

Alias for field number 4

class pyeds.coordinator.StdQueue(maxsize=0)
put(item, block=False, timeout=None)

Put an item into the queue.

If optional args ‘block’ is true and ‘timeout’ is None (the default), block if necessary until a free slot is available. If ‘timeout’ is a non-negative number, it blocks at most ‘timeout’ seconds and raises the Full exception if no free slot was available within that time. Otherwise (‘block’ is false), put an item on the queue if a free slot is immediately available, else raise the Full exception (‘timeout’ is ignored in that case).

class pyeds.coordinator.StdTask(target, name)
class pyeds.coordinator.StdTimer(interval, handler)
pyeds.coordinator.set_provider(name)

Choose the default provider.

Args:
  • name (str): Name of provider.

Raises:
  • LookupError: When a provider with given name is not registered.