Welcome to WS’s documentation!

Note

Documentation still in active development!

A Business Process Manager for Django. Uses Celery for task automation and ExtJS for web interface.

Overview

WS is a Business Process Manager for Django. Uses Celery for asynchronous task automation and ExtJS for web interface.

WS executes processes following previously defined workflows, creating a tasks for each node, gided by the transitions between nodes.

The user responsible for the task is automatically chosen from the role defined in the node.

Installation

Todo

pip install django-ws

WS and all needed dependencies should be installed automatically with:

pip install hg+https://lagunak.gisa-elkartea.org/hg/django-ws

Dependencies

Also, this project uses South to ease upgrading.

Celery needs an AMQP broker, for example rabbitmq

Configuration

Add this to INSTALLED_APPS in project’s settings.py:

  • ‘ws’
  • ‘guardian’
  • ‘djcelery’
  • ‘extjs4’

Add also the following line to your project’s settings.py:

import ws
ws.setup_loader()

Celery configuration

Celery has many configuration options, take a look at celery documentation.

The simplest configuration requires to set the AMQP broker url. For example:

BROKER_URL = 'amqp://guest:guest@localhost:5672/'

Django-guardian configuration

Set anonymous user’s id:

ANONYMOUS_USER_ID = -1

ExtJS administration interface

Include ws.urls somewhere in your urls:

(r'^ws/', include('ws.urls'))

Collect the static files from extjs4 and ws:

./manage.py collectstatic

Quick Start

Administration

User permissions

Creating a workflow

In this section we’ll see how to create new workflows through an example, “Organizing a conference”:

First the call for papers is sent, and begins the search for a location. When there are sufficient talks and the location is chosen begins the propaganda. Then subscriptions are accounted until the starting day comes, when the conference finally begins.

The graph could be something like this:

digraph conference {
    "Send the Call for Papers" -> "Collect papers"
    "Collect papers" -> "Publicize"
    "Search a location" -> "Publicize"
    "Publicize" -> "Mailing"
    "Publicize" -> "Newspapers"
    "Publicize" -> "Poster"
    "Mailing"    -> "Receive subscriptions"
    "Newspapers" -> "Receive subscriptions"
    "Poster"     -> "Receive subscriptions"
    "Receive subscriptions" -> "Wait until the starting day"
    "Wait until the starting day" -> "Receive subscriptions"
    "Wait until the starting day" -> "Start the conference"
};

Using django admin interface

We’ll see how to create the “Organizing a conference” workflow using Django’s admin interface:

_images/ws-admin.png
Create the workflow

The new workflow’s only required attribute is name: “Organizing conference”

Node
  • name: “Send the Call for Papers”
  • is start: True
  • split: AND
  • role: Organization
  • celery task: conferencer.tasks.mailing
Node
  • name: “Collect papers”
  • join: AND
  • split: AND
  • role: Accounting
  • celery task: conferencer.tasks.ask_human
Node
  • name: “Publicize”
  • join: AND
  • split: AND
  • role: Accounting
  • celery task: conferencer.tasks.ask_human

Using fixtures

Using python

Create the workflow:

from ws.models import Workflow, Node, Transition, Process
from ws.tasks.dummy import dummy

# Create a workflow and save it
workflow = Workflow.objects.create()

# Create three nodes for the workflow tied to dummy tasks and save them
first = Node.objects.create(name='first', workflow=workflow, celery_task=dummy, is_start=True)
second = Node.objects.create(name='second', workflow=workflow, celery_task=dummy)
third = Node.objects.create(name='third', workflow=workflow, celery_task=dummy, is_end=True)

# Create two transitions to bind the nodes
Transition.objects.create(parent=first, child=second)
Transition.objects.create(parent=second, child=third)

Execute the workflow:

process = Process.objects.create(workflow=workflow)
process.start()

Custom celery tasks

WS task’s are celery tasks inheriting BPMTask. They must be in a module loaded by celery, the typical place it’s a tasks.py file in the django application’s root. It’s strongly recommended to define also a form describing the task’s parameters, but not strictly necessary:

from ws.tasks import BPMTask
from ws import forms

class MultiplyTaskForm(forms.BPMTaskForm):
    a = forms.IntegerField(label='first number')
    b = forms.IntegerField(label='second number')


class MultiplyTask(BPMTask):
    form = MultiplyTaskForm

    def call(self, a, b):
        return a * b

Note that ws.forms module is used instead django.forms. ws.forms are basically ExtJS enabled django.forms.

It’s also possible to define certain actions that will take place when certain events happen:

class MultiplyTask(BPMTask):

    def call(self, a, b):
        return a * b

    def on_start(self, task_id, args, kwargs):
        print('Task ID: {}'.format(task_id))
        print('Received args: {}'.format(args))
        print('Received kwargs: {}'.format(kwargs))

    def on_success(self, retval, task_id, args, kwargs):
        print('Return value: {}'.format(retval))

    def on_failure(self, exc, task_id, args, kwargs, einfo):
        print('Exception: {}'.format(exc))

    def on_retry(self, exc, task_id, args, kwargs, einfo):
        print('Retrying...')

    def on_revoke(self, task_id, args, kwargs):
        print('Revoked :-/')

Development, Help & Suggestions

WS is hosted in a redmine project on http://lagunak.gisa-elkartea.org/projects/django-ws

Reporting bugs and suggestions

Use the issue tracker.

Asking for help

There is a forum ready for questions. Preferred language is english, but basque or spanish questions are also welcomed.

Getting source code

The code is in a mercurial repository:

hg clone https://lagunak.gisa-elkartea.org/hg/django-ws

Testing

The code is developed and tested in Django 1.4 and RabbitMQ 2.8.

Many tests require a working celery environment. You could run celeryd and the AMQP broker or set the celery’s test runner:

TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'

Glossary

Workflow
A collection of nodes, tied by transitions. A worfklow must have at least one starting node.
Node

A concrete step of the workflow, defines WHO must do WHAT.

Each node executes a celery task. It can define all required parameters or leave some empty. If at the time of execution some parameters are still missing human intervention is requested.

Each node has a role assigned. When human intervention is requested the target user is chosen from this group.

Role

A Group of users with a defined role in the process. The users of this group will be responsible of the task; at this moment this only means that thew will set the missed parameters from the node’s celery task.

To control when the node must be fired a join condition is defined:

  • if a node has AND as the condition for joining, all the transitions that point to this node must be fulfilled.
  • if a node has XOR as the condition for joining, only one of the transitions that point to this node must be fulfilled. When it does, all other parent nodes are stopped.

To control what to do when a node is finished, a split condition is defined:

  • if a node has AND as the condition for splitting, when this node is successful, all the children transitions that match the result will be notified.
  • if a node has XOR as the condition for splitting, when this node is successful, only one of the children transitions that match the result will be notified.

Any node can be set as starting point of the workflow. If there are more than one starting nodes all are fired in parallel.

Any node can be a ending point of the workflow. After any of the ending nodes is executed the workflow is terminated.

Todo

OR conditions

Celery task
Each node executes some automation: send a file somewhere, notify someone when a task is finished, etc. This automations are implemented with Celery.
Transition
Binding that tie together two nodes in a workflow. They also have an optional condition witch must be fulfilled for the transition to be valid.
Process
Execution of a workflow. Besides having a starting and an ending date, also keeps track of the process status.
Task

Execution of a node in a given process. Besides having a starting and an ending date, also keeps track of the undergoing celery task status, progress and result.

When a task is started tries to get all parametters for the celery task. This parameters can be defined in workflow, process, node, task models and will automatically inherit from one another, being the last ones the parameters define in tasks. In this way, you can define workflow wide execution parameters and override them for a given task.

If there is some missing parametter the task goes into PENDING state. A user from the node’s role must fill the gaps.

Role
A pool of users electible for performing some task. Only the users of the specified role can do the task.

API documentation

ws

ws.celery

ws.celery.bpm

ws.celery.signals

ws.celery.shortcuts

ws.forms

ws.models

ws.tasks

ws.views

TODO

Todo

OR conditions

(The original entry is located in /home/docs/checkouts/readthedocs.org/user_builds/django-ws/checkouts/latest/docs/glossary.rst, line 50.)

Todo

pip install django-ws

(The original entry is located in /home/docs/checkouts/readthedocs.org/user_builds/django-ws/checkouts/latest/docs/installation.rst, line 5.)

  • docstrings
  • tests
  • documentation
  • pypi
  • setup.py

Optional

  • announcement on reddit and freashmeat

Indices and tables