Flaskで非同期タスクを作成する 質問する

Flaskで非同期タスクを作成する 質問する

私は Flask でアプリケーションを作成していますが、WSGI同期とブロッキングを除けば非常にうまく動作します。特に、サードパーティの API を呼び出すタスクが 1 つあり、そのタスクは完了するまでに数分かかることがあります。その呼び出し (実際には一連の呼び出し) を行い、制御が Flask に戻っている間に実行したいと思います。

私の見解は次のようになります:

@app.route('/render/<id>', methods=['POST'])
def render_script(id=None):
    ...
    data = json.loads(request.data)
    text_list = data.get('text_list')
    final_file = audio_class.render_audio(data=text_list)
    # do stuff
    return Response(
        mimetype='application/json',
        status=200
    )

今、私がやりたいのは、ラインを

final_file = audio_class.render_audio()

実行し、メソッドが返されたときに実行されるコールバックを提供しますが、Flask はリクエストの処理を継続できます。これは、Flask で非同期に実行する必要がある唯一のタスクであり、これを実装する最適な方法についてアドバイスをお願いします。

Twisted と Klein も調べてみましたが、Threading で十分かもしれないので、これらが過剰かどうかはわかりません。あるいは、Celery がこれに適した選択肢でしょうか?

ベストアンサー1

私は使うだろうセロリ非同期タスクを処理します。タスク キューとして機能するブローカーをインストールする必要があります (RabbitMQ と Redis が推奨されます)。

app.py:

from flask import Flask
from celery import Celery

broker_url = 'amqp://guest@localhost'          # Broker URL for RabbitMQ task queue

app = Flask(__name__)    
celery = Celery(app.name, broker=broker_url)
celery.config_from_object('celeryconfig')      # Your celery configurations in a celeryconfig.py

@celery.task(bind=True)
def some_long_task(self, x, y):
    # Do some long task
    ...

@app.route('/render/<id>', methods=['POST'])
def render_script(id=None):
    ...
    data = json.loads(request.data)
    text_list = data.get('text_list')
    final_file = audio_class.render_audio(data=text_list)
    some_long_task.delay(x, y)                 # Call your async task and pass whatever necessary variables
    return Response(
        mimetype='application/json',
        status=200
    )

Flask アプリを実行し、別のプロセスを開始して Celery ワーカーを実行します。

$ celery worker -A app.celery --loglevel=debug

ミゲル・グリングバーグの書き上げるFlask で Celery を使用するためのより詳細なガイド。

おすすめ記事