Django - Asynchronous tasks

From XennisWiki
(Redirected from Celery)
Jump to: navigation, search

Run asynchronous tasks within a Django application.

Celery with django-celery

Setup Django application

myapp/settings.py

INSTALLED_APPS = (
    'anothermodule',
    # ...
    'djcelery',
    'kombu.transport.django',
)

import djcelery
djcelery.setup_loader()
BROKER_URL = "django://"

Create a task

anothermodule/tasks.py

from __future__ import absolute_import
from celery import shared_task


@shared_task
def add(x, y):
    return x + y

Run

Run Celery with log level (-l) info

$ python manage.py celery worker -l info

Open a Python shell with the Django environment

$ python manage.py shell
>>> from anothermodule import tasks
>>> add_task = tasks.add.delay(0, 3)
>>> add_task.ready()
True
>>> add_task.successful()
True

Celery (without django-celery)

Installation

pip: celery

Setup application

myapp/celery.py

from __future__ import absolute_import

import os

from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')

from django.conf import settings  # noqa

app = Celery('myapp')

# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

myapp/settings.py

# Celery settings
BROKER_URL = 'amqp://guest:guest@localhost//'

Create a task

anothermodule/tasks.py

from __future__ import absolute_import
from celery import shared_task

@shared_task
def my_task(name, num):
    # do some action here
    return True

anothermodule/view.py

import tasks

def run_my_task(request):
    tasks.my_task.delay('Hello', 2)
    return HttpResponse('Start my_task')

Run

Run the Django application and run Celery:

celery -A myapp worker -l info

Terminate a task by its ID

Expand your task to react to a sigterm signal.

import signal
import sys
# ...

@shared_task
def add(x, y):
    signal.signal(signal.SIGTERM, signal_term_handler)
    # ...

def signal_term_handler(signal, frame):
    print 'got SIGTERM'
    sys.exit(0)

Run and then terminate a task

$ python manage.py shell
>>> # run task
>>> from anothermodule import tasks
>>> t=tasks.add.delay(0,0)
>>>
>>> # revoke (terminate) task by its ID
>>> from myapp.celery import app
>>> app.control.revoke(t.id, terminate=True)

Celery with django-celery

see Python.org - django-celery

See also

External links