API¶
StateMachine¶
- class statemachine.statemachine.StateMachine(model: Any = None, state_field: str = 'state', start_value: Any = None, rtc: bool = True, allow_event_without_transition: bool = False, listeners: List[object] | None = None)[source]¶
- Parameters:
model – An optional external object to store state. See Domain models.
state_field (str) – The model’s field which stores the current state. Default:
state.start_value – An optional start state value if there’s no current state assigned on the Domain models. Default:
None.rtc (bool) – Controls the Processing model. Defaults to
Truethat corresponds to a run-to-completion (RTC) model.allow_event_without_transition – If
Falsewhen an event does not result in a transition, an exceptionTransitionNotAllowedwill be raised. IfTruethe state machine allows triggering events that may not lead to a state Transition, including tolerance to unknown Event triggers. Default:False.listeners – An optional list of objects that provies attributes to be used as callbacks. See Listeners for more details.
- exception TransitionNotAllowed(event: Event, state: State)¶
Shortcut for easy exception handling.
Example:
try: sm.send("an-inexistent-event") except sm.TransitionNotAllowed: pass
- add_listener(*listeners)[source]¶
Add a listener.
Listener are a way to generically add behavior to a StateMachine without changing its internal implementation.
See also
- property current_state: State¶
Get/Set the current State.
This is a low level API, that can be to assign any valid state completely bypassing all the hooks and validations.
- property current_state_value¶
Get/Set the current State value.
This is a low level API, that can be used to assign any valid state value completely bypassing all the hooks and validations.
- events = []¶
- final_states = []¶
- initial_state = None¶
- name = 'StateMachine'¶
- send(event: str, *args, **kwargs)[source]¶
Send an Event to the state machine.
See also
See: Triggering events.
- states = []¶
- states_map = {}¶
State¶
See also
States reference.
- class statemachine.state.State(name: str = '', value: Any = None, initial: bool = False, final: bool = False, enter: Any = None, exit: Any = None)[source]¶
A State in a StateMachine describes a particular behavior of the machine. When we say that a machine is “in” a state, it means that the machine behaves in the way that state describes.
- Parameters:
name –
A human-readable representation of the state. Default is derived from the name of the variable assigned to the state machine class. The name is derived from the id using this logic:
name = id.replace("_", " ").capitalize()
value – A specific value to the storage and retrieval of states. If specified, you can use It to map a more friendly representation to a low-level value.
initial – Set
Trueif theStateis the initial one. There must be one and only one initial state in a statemachine. Defaults toFalse.final – Set
Trueif represents a final state. A machine can have optionally many final states. Final states have no Transition starting from It. Defaults toFalse.enter – One or more callbacks assigned to be executed when the state is entered. See Actions.
exit – One or more callbacks assigned to be executed when the state is exited. See Actions.
State is a core component on how this library implements an expressive API to declare StateMachines.
>>> from statemachine import State
Given a few states…
>>> draft = State("Draft", initial=True)
>>> producing = State("Producing")
>>> closed = State('Closed', final=True)
Transitions are declared using the
State.to()orState.from_()(reversed) methods.>>> draft.to(producing) TransitionList([Transition(State('Draft', ...
The result is a TransitionList. Don’t worry about this internal class. But the good thing is that it implements the
ORoperator to combine transitions, so you can use the|syntax to compound a list of transitions and assign to the same event.You can declare all transitions for a state in one single line …
>>> transitions = draft.to(draft) | producing.to(closed)
… and you can append additional transitions for a state to previous definitions.
>>> transitions |= closed.to(draft)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Producing', 'Closed'), ('Closed', 'Draft')]
There are handy shortcuts that you can use to express this same set of transitions.
The first one,
draft.to(draft), is also called a Self transition, and can be expressed using an alternative syntax:>>> draft.to.itself() TransitionList([Transition(State('Draft', ...
You can even pass a list of target states to declare at once all transitions starting from the same state.
>>> transitions = draft.to(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Draft'), ('Draft', 'Producing'), ('Draft', 'Closed')]
Sometimes it’s easier to use the
State.from_()method:>>> transitions = closed.from_(draft, producing, closed)
>>> [(t.source.name, t.target.name) for t in transitions] [('Draft', 'Closed'), ('Producing', 'Closed'), ('Closed', 'Closed')]
- property from_: _FromState¶
Create transitions from the given target states (reversed).
- property to: _ToState¶
Create transitions to the given target states.
States (class)¶
- class statemachine.states.States(states: Dict[str, State] | None = None)[source]
A class representing a collection of State objects.
Helps creating StateMachine’s State definitions from other sources, like an
Enumclass, usingStates.from_enum().>>> states_def = [('open', {'initial': True}), ('closed', {'final': True})]
>>> from statemachine import StateMachine >>> class SM(StateMachine): ... ... states = States({ ... name: State(**params) for name, params in states_def ... }) ... ... close = states.open.to(states.closed)
And states can be used as usual.
>>> sm = SM() >>> sm.send("close") >>> sm.current_state.id 'closed'
- __init__(states: Dict[str, State] | None = None) None[source]
Initializes a new instance of the States class.
- Parameters:
states – A dictionary mapping keys as
State.idand values State instances.- Returns:
None.
- classmethod from_enum(enum_type: Type[Enum], initial, final=None, use_enum_instance: bool = False)[source]
Creates a new instance of the
Statesclass from an enumeration.Consider an
Enumtype that declares our expected states:>>> class Status(Enum): ... pending = 1 ... completed = 2
A StateMachine that uses this enum can be declared as follows:
>>> from statemachine import StateMachine >>> class ApprovalMachine(StateMachine): ... ... _ = States.from_enum(Status, initial=Status.pending, final=Status.completed) ... ... finish = _.pending.to(_.completed) ... ... def on_enter_completed(self): ... print("Completed!")
Tip
When you assign the result of
States.from_enumto a class-level variable in your StateMachine, you’re all set. You can use any name for this variable. In this example, we used_to show that the name doesn’t matter. The metaclass will inspect the variable of type States (class) and automatically assign the inner State instances to the state machine.Everything else is similar, the
Enumis only used to declare the State instances.>>> sm = ApprovalMachine()
>>> sm.pending.is_active True
>>> sm.send("finish") Completed!
>>> sm.completed.is_active True
>>> sm.current_state_value 2
If you need to use the enum instance as the state value, you can set the
use_enum_instance=True:>>> states = States.from_enum(Status, initial=Status.pending, use_enum_instance=True) >>> states.completed.value <Status.completed: 2>
Deprecated since version 2.3.3: On the next major release,
use_enum_instance=Truewill be the default.- Parameters:
enum_type – An enumeration containing the states of the machine.
initial – The initial state of the machine.
final – A set of final states of the machine.
use_enum_instance – If
True, the value of the state will be the enum item instance, otherwise the enum item value. Defaults toFalse.
- Returns:
A new instance of the States (class).
- items()[source]
Returns a view object of the states, with pairs of
(State.id, State).- Parameters:
None.
- Returns:
A view object of the items in the the instance.
Transition¶
See also
Transitions reference.
- class statemachine.transition.Transition(source: State, target: State, event=None, internal=False, validators=None, cond=None, unless=None, on=None, before=None, after=None)[source]¶
A transition holds reference to the source and target state.
- Parameters:
source (State) – The origin state of the transition.
target (State) – The target state of the transition.
event (Optional[Union[str, List[str]]]) – List of designators of events that trigger this transition. Can be either a list of strings, or a space-separated string list of event descriptors.
internal (bool) – Is the transition internal or external? Internal transitions don’t execute the state entry/exit actions. Default
False.validators (Optional[Union[str, Callable, List[Callable]]]) – The validation callbacks to be invoked before the transition is executed.
cond (Optional[Union[str, Callable, List[Callable]]]) – The condition callbacks to be invoked before the transition is executed that should evaluate to True.
unless (Optional[Union[str, Callable, List[Callable]]]) – The condition callbacks to be invoked if the cond is False before the transition is executed.
on (Optional[Union[str, Callable, List[Callable]]]) – The callbacks to be invoked when the transition is executed.
before (Optional[Union[str, Callable, List[Callable]]]) – The callbacks to be invoked before the transition is executed.
after (Optional[Union[str, Callable, List[Callable]]]) – The callbacks to be invoked after the transition is executed.
TransitionList¶
- class statemachine.transition_list.TransitionList(transitions: Iterable[Transition] | None = None)[source]¶
A list-like container of Transitions with callback functions.
- __getitem__(index: int) Transition[source]¶
Returns the Transition at the specified
index.- Parameters:
index – The index of the transition.
- Returns:
The Transition at the specified index.
- __init__(transitions: Iterable[Transition] | None = None)[source]¶
- Parameters:
transitions – An iterable of Transition objects. Defaults to None.
- __len__()[source]¶
Returns the number of transitions in the TransitionList instance.
- Returns:
The number of transitions.
- __or__(other: TransitionList | Iterable)[source]¶
Return a new TransitionList that combines the transitions of this TransitionList with another TransitionList or iterable.
- Parameters:
other – Another TransitionList or iterable of Transition objects.
- Returns:
- A new TransitionList object that combines the
transitions of this TransitionList with other.
- Return type:
- __repr__()[source]¶
Return a string representation of the TransitionList.
- add_event(event: str)[source]¶
Adds an event to all transitions in the TransitionList instance.
- Parameters:
event – The name of the event to be added.
- add_transitions(transition: Transition | TransitionList | Iterable)[source]¶
Adds one or more transitions to the TransitionList instance.
- Parameters:
transition – A sequence of transitions or a TransitionList instance.
- Returns:
The updated TransitionList instance.
- property unique_events: List[Event]¶
Returns a list of unique event names across all transitions in the TransitionList instance.
- Returns:
A list of unique event names.
Model¶
See also
Domain models reference.
- class statemachine.model.Model[source]¶
- state¶
Holds the current State value of the StateMachine.
TriggerData¶
Event¶
- class statemachine.event.Event(transitions: str | TransitionList | None = None, id: str | None = None, name: str | None = None, _sm: StateMachine | None = None)[source]¶
An event triggers a signal that something has happened.
They are sent to a state machine and allow the state machine to react.
An event starts a Transition, which can be thought of as a “cause” that initiates a change in the state of the system.
See also Events.
- __call__(*args, **kwargs)[source]¶
Send this event to the current state machine.
Triggering an event on a state machine means invoking or sending a signal, initiating the process that may result in executing a transition.
- id: str¶
The event identifier.
- name: str¶
The event name.
EventData¶
- class statemachine.event_data.EventData(trigger_data: statemachine.event_data.TriggerData, transition: 'Transition', result: 'Any | None' = None, executed: bool = False)[source]¶
- source: State¶
The State which StateMachine was in when the Event started.
- state: State¶
The current State of the StateMachine.
- target: State¶
The destination State of the Transition.
- transition: Transition¶
The Transition instance that was activated by the Event.
- trigger_data: TriggerData¶
The TriggerData of the Event.