私は 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 を使用するためのより詳細なガイド。