Flask is a great web framework. The only problem, as with all web applications, is the processing of long-running tasks. Luckily for us, we can use our knowledge of Celery and combine it with Flask to process the long-running tasks asynchronously. Even better, we already know everything we need to do this.
This post is part of my journey to learn Python. You can find the other parts of this series here. You find the code for this post in my PythonFriday repository on GitHub.
A minimalistic Flask application
This minimalist Flask application shows how to import your Celery task and invoke it from Flask:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import os import sys import flask folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) sys.path.insert(0, folder) from celery_task import prepare app = flask.Flask(__name__) @app.route('/task/<int:num>') def create_task(num): id = prepare.delay(num) return str(id) if(__name__ == "__main__"): app.run() |
The import at line 7 is the same as you would import your task into the REPL. The same is true for the call of the method prepare.delay() at line 13. There is no need for anything special when you call Celery from Flask.
If you access the URL http://127.0.0.1:5000/task/20 you should see the id of the task:
If we check our logs, we should find the entries where Celery processes our task with this id:
[…] Task celery_task.prepare[c7283e78-…] received
[…] celery_task.prepare[c7283e78-…]: order #20 prepared
[…] Task celery_task.prepare[c7283e78-…] succeeded in 5.016s: None
Start your message queue
Keep in mind that we need a running message queue. Otherwise, we get an exception like this when we start our Flask application:
Traceback (most recent call last):
…kombu.exceptions.OperationalError: [Errno 111] Connection refused
Next
Flask and Celery are a great combination and we do not need anything special to get those two parts working. Next week we take a look at backends for Celery. They are needed when we want to know if a task is done or still waits to be processed.