Django Chronograph

In this recipe, I will be writing all I know about using the django-chronograph app for your websites.

Django-chronograph is Django’s way of doing tasks in the background on fixed intervals by interacting with the system’s cron daemon. This should be great for long running tasks, that would especially timeout a request if not done asynchronously, like sending emails, or resizing images or of the sort. This is a cousin to interfacing with the celery daemon approach, but not exactly an alternative as they have some quite distinct differences. Celery will not be written about here in this recipe though.

Setting Up

For this setup, I will assume that you are using virtualenv to organize projects. If you want to know more about virtualenv and how to set it up for projects, you can view it here.

Let us now skip to the part after we have installed virtualenv to the system, created a virtualenv instance, and activating it. So, we are now ready to install Django Chronograph. We can install this one using pip (while our virtualenv is activated) however, there will be errors that we will encounter because virtualenv, by default, installs an older version of distribute (0.6.24) which Django Chronograph will not find pleasing to its eyes.

To remedy this, we have to install a newer version (0.6.26), so run the command: easy_install -U distribute.

There should be no problems here. So now, let us proceed to installing Django Chronograph. Run the command:

pip install django-chronograph.

Note that Django Chronograph needs two important tables to run properly. To have that, we must include chronograph in our INSTALLED_APPS in settings.py and then we have to run python manage.py syncdb to have our tables created. To see, the tables, we have to in the admin page for that; but for convenience, the models will be named as “Job” and “Log”.

Getting Things Running

Obviously, the Job model for chronograph will tell Django Chronograph what stuff it needs to do repeatedly, but before we go off and create Job instances to our heart’s desire – that is the easy part, we have to make sure that Django Chronograph itself is actually being run by the system’s cron daemon.

Unfortunately and as far as I know, cron cannot organize cron jobs in a per-project basis. It has to be per user. But that is the administrator’s problem to solve, not ours… for the moment at least. So let’s go create those cron jobs! First, run crontab -e to edit your crontab and put the following:

envPath = "<path/to/virtualenv/directory>"

appPath = "<path/to/django/project/directory>"

* * * * * $envPath/bin/chronograph -e $envPath/bin/activate_this.py -p $appPath

The variables above are just for convenience so that it would not be such a pain to edit your cron jobs again later (if ever you need to). The above code should get your django-chronograph installation running every minute. The $envPath/bin/chronograph is a script installed automatically the app, while the $envPath/bin/activate_this.py is a script created by virtualenv (probably for this purpose, in case, you have code that runs automatically – preventing you to source the activate script). The -e argument specifies the environment that will be run, whilst the -p will specify the path to the Django project (the one housing the manage. by script).

Next, we have to create a Django management command for the Django Chronograph to run. In the event, that you, the precious reader, still do not know, we have to create a class that extends django.core.management.BaseCommand and we must put said class alone in a file in the <app_pkg>.management.commands package. To properly extend the BaseCommand class, we have to override the handle(self, **options) method where you will be putting the code that will be run when this command is invoked (either by Django Chronograph or manage.py)

Now comes the easy part: we create Job instances for Django Chronograph to run in the admin page. We can set each job to run minutely, hourly, weekly, or monthly, you decide! Django Chronograph handles it for you by itself (even though it runs per minute by the cron daemon).

And that is it for Django Chronograph! I hope that there will be no problems that will surface when you use this Django app for your project.