本記事の背景
いままで、マルチスレッドのProcessのやり方でFlaskで非同期を実現したが、本記事は、Pythonのasync, awaitを使ったやり方で実現する
Pythonでのawait, asyncとは
下記の記事が非常にわかりやすく解説しています。
https://qiita.com/maueki/items/8f1e190681682ea11c98
筆者が作成したコードの構成が同期処理としてとらえています。
つまり、下記の処理は順番に行われているからです。
ダウンロードボタンを押下→ダウンロード処理→ダウンロード完了
Flask内で存在しているタスクについて
- ダウンロード処理タスク
- ダウンロード処理中のページの表示
- ダウンロード処理が完了したページの表示
筆者は上記の3つの処理をタスクとして捉えているが、
ダウンロード処理は関数として定義できていることに対して、
ページの表示に関しては、下記のような実装されているため、実際にタスクとして定義する関数になりえないと考えています。
#
def foo():
return render_template('finish.html')
def bar():
return render_template('downloading.html')
実装コード
上記の理由により、筆者は、ダウンロードボタン押下後にダウンロード終了するまでは、ページの遷移を行わず、ダウンロード完了後にページが遷移するという実装にしました。
async def download_mp3(url, file_name):
ins = networkmusic(url, file_name)
ins.download()
@app.route('/download', methods=['POST'])
def async_download():
form = DownloadForm()
if request.method =="POST":
url = request.form.get("url")
tp = request.form.get("tp")
file_name = request.form.get('file_name')
if tp == 'mp3' and len(url) > 1:
# 新規のイベントループを作成する
loop = asyncio.new_event_loop()
# 同期の場合(1)
loop.run_until_complete(download_mp3(url,file_name))
# 同期の場合(2)
# task_1 = loop.create_task(download_mp3(url,file_name))
# loop.run_until_complete(asyncio.gather(task_1))
return render_template('finish.html')
ダウンロード完了
参考文献