使用 Flask API 返回'still loading'响应



我有一个scikit-learn分类器作为Dockerized Flask应用程序运行,与gunicorn一起启动。它以 JSON 格式接收输入数据作为 POST 请求,并使用结果的 JSON 对象进行响应。

首次使用 gunicorn 启动应用时,将从数据库中读取一个大型模型(使用 joblib 序列化),并在应用准备好接受请求之前加载到内存中。这可能需要 10-15 分钟。

可重现的示例不可行,但基本结构如下所示:

from flask import Flask, jsonify, request, Response
import joblib
import json
def classifier_app(model_name):
    # Line below takes 10-15 mins to complete
    classifier = _load_model(model_name)
    app = Flask(__name__)
    @app.route('/classify_invoice', methods=['POST'])
    def apicall():
        query = request.get_json()
        results = _build_results(query['data'])
        return Response(response=results,
                        status=200,
                        mimetype='application/json')
    print('App loaded!')
    return app

如何配置 Flask 或 gunicorn 以在 _load_model 仍在运行时向任何传入的 http 请求返回"仍在加载"响应(或适当的错误消息)?

基本上,您希望为一个请求返回两个响应。所以有两种不同的可能性。

第一种是在后台运行耗时的任务,每两秒用简单的ajax请求ping服务器来检查任务是否完成。如果任务完成,则返回结果,如果没有,则返回"Please standby"字符串或其他内容。

第二个是使用websockets和flask-socketio扩展。

基本服务器代码如下所示:

from threading import Thread
from flask import Flask
app = Flask(__name__)
socketio = SocketIO(app)
def do_work():
    result = your_heavy_function()
    socketio.emit("result", {"result": result}, namespace="/test/")
@app.route("/api/", methods=["POST"])
def start():
    socketio.start_background_task(target=do_work)
    # return intermediate response
    return Response()

在客户端,你应该做这样的事情

var socket = io.connect('http://' + document.domain + ':' + location.port + '/test/');
socket.on('result', function(msg) {
    // Process your request here
});

有关更多详细信息,请访问此博客文章,用于服务器端参考的 flask-socketio 文档和用于客户端参考的 socketio 文档。

PS 使用网络套接字,您也可以制作进度条。

相关内容

  • 没有找到相关文章

最新更新