J'essaie actuellement de concevoir une application de flacon qui permet des cartes en temps réel grâce à l'utilisation de douilles et de céleri. Je veux être en mesure d'obtenir des données de manière asynchrone, puis l'envoyer via un socket au client. J'obtiens cependant l'erreur: RuntimeError: Working outside of request context.
Je reçois ceci quand la douille se connecte d'abord.Flacon + Céleri + socketio RuntimeError: Travailler en dehors du contexte de la demande
pile trace
Traceback (most recent call last):
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/celery/app/trace.py", line 374, in trace_task
R = retval = fun(*args, **kwargs)
File "/Users/bev/PycharmProjects/flask_project/celery_config.py", line 15, in __call__
return TaskBase.__call__(self, *args, **kwargs)
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/celery/app/trace.py", line 629, in __protected_call__
return self.run(*args, **kwargs)
File "/Users/bev/PycharmProjects/flask_project/main.py", line 20, in async_data
send(jsonify({"result": sample(range(101), 6)}))
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/flask/json.py", line 251, in jsonify
if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not request.is_xhr:
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/werkzeug/local.py", line 306, in _get_current_object
return self.__local()
File "/Users/bev/.virtualenvs/flask_project/lib/python3.6/site-packages/flask/globals.py", line 37, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem.
main.py
from flask import Flask, render_template, jsonify
from flask_socketio import SocketIO, send
from random import sample
from celery_config import make_celery
app = Flask(__name__)
app.config["SECRET_KEY"] = "thisisasecret"
socketio = SocketIO(app)
app.config.update(
CELERY_BROKER_URL="amqp://localhost//",
CELERY_RESULT_BACKEND="rpc://"
)
celery = make_celery(app)
@celery.task(name="main.async_data")
def async_data():
# for now this is very small as an example
# preferably batched to be done every 15 minutes.
send(jsonify({"result": sample(range(101), 6)}))
return True
@app.route("/")
def index():
return render_template("chart.html")
@socketio.on("connect")
def handle_connection():
async_data.delay()
print("You are connected and we are getting your data")
if __name__ == "__main__":
socketio.run(app, debug=True)
celery_config.py
from celery import Celery
def make_celery(app):
celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
graphique javascript
let chartConfig = {
type: "line",
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
datasets: [{
label: "GOOG",
data: [],
borderColor: "rgba(22, 172, 65, 1)",
borderWidth: 1,
fill:false
}]
}
};
let socket = io.connect("http://" + document.domain + ':' + location.port);
socket.on("connect", function() {
socket.send("Connected Socket off to get data");
});
socket.on("message", function (data) {
chartConfig.data.datasets[0].data = data.result;
let ctx = document.getElementById("myChart").getContext("2d");
let myLineChart = new Chart(ctx, chartConfig)
});
À quel moment vous avez eu l'erreur? Pourriez-vous ajouter une trace complète à la question? Comment lancez-vous l'application 'Flask' et l'application' Celery'? –
Je lance l'application Celery en utilisant 'python main.py' – Warmley
Je suppose que' send() 'doit être dans la fonction socketio décorée' handle_connection'. Vous pouvez essayer d'utiliser 'send' dans un rappel à la tâche' async_data'. http://docs.celeryproject.org/en/latest/userguide/calling.html#linking-callbacks-errbacks –