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/'
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:
Using django admin interface¶
We’ll see how to create the “Organizing a conference” workflow using Django’s admin interface:

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¶
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