У меня есть классификатор scikit-learn, работающий как Dockerized Flask app, запущенный с помощью 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 для возврата ответа «все еще загружается» (или подходящего сообщения об ошибке) на любые входящие HTTP-запросы, пока _load_model
все еще работает?
Вы хотите создать индикатор выполнения или что-то в этом роде? — person ajrwhite schedule 29.01.2019
Вы можете использовать Celery для асинхронной обработки задачи joblib. Вам также необходимо установить брокера, такого как RabbitMQ или Redis, который будет служить очередью задач. — person ajrwhite schedule 29.01.2019
@Montreal нет индикатора выполнения — просто HTTP-ответ на запрос POST. — person ajrwhite schedule 29.01.2019
@prithajnath, это звучит интересно, но не могли бы вы объяснить, как это решает проблему? Приложение создается во время выполнения задачи joblib, а затем, если запрос поступает до того, как модель существует, мы можем вернуть ошибку? — person ajrwhite schedule 29.01.2019
По сути, вы хотите вернуть два ответа на один запрос. Итак, есть две разные возможности.
Первый — запускать трудоемкую задачу в фоновом режиме и пинговать сервер с простыми запросами ajax каждые две секунды, чтобы проверить, завершена ли задача или нет. Если задача выполнена, вернуть результат, если нет, вернуть
"Please standby"
строку или что-то в этом роде.Второй — использовать веб-сокеты и расширение flask-socketio.
Базовый код сервера будет примерно таким:
На стороне клиента вы должны сделать что-то вроде этого
Для получения дополнительных сведений посетите это сообщение в блоге, < href = «https://flask-socketio.readthedocs.io/en/latest/» rel = «nofollow noreferrer»> документацию по flask-socketio для справки на стороне сервера и документация по socketio для справки на стороне клиента.
PS Используя веб-сокеты, вы тоже можете сделать индикатор выполнения.