How to run a celery task on flask startup?

Viewed 153

Very simple question, I hope. I have a flask service that needs to listen to a subscription. I have all the code written to listen to the subscription and run some code when triggered.

The flask app code is:

from flask import Flask, jsonify
import logging
from celery.bin.worker import worker
from celery import shared_task

from proj.celery_config import make_celery, get_options
from proj.config import Config
app = Flask(__name__)
app.config.from_object(Config)

celery = make_celery(app)
options = get_options(app)
worker = worker(app)


@shared_task()
def run_listener():
    listen()


@app.route('/actuator/health')
def health_check():
    return jsonify({'status': 'UP'})


@app.route('/')
def hello_world():
    """
    A simple test route for verifying flask is working.

    :return: string containing "Hello, World!"
    """
    logger.info("Hello world called!")
    return 'Hello, World!'


def main():
    return app

The code for make_celery and get_options is:

from celery import Celery


def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_BROKER_URL'],
        broker=app.config['CELERY_BROKER_URL']
    )
    celery.conf.update(app.config)

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

    celery.Task = ContextTask
    return celery


def get_options(app):
    return {
        'broker': app.config['CELERY_BROKER_URL'],
        'traceback': True,
        'loglevel': 'info',
        'queues': 'q1'
    }

I have not set up all the endpoints yet, but here is something very important here: the task run_listener needs to work on startup without running the worker outside the app. Meaning I cannot do a celery -A tasks .... I just want it to run whenever the flask app is run. Is there a way to do this?

I have tried running worker.run(**options) but I get an error, no matter if I use the flask app or the celery app when initializing the worker object. Am I missing something?

0 Answers
Related