本記事の背景
ダウンロードなど時間がかかる処理を行う場合、先にResponseを返さないと応答なしエラーが表示されてしまいます。
これを回避するためにマルチスレッド処理が良いのですが、マルチスレッドをちゃんと理解しないと実装が難しいと思われます。
もう一つは非同期を実装する方法です。こちらは、Pythonの非同期を使うやり方がありますが、asyncやawaitに対して理解が必要になります。
そこでマルチスレッドを使わずに普通の関数でやってしまいたい時に本記事を参考にしてください。
但し、簡易なメッセージのみ表示するので、カッコ悪い部分は勘弁してください。
Streaming Contents
使い方は簡単です。Flaskで提供しているStreaming Contentsを使うと簡単な実装で済みます。
※こちらは非同期ではなく、同期処理になります。
# stream_with_contextインポート
from flask import Flask, stream_with_context
#時間がかかる処理関数
def download_mp3(url, file_name):
yield "Start:<br>"
ins = networkmusic(url, file_name)
ins.download()
yield "END"
# ルーティング関数
@app.route('/download', methods=['POST'])
def download():
if request.method =="POST":
url = request.form.get("url")
tp = request.form.get("tp")
file_name = request.form.get('file_name')
if len(url) >=1 and len(file_name) >=1 :
# streamを使ったWebの更新
return app.response_class(stream_with_context(download_mp3(url,file_name)))
else:
pass
実行結果
メリット
・実装が簡単
・非同期処理の実装が不要
・リアルタイムで処理結果が見れる
デメリット
・UIがダサい
※ただし、よりよい改善方法が見つかれば、少し良いUIを実装することも可能
別解
FlaskのResponseを使用しても同様な効果が得られる
from flask import Flask, Response
return Response(download_mp3(url,file_name), mimetype='text/event-stream')
参考文献
Flask 公式ページ
https://flask.palletsprojects.com/en/2.1.x/patterns/streaming/