I've got a simple Python Flask/Celery app that's running into issues with flashing messages after a delay. I'm using Celery's delay() function to call a function that sleeps for 5 seconds, then flashes a message. Despite using with app.app_context()
in my background function, Celery reports:
RuntimeError: Working outside of request context
I've also tried the @copy_current_request_context
decorator, as mentioned by this question, but then I get
RuntimeError: This decorator can only be used at local scopes when a request context is on the stack. For instance within view functions
app.py:
from flask import Flask, flash, render_template, request
from celery import Celery
import time
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
@celery.task
def my_background_task():
with app.app_context():
time.sleep(5)
flash("Background task complete.")
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
task = my_background_task.delay()
return render_template("index.html")
else:
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True,host='0.0.0.0')
templates/index.html:
<!doctype html>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul class=flashes>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block body %}
<form method="POST">
<input type="submit" name="submit" value="Submit request">
</form>
{% endblock %}
I'm running the app with three terminal windows: running Redis with redis-server
, running Celery with celery worker -A app.celery --loglevel=info
, and running Python with python app.py
.