# <a name="transitions-module"></a> transitions
[](https://github.com/pytransitions/transitions)
[](https://github.com/pytransitions/transitions/actions?query=workflow%3Apytest)
[](https://coveralls.io/github/pytransitions/transitions?branch=master)
[](https://pypi.org/project/transitions)
[](https://copr.fedorainfracloud.org/coprs/aleneum/python-transitions/)
[](https://github.com/pytransitions/transitions/compare/0.9.2...master)
[](LICENSE)
[](https://mybinder.org/v2/gh/pytransitions/transitions/master?filepath=examples%2FPlayground.ipynb)
<!-- [](https://github.com/pytransitions/transitions) -->
<!--[](Link)-->
A lightweight, object-oriented state machine implementation in Python with many extensions. Compatible with Python 2.7+ and 3.0+.
## Installation
pip install transitions
... or clone the repo from GitHub and then:
python setup.py install
## Table of Contents
- [Quickstart](#quickstart)
- [Non-Quickstart](#the-non-quickstart)
- [Some key concepts](#some-key-concepts)
- [Basic initialization](#basic-initialization)
- [States](#states)
- [Callbacks](#state-callbacks)
- [Checking state](#checking-state)
- [Enumerations](#enum-state)
- [Transitions](#transitions)
- [Triggering a transition](#triggers)
- [Automatic transitions](#automatic-transitions-for-all-states)
- [Transitioning from multiple states](#transitioning-from-multiple-states)
- [Reflexive transitions from multiple states](#reflexive-from-multiple-states)
- [Internal transitions](#internal-transitions)
- [Ordered transitions](#ordered-transitions)
- [Queued transitions](#queued-transitions)
- [Conditional transitions](#conditional-transitions)
- [Check transitions](#check-transitions)
- [Callbacks](#transition-callbacks)
- [Callable resolution](#resolution)
- [Callback execution order](#execution-order)
- [Passing data](#passing-data)
- [Alternative initialization patterns](#alternative-initialization-patterns)
- [Logging](#logging)
- [(Re-)Storing machine instances](#restoring)
- [Typing support](#typing-support)
- [Extensions](#extensions)
- [Hierarchical State Machine](#hsm)
- [Diagrams](#diagrams)
- [Threading](#threading)
- [Async](#async)
- [State features](#state-features)
- [Django](#django-support)
- [Bug reports etc.](#bug-reports)
## Quickstart
They say [a good example is worth](https://www.google.com/webhp?ie=UTF-8#q=%22a+good+example+is+worth%22&start=20) 100 pages of API documentation, a million directives, or a thousand words.
Well, "they" probably lie... but here's an example anyway:
```python
from transitions import Machine
import random
class NarcolepticSuperhero(object):
# Define some states. Most of the time, narcoleptic superheroes are just like
# everyone else. Except for...
states = ['asleep', 'hanging out', 'hungry', 'sweaty', 'saving the world']
def __init__(self, name):
# No anonymous superheroes on my watch! Every narcoleptic superhero gets
# a name. Any name at all. SleepyMan. SlumberGirl. You get the idea.
self.name = name
# What have we accomplished today?
self.kittens_rescued = 0
# Initialize the state machine
self.machine = Machine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
# Add some transitions. We could also define these using a static list of
# dictionaries, as we did with states above, and then pass the list to
# the Machine initializer as the transitions= argument.
# At some point, every superhero must rise and shine.
self.machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out')
# Superheroes need to keep in shape.
self.machine.add_transition('work_out', 'hanging out', 'hungry')
# Those calories won't replenish themselves!
self.machine.add_transition('eat', 'hungry', 'hanging out')
# Superheroes are always on call. ALWAYS. But they're not always
# dressed in work-appropriate clothing.
self.machine.add_transition('distress_call', '*', 'saving the world',
before='change_into_super_secret_costume')
# When they get off work, they're all sweaty and disgusting. But before
# they do anything else, they have to meticulously log their latest
# escapades. Because the legal department says so.
self.machine.add_transition('complete_mission', 'saving the world', 'sweaty',
after='update_journal')
# Sweat is a disorder that can be remedied with water.
# Unless you've had a particularly long day, in which case... bed time!
self.machine.add_transition('clean_up', 'sweaty', 'asleep', conditions=['is_exhausted'])
self.machine.add_transition('clean_up', 'sweaty', 'hanging out')
# Our NarcolepticSuperhero can fall asleep at pretty much any time.
self.machine.add_transition('nap', '*', 'asleep')
def update_journal(self):
""" Dear Diary, today I saved Mr. Whiskers. Again. """
self.kittens_rescued += 1
@property
def is_exhausted(self):
""" Basically a coin toss. """
return random.random() < 0.5
def change_into_super_secret_costume(self):
print("Beauty, eh?")
```
There, now you've baked a state machine into `NarcolepticSuperhero`. Let's take him/her/it out for a spin...
```python
>>> batman = NarcolepticSuperhero("Batman")
>>> batman.state
'asleep'
>>> batman.wake_up()
>>> batman.state
'hanging out'
>>> batman.nap()
>>> batman.state
'asleep'
>>> batman.clean_up()
MachineError: "Can't trigger event clean_up from state asleep!"
>>> batman.wake_up()
>>> batman.work_out()
>>> batman.state
'hungry'
# Batman still hasn't done anything useful...
>>> batman.kittens_rescued
0
# We now take you live to the scene of a horrific kitten entreement...
>>> batman.distress_call()
'Beauty, eh?'
>>> batman.state
'saving the world'
# Back to the crib.
>>> batman.complete_mission()
>>> batman.state
'sweaty'
>>> batman.clean_up()
>>> batman.state
'asleep' # Too tired to shower!
# Another productive day, Alfred.
>>> batman.kittens_rescued
1
```
While we cannot read the mind of the actual batman, we surely can visualize the current state of our `NarcolepticSuperhero`.

Have a look at the [Diagrams](#diagrams) extensions if you want to know how.
## The non-quickstart
A state machine is a _model_ of behavior composed of a finite number of _states_ and _transitions_ between those states. Within each state and transition some _action_ can be performed. A state machine needs to start at some _initial state_. When using `transitions`, a state machine may consist of multiple objects where some (_machines_) contain definitions for the manipulation of other (_models_). Below, we will look at some core concepts and how to work with them