Simle Python Workflows for Web Apps

What is workflow?

A workflow consists of an orchestrated and repeatable pattern of business activity enabled by the systematic organization of resources into processes that transform materials, provide services, or process information. It can be depicted as a sequence of operations, declared as work of a person or group, an organization of staff, or one or more simple or complex mechanisms.


Most common and easy to understand use-case of workflows is a publishing management systems, where content (the article) goes thought the set of states:

Approval workflows for a content
Untangle your content production process, by

Simply  speaking workflow is a collection of transitions that transition between states, which is a case of event-driven finite-state machine:

Finite State Machine is conceived as an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state. It can change from one state to another when initiated by a triggering event or condition; this is called a transition. A particular FSM is defined by a list of its states, its initial state, and the triggering condition for each transition.


Though the workflows and workflow management solutions for modeling/organizing business processes are usually quite huge, complex and complicated they still share same simple principles, including graph-alike representation:

Workflow diagram tree
How to set up Plone intranet/extranet workflow, by

Also it is worth mentioning that thanks to efforts of workflow patterns research group, who developed conceptual basis for process technology, it's possible to model any Business Process Management with usage of following patterns types (the total number of patterns is more than 200):

  • Control-Flow - captures elementary aspects of process control
  • Resource - capture the various ways in which resources are represented and utilized
  • Data - capture the various ways in which data is represented and utilised
  • Exception Handling  - presents a classification framework for exception handling in process-aware information systems
  • Presentation - reduce the perceived model complexity without changing the abstract syntax

The other thing that is worth keep in mind is that Business Process Management deals with the life-cycle of business process models which includes their designexecution and analysis. Although cases when developing workflow management systems is required is not that common, much more common case is developing system that implements some workflow itself, but still knowing conceptual basis provided in researches for workflow management will benefit you a lot.

Choosing strategy for developing workflow

Most probably you should not care about workflows if you are developing a strictly data-centric application, but if application is at least at some point a process-oriented, which means that appication content goes through the some kind of lifecycle, what is quite often case, then you need to think about workflow design and implementation. In simplest cases you will have so called one person workflow where one person does all variety of actions on objects, which could be a bit confusing because at first glance it could make a false impression of that there is no states or transactions or permissions involved at all, but actually that type of workflow has simplified permissions and transactions policies.

Features to look for when choosing workflow framework:

  • Multiple workflows per object
  • Content type specific workflows
  • Restrict transitions by permission
  • Configurable callbacks when entering state
  • Configurable callbacks when executing transition
  • Reset workflow to initial state
  • Platform independent
  • Extensible/Replaceable
  • On top of instance (instead of inheritance by model/resource)
  • Describe actions - quite useful having way to get a list of transactions that current can do and general state info in context of permissions of current user

Simple web specific workflow frameworks

Here I describe and compare some of python frameworks for creating simple workflows specifically for web services. In this section I won't review complex management systems written in like airflow (I very recommend you to check this one out) or viewflow.


Multiple per object Content type specific Transitions by permission Entering state callbacks Executing transition callbacks Reset to initial state Platform independent Extensible / Replaceable On top of instance Describe actions
Y Y Y Y Y  Y Y Y Y Y

This one is my favorite, it is platform independent and  provides all of features I'm looking for in simple workflow state machine for web applications. As  a bonus it even has a support of having workflows described in XML format. 

# defenition
from repoze.workflow import Workflow, get_workflow
# params: state_attr, initial_state, permission_checker=None, name='', description=''
my_workflow = Workflow(state_attr='state', initial_state='draft')
# params: state_name, callback=None, aliases=(), title=None, **kw
# params: transition_name, from_state, to_state,callback=None, permission=None, title=None, **kw
my_workflow.add_transition('to_public', 'draft', 'public')
my_workflow.add_transition('to_draft', 'public', 'draft')

# usage
my_workflow = get_workflow(content, 'security')
my_workflow.transition_to_state(content, request, 'public')
state_info = my_workflow.state_info(content, request)


Multiple per object Content type specific Transitions by permission Entering state callbacks Executing transition callbacks Reset to initial state Platform independent Extensible / Replaceable On top of instance Describe actions
?/N Y Y N N  N N N Y/? N

It doesn't have all nice features that I would expect from simple workflow framework for web applications, but it still seems to be useful and easy to use, but still a bit weird, especially Transition doesn't have from-state, it only has destination state.  You can configure it only through code in a manner that has some syntax overhead.

# Create the workflow object
workflow = Workflow.objects.create(name="Standard")
private = State.objects.create(name="Private", workflow= workflow)
make_public = Transition.objects.create(name="Make public", workflow=workflow, destination=public)
workflow.initial_state = private

# Usage
owner = register_role("Owner")

from permissions.utils import register_permission
view = register_permission("View", "view")
edit = register_permission("Edit", "edit")

# Add all permissions which are managed by the workflow
from workflows.models import WorkflowPermissionRelation
WorkflowPermissionRelation.objects.create(workflow=workflow, permission=view)
WorkflowPermissionRelation.objects.create(workflow=workflow, permission=edit)

# Add permissions for the single states
from workflows.models import StatePermissionRelation
StatePermissionRelation.objects.create(state=public, permission=view, role=owner)
StatePermissionRelation.objects.create(state=private, permission=edit, role=owner)

# Assign the workflow to the content object
from workflows.utils import set_workflow
set_workflow(object, workflow)

# Now self.object has the intial workflow state.
from permissions.utils import has_permission
has_permission(object, user, "edit")

# Now we change the workflow state
from workflows.utils import set_state
set_state(object, public)
has_permission(object, user, "edit")

Multiple per object Content type specific Transitions by permission Entering state callbacks Executing transition callbacks Reset to initial state Platform independent Extensible / Replaceable On top of instance Describe actions
Y Y Y Y Y  Y N Y/N N/? Y

Won't get in much of explanations or examples on this one, only say that it's part of cone framework and it implements a lot of concepts I really like, especially a way of declaring states ACL:

class WorkflowNodeWithStateACLs(WorkflowNode):

    state_acls = {
        'initial': [
            (Allow, 'role:manager', ['manage', 'edit', 'change_state']),
            (Allow, Everyone, ['login']),
            (Deny, Everyone, ALL_PERMISSIONS),
        'final': [
            (Allow, 'role:manager', ['view', 'edit', 'change_state']),
            (Deny, Everyone, ALL_PERMISSIONS),

You defiantly nedd to check out how it does things, because you can borrow a lot of concepts from there even if you are working with other workflow frameworks.


Prev Post Next Post