Getting Started with Celery and Django
February 4, 2012
We're going to implement a simple asynchronous task from a Django site, using Celery with a Redis back end. This task will send an email, based on parameters passed through the task to it. We assume you have an existing Django project and are adding celery to it.
Install software
We need to install redis
# apt-get install redis
Install Required Libraries
Use pip to install the following python libraries:
redis django-celery-with-redis
Write Task
Here's the task code we're going to use.
from celery.task import task from django.template.loader import render_to_string from django.core.mail import EmailMessage from django.conf import settings @task(ignore_result=True) def notify(pThing, pType, pUser): """ Send an admin notification email when something happens """ lDestination = ['address@destination.co.uk'] lFrom = 'address@from.co.uk' lContext = { 'Thing' : pThing, 'User' : pUser, } lSubject = render_to_string('email/%s_subject.txt' % (pType), lContext) lSubject = "%s %s" % (settings.EMAIL_SUBJECT_PREFIX, lSubject) lSubject = ''.join(lSubject.splitlines()) # Email subject *must not* contain newlines lMessage = render_to_string('email/%s.txt' % (pType), lContext) lEmailMessage = EmailMessage(subject=lSubject, body=lMessage, from_email=lFrom, to=lDestination, bcc=[]) lEmailMessage.send(True)
This function has been saved into a file called notifications.py
, and this is inside a package called drumcoder.tasks
.
settings.py
We need the following inside settings.py
:
BROKER_URL = "redis://localhost:6379/0" CELERY_RESULT_BACKEND = "redis" CELERY_REDIS_HOST = "localhost" CELERY_REDIS_PORT = 6379 CELERY_REDIS_DB = 0 CELERY_IMPORTS = ("drumcoder.tasks.notifications", ) CELERY_SEND_TASK_ERROR_EMAILS = True CELERYD_LOG_FILE='/tmp/celery.log' import djcelery djcelery.setup_loader()
Call Task
We now need to call the task from our code. We first need to import
it, directly from where it is defined:
from drumcoder.tasks.notifications import notify
We then call it using a delay()
function call, passing in parameters as if we were calling the function directly:
notify.delay(lContest, 'edit_contest', request.user)
Run Celery Daemon
Finally, we need to run the Celery Daemon. This can be done through manage.py
:
$ ./manage.py celeryd
If you now run up the web app in a second command prompt with ./manage.py runserver
, the task should now be run successfully when it is triggered.