質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1700閲覧

asyncを使用してflaskで裏で定期的に処理をしたいです。

PTK

総合スコア29

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/03/29 16:39

編集2023/03/30 04:55

実現したいこと

asyncを使用してflaskで裏で定期的に処理をしたいです。

前提

pythonでpostリクエストを受け取り、裏で定期的に受け取ったデータを処理したいです。

発生している問題

app.runのタスクを定義した後の処理がされません。

該当のソースコード

python

1from flask import Flask,request 2import asyncio 3 4 5 6queue = asyncio.Queue() 7 8 9app = Flask(__name__) 10 11 12@app.route('/',methods=['POST']) 13async def hello(): 14 15 data = request.get_json() 16 await queue.put(data) 17 18 return '200' 19async def main(): 20 wstsk=asyncio.create_task(app.run(host='0.0.0.0', port=8000)) 21 while True: 22 23 while not queue.empty(): 24 try: 25 item = await queue.get() 26 print(item) 27 finally: 28 queue.task_done() 29 await asyncio.sleep(100) 30 31 32 33 34 35if __name__ == '__main__': 36 37 38 loop = asyncio.get_event_loop() 39 40 loop.run_until_complete(main())

試したこと

threddingを使用したところ、データを受け取りつつ処理することができましたが、どうしても使いたいasyncioの機能があり、
なるべくasyncioとthreddingは併用しない方が良いらしいので、asyncを使った処理を実現したいです。
また、app.run()と受け取った情報を処理する関数をどちらもタスクとしてみましたが、proccess_queue内のwhile文が一周目は実行され,"processing"が出力されましたが、app.runのタスクが処理を手放さないのか2周目以降は実行されませんでした。
以下がそのコードです。

python

1from flask import Flask,request 2import asyncio 3 4queue = asyncio.Queue() 5 6app = Flask(__name__) 7 8 9 10@app.route('/',methods=['POST']) 11async def hello(): 12 13 data = request.get_json() 14 await queue.put(data) 15 16 return '200' 17 18async def run_app(): 19 await app.run(host='0.0.0.0', port=8000) 20 21 22async def process_queue(): 23 24 while True: 25 26 print('processing') 27 28 await asyncio.sleep(2) 29 30 31 32async def main(): 33 tasks = [ 34 asyncio.create_task(process_queue()), 35 asyncio.create_task(run_app()) 36 37 ] 38 await asyncio.gather(*tasks) 39if __name__ == '__main__': 40 41 loop = asyncio.get_event_loop() 42 43 loop.run_until_complete(main()) 44 loop.close() 45

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

勘違いしていました。Flaskのasyncは、中で別のevent loopを作るので、外のevent loopには処理は移らないのですね。
そういうことなら、Flaskとは別のスレッドでevent loopを走らせてやるなどの必要があると思います。

thread を使うのはどうしても避けたいということなら、ASGI サーバーとアダプタを使うという方法があるようです。
もしくは、async/await にしっかり対応したフレームワークに移行するのがいいのでは。Quart は Flask とほぼ同じように使えそうです。

元の回答

asyncio.gather() を await しないといけないのでは。

python

1async def main(): 2 tasks = [ 3 asyncio.create_task(process_queue()), 4 asyncio.create_task(run_app()) 5 ] 6 7 await asyncio.gather(*tasks)

投稿2023/03/30 04:15

編集2023/03/30 06:28
bsdfan

総合スコア4560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PTK

2023/03/30 04:56

回答ありがとうございます。awaitをつけましたが、挙動は特に変わりませんでした。
PTK

2023/03/30 07:28

大変参考になります。quart使ってみます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問