I recently switch to Celery 3.0. Before that I was using Flask-Celery in order to integrate Celery with Flask. Although it had many issues like hiding some powerful Celery functionalities but it allowed me to use the full context of Flask app and especially Flask-SQLAlchemy.
In my background tasks I am processing data and the SQLAlchemy ORM to store the data. The maintainer of Flask-Celery has dropped support of the plugin. The plugin was pickling the Flask instance in the task so I could have full access to SQLAlchemy.
I am trying to replicate this behavior in my tasks.py file but with no success. Do you have any hints on how to achieve this?
Update: We’ve since started using a better way to handle application teardown and set up on a per-task basis, based on the pattern described in the more recent flask documentation.
extensions.py
app.py
Once you’ve set up your app this way, you can run and use celery without having to explicitly run it from within an application context, as all your tasks will automatically be run in an application context if necessary, and you don’t have to explicitly worry about post-task teardown, which is an important issue to manage (see other responses below).
Troubleshooting
Those who keep getting
with _celery.app.app_context(): AttributeError: 'FlaskCelery' object has no attribute 'app'make sure to:celeryimport at theapp.pyfile level. Avoid:app.py
flask runand useNote the
app:celery, i.e. loading fromapp.py.You can still import from extensions to decorate tasks, i.e.
from extensions import celery.Old answer below, still works, but not as clean a solution
I prefer to run all of celery within the application context by creating a separate file that invokes celery.start() with the application’s context. This means your tasks file doesn’t have to be littered with context setup and teardowns. It also lends itself well to the flask ‘application factory’ pattern.
extensions.py
tasks.py
app.py
RunCelery.py