Flask тайм-аут при подаче с использованием gunicorn - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть приложение, которое будет конвертировать аудио файл в текст. Использование flask и flask -socketio. Он отлично работает, когда я запускаю его с помощью: "python run.py", но когда я запускаю его с помощью: "gunicorn -k eventlet -b 0.0.0.0:5000 run: app", он останавливается на той части, где он вызывает Google речь к тексту API в файле audio.py.

Это текущие коды прямо сейчас.

run.py:

from ats import socketio, app, db

if __name__ == '__main__':
    db.create_all()
    socketio.run(app, host='0.0.0.0', port=5001, debug=True)

init .py

import logging, json

from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit, send
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmall

app = Flask(__name__, instance_relative_config=True, static_folder="templates/static", template_folder="templates")

# Create db instance
db = SQLAlchemy(app)
ma = Marshmallow(app)

@app.route('/')
def index():
    return render_template('index.html');

# import models
from ats import models

# set up CORS
CORS(app)
socketio = SocketIO(app, cors_allowed_origins='*', async_mode='eventlet')


# import blueprints
from ats.product.product import product_blueprint

# register blueprints
app.register_blueprint(product_blueprint, url_prefix='/api/product')

from ats import error_handlers

product.py

import os
import math
import eventlet
from os.path import join
from flask import Blueprint, request, jsonify, abort
from ats.utils import audio as AUDIO

product_blueprint = Blueprint('product', __name__)

@product_blueprint.route('/add', methods=['post'])
def addProduct():
    try:
        data = request.form

        foldername = data['name']
        scriptFile = request.files['script']
        audioFile = request.files['audio']

        # save the script and audio file to uploads folder
        FILE.createFolder(foldername)
        FILE.save(foldername, scriptFile)
        FILE.save(foldername, audioFile)

        # list the files in the uploads
        audioFiles = FILE.getAudioFileList(foldername)

        fileCount = len(audioFiles)
        currentFile = 1
        # ============ speech to text =============
        for file in audioFiles:
            recognizedText = AUDIO.convert(foldername, file)

            # save to database
            newAudio = {
                'name': file,
                'recognizedText': recognizedText,
                'length': duration,
            }
            Audio.add(newAudio)

            # emit event to update the client about the progress
            percent = math.floor((currentFile / float(fileCount) ) * 100) 
            emit('upload_progress', {'data': percent}, room=data['sid'], namespace='/')
            eventlet.sleep()
            currentFile += 1

        # Delete the files in uploads folder
        FILE.delete(foldername)

        return jsonify({'data': None, 'message': 'Product was added.', 'success': True}), 200
    except Exception as e:
        abort(500, str(e))

audio.py

import os
from ats import app

# Imports the Google Cloud client library
from google.cloud import speech
from google.cloud.speech import enums
from google.cloud.speech import types

# Instantiates a client
client = speech.SpeechClient()

def convert(foldername, filename):
    try:

        file = os.path.join(app.config['UPLOAD_FOLDER'], foldername, filename)

        # Loads the audio into memory
        with io.open(file, 'rb') as audio_file:
            content = audio_file.read()
            audio = types.RecognitionAudio(content=content)

        config = types.RecognitionConfig(
            encoding=enums.RecognitionConfig.AudioEncoding.LINEAR16,
            sample_rate_hertz=48000,
            language_code='ja-JP')

        # Call speech in the audio file
        response = client.recognize(config, audio) # The code will stop here, that results to worker timeout in gunicorn

        return response
    except Exception as e:
        raise e

Я почти неделю искал решение, но все еще продолжаю не мог найти один. Спасибо за помощь, ребята.

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Когда вы запускаете приложение напрямую, используя python run.py, тайм-аут не применяется, прикладная программа отнимает столько времени, сколько требуется для обработки, однако при запуске приложения с помощью Gunicorn время ожидания по умолчанию составляет 30 секунд, что означает, что вы получите ошибка тайм-аута, если ваше приложение не отвечает в течение 30 секунд. Чтобы избежать этого, вы можете увеличить время ожидания по умолчанию, установленное Gunicorn, добавив --timeout <timeinterval-in-seconds>

Следующая команда устанавливает время ожидания на 10 минут

gunicorn -k eventlet -b 0.0.0.0:5000 --timeout 600 run:app

0 голосов
/ 05 февраля 2020

Теперь работает, запустив его, используя uwsgi вместо gunicorn. Вот конфиг, сервис и nginx

ats.ini

[uwsgi]
module = wsgi:app

master = true
processes = 1

socket = ats.sock
chmod-socket = 660
vacuum = true

die-on-term = true

/ etc / systemd / system / ats.service

[Unit]
Description=uWSGI instance to serve ats
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/user/ats
Environment="PATH=/home/user/ats/env/bin"
ExecStart=/home/user/ats/env/bin/uwsgi --ini ats.ini --gevent 100

[Install]
WantedBy=multi-user.target

nginx

server {
    listen 80;
    server_name <ip_address or domain>;
    access_log  /var/log/nginx/access.log;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/ats/ats.sock;
        proxy_set_header Connection "Upgrade";

        client_max_body_size 200M;
    }

    location /socket.io {
        include uwsgi_params;
        uwsgi_pass unix:/home/user/ats/ats.sock;
        proxy_set_header Connection "Upgrade";
    }
}

Спасибо, ребята

...