Using Kronos to simplify cron jobs in Django

Tags: kronos

Kronos makes it really easy to define and schedule tasks with cron

Author of django-kronos

Life is much easier with well organised code that is easy to test and deploy.  Lets see how using kronos simplifies cron in a django project:

  • No more manual editing of crontabs
  • Schedule management commands or regular python functions
  • Logical organisation of cron tasks in an app's cron.py module
  • Django settings are automatically available to the cron job
  • Test a cron job with a simple management command
  • Schedule all cron jobs with a single management command
Here is an example of a cron job I have set up for this blog - to remove unconfirmed subscribers (they have not clicked a validation link in an email sent to them).


# in app/cron.py
import kronos
from blog_email.models import BlogEmailSubscriber

@kronos.register('30 2 * * 0')
def DeleteUnconfirmedSubscribers():
    BlogEmailSubscriber.objects.filter(confirmed=False).delete()
    

The kronos.register decorator takes regular cron syntax as its first argument. So this task will be registered to run every Sunday at 2:30 am.

We can run this task to test it works using:


python manage.py runtask DeleteUnconfirmedSubscribers
    

It is very convenient to be able to access your models, settings and well, your whole django project from the cronjob!

To register the tasks with cron, we run:


python manage.py installtasks
    

This will first uninstall all tasks in the current user's crontab, and then install all registered tasks.  Super convenient for making sure the crontab contains all registered tasks, with any unwanted tasks removed.

This makes it very easy to use as part of an automated deployment, for example using Fabric:


# in fabfile.py
from fabric.api import cd, env, run

env.hosts = ['example.com']
env.user = 'django'  # the user you want to run the cron jobs

def deploy():
    with cd('/path/to/django_project/'):
        # other deployment command here...
        run('python manage.py installtasks')
        run('crontab -l') . # display the new crontab for user 'django'
    

Note: it is important to run these commands as the appropriate user, as each user has there own crontab, and tasks will be run by the user who owns the crontab.

Loading comments...
';