1Celery Background Tasks
2=======================
3
4If your application has a long running task, such as processing some uploaded
5data or sending email, you don't want to wait for it to finish during a
6request. Instead, use a task queue to send the necessary data to another
7process that will run the task in the background while the request returns
8immediately.
9
10Celery is a powerful task queue that can be used for simple background tasks
11as well as complex multi-stage programs and schedules. This guide will show you
12how to configure Celery using Flask, but assumes you've already read the
13`First Steps with Celery <https://celery.readthedocs.io/en/latest/getting-started/first-steps-with-celery.html>`_
14guide in the Celery documentation.
15
16Install
17-------
18
19Celery is a separate Python package. Install it from PyPI using pip::
20
21    $ pip install celery
22
23Configure
24---------
25
26The first thing you need is a Celery instance, this is called the celery
27application.  It serves the same purpose as the :class:`~flask.Flask`
28object in Flask, just for Celery.  Since this instance is used as the
29entry-point for everything you want to do in Celery, like creating tasks
30and managing workers, it must be possible for other modules to import it.
31
32For instance you can place this in a ``tasks`` module.  While you can use
33Celery without any reconfiguration with Flask, it becomes a bit nicer by
34subclassing tasks and adding support for Flask's application contexts and
35hooking it up with the Flask configuration.
36
37This is all that is necessary to properly integrate Celery with Flask::
38
39    from celery import Celery
40
41    def make_celery(app):
42        celery = Celery(
43            app.import_name,
44            backend=app.config['CELERY_RESULT_BACKEND'],
45            broker=app.config['CELERY_BROKER_URL']
46        )
47        celery.conf.update(app.config)
48
49        class ContextTask(celery.Task):
50            def __call__(self, *args, **kwargs):
51                with app.app_context():
52                    return self.run(*args, **kwargs)
53
54        celery.Task = ContextTask
55        return celery
56
57The function creates a new Celery object, configures it with the broker
58from the application config, updates the rest of the Celery config from
59the Flask config and then creates a subclass of the task that wraps the
60task execution in an application context.
61
62An example task
63---------------
64
65Let's write a task that adds two numbers together and returns the result. We
66configure Celery's broker and backend to use Redis, create a ``celery``
67application using the factory from above, and then use it to define the task. ::
68
69    from flask import Flask
70
71    flask_app = Flask(__name__)
72    flask_app.config.update(
73        CELERY_BROKER_URL='redis://localhost:6379',
74        CELERY_RESULT_BACKEND='redis://localhost:6379'
75    )
76    celery = make_celery(flask_app)
77
78    @celery.task()
79    def add_together(a, b):
80        return a + b
81
82This task can now be called in the background::
83
84    result = add_together.delay(23, 42)
85    result.wait()  # 65
86
87Run a worker
88------------
89
90If you jumped in and already executed the above code you will be
91disappointed to learn that ``.wait()`` will never actually return.
92That's because you also need to run a Celery worker to receive and execute the
93task. ::
94
95    $ celery -A your_application.celery worker
96
97The ``your_application`` string has to point to your application's package
98or module that creates the ``celery`` object.
99
100Now that the worker is running, ``wait`` will return the result once the task
101is finished.
102