現在、ソケットとセロリを使用してリアルタイムチャートを作成できるフラスコアプリケーションを設計しようとしています。データを非同期的に取得し、それをソケット経由でクライアントに送信したいと考えています。私はしかし、エラーを取得しています:RuntimeError: Working outside of request context.
私はソケットが最初に接続するときこれを取得します。Flask + Celery + socketio RuntimeError:リクエストコンテキスト外での作業
スタックトレース
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
チャートジャバスクリプト
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)
});
エラーが発生した瞬間はありますか?質問に完全な痕跡を追加できますか?あなたは 'Flask'アプリケーションと' Celery'アプリケーションをどのように実行しますか? –
私は 'python main.py'を使ってCeleryアプリケーションを実行します – Warmley
' send() 'はsocketio装飾関数' handle_connection'の中になければならないと思います。 'async_data'タスクのコールバックで' send'を使ってみることができます。 http://docs.celeryproject.org/en/latest/userguide/calling.html#linking-callbacks-errbacks –