Tareas de fondo de Celery

Si su aplicación tiene una tarea de larga duración, como el procesamiento de algunos datos cargados o el envío de correo electrónico, no querrá esperar a que termine durante una solicitud. En su lugar, utilice una cola de tareas para enviar los datos necesarios a otro proceso que ejecutará la tarea en segundo plano mientras la solicitud vuelve inmediatamente.

Celery es una poderosa cola de tareas que puede ser utilizada para tareas simples en segundo plano, así como para programas complejos de varias etapas y programaciones. Esta guía le mostrará cómo configurar Celery usando Flask, pero asume que ya ha leído la guía Primeros pasos con Celery en la documentación de Celery.

Instalar

Celery es un paquete independiente de Python. Instálalo desde PyPI usando pip:

$ pip install celery

Configurar

Lo primero que necesitas es una instancia de Celery, esto se llama la aplicación Celery. Sirve el mismo propósito que el objeto Flask en Flask, sólo que para Celery. Dado que esta instancia se utiliza como punto de entrada para todo lo que quieres hacer en Celery, como la creación de tareas y la gestión de los trabajadores, debe ser posible que otros módulos lo importen.

Por ejemplo, puedes colocar esto en un módulo tasks. Aunque puedes usar Celery sin ninguna reconfiguración con Flask, se vuelve un poco más agradable subclasificando tasks y añadiendo soporte para los contextos de aplicación de Flask y enganchándolo con la configuración de Flask.

Esto es todo lo que se necesita para integrar Celery con Flask:

from celery import Celery

def make_celery(app):
    celery = Celery(app.import_name)
    celery.conf.update(app.config["CELERY_CONFIG"])

    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery

La función crea un nuevo objeto Celery, lo configura con el broker desde la configuración de la aplicación, actualiza el resto de la configuración de Celery desde la configuración de Flask y luego crea una subclase de la tarea que envuelve la ejecución de la tarea en un contexto de aplicación.

Nota

Celery 5.x desaprobó las claves de configuración en mayúsculas, y la 6.x las eliminará. Consulte su guía de migración oficial.

Una tarea de ejemplo

Vamos a escribir una tarea que sume dos números y devuelva el resultado. Configuramos el broker y el backend de Celery para usar Redis, creamos una aplicación celery usando la fábrica de arriba, y luego la usamos para definir la tarea:

from flask import Flask

flask_app = Flask(__name__)
flask_app.config.update(CELERY_CONFIG={
    'broker_url': 'redis://localhost:6379',
    'result_backend': 'redis://localhost:6379',
})
celery = make_celery(flask_app)

@celery.task()
def add_together(a, b):
    return a + b

Esta tarea puede llamarse ahora en segundo plano:

result = add_together.delay(23, 42)
result.wait()  # 65

Ejecutar un trabajador

Si te has lanzado y ya has ejecutado el código anterior, te decepcionará saber que .wait() nunca devolverá realmente. Esto se debe a que también es necesario ejecutar un trabajador Celery para recibir y ejecutar la tarea

$ celery -A your_application.celery worker

La cadena your_application tiene que apuntar al paquete o módulo de tu aplicación que crea el objeto celery.

Ahora que el trabajador se está ejecutando, wait devolverá el resultado una vez que la tarea haya terminado.