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