XWorkflows

XWorkflows is a library designed to bring a simple approach to workflows in Python.

It provides:

  • Simple workflow definition
  • Running code when performing transitions
  • Hooks for running extra code before/after the transition
  • A hook for logging performed transitions

You can also refer to the django_xworkflows project for integration with Django.

Getting started

First, install the xworkflows package:

pip install xworkflows

Declaring workflows

You can now define a Workflow:

class MyWorkflow(xworkflows.Workflow):
    states = (
        ('init', _(u"Initial state")),
        ('ready', _(u"Ready")),
        ('active', _(u"Active")),
        ('done', _(u"Done")),
        ('cancelled', _(u"Cancelled")),
    )

    transitions = (
        ('prepare', 'init', 'ready'),
        ('activate', 'ready', 'active'),
        ('complete', 'active', 'done'),
        ('cancelled', ('ready', 'active'), 'cancelled'),
    )

    initial_state = 'init'

Applying a workflow

In order to apply that workflow to an object, you must:

Here is an example:

class MyObject(xworkflows.WorkflowEnabled):
    state = MyWorkflow()

Using the transitions

With the previous definition, some methods have been magically added to your object definition (have a look at WorkflowEnabledMeta to see how).

There is now one method per transition defined in the workflow:

>>> obj = MyObject()
>>> obj.state
State('init')
>>> obj.prepare()
>>> obj.state
State('ready')

As seen in the example above, calling a transition automatically updates the state of the workflow.

Only transitions compatible with the current state may be called:

>>> obj.state
State('ready')
>>> obj.complete()
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
InvalidTransitionError: Transition "complete" isn't available from state "ready"

Custom transition code

It is possible to define explicit code for a transition:

class MyObject(xworkflows.WorkflowEnabled):
    state = MyWorkflow

    @xworkflows.transition()
    def activate(self, user):
        self.activated_by = user
        print "State is %s" % self.state.name

When calling the transition, the custom code is called before updating the state:

>>> obj.state
State('ready')
>>> obj.activate('blah')
State is ready
>>> obj.state
State('active')
>>> obj.activated_by
'blah'

Hooks

Other functions can be hooked onto transitions, through the before_transition(), after_transition(), transition_check(), on_enter_state() and on_leave_state() decorators:

class MyObject(xworkflows.WorkflowEnabled):
    state = MyWorkflow

    @xworkflows.before_transition('foobar', 'gobaz')
    def hook(self, *args, **kwargs):
        pass

Indices and tables

Table Of Contents

Next topic

Reference

This Page