タグ:Bootstrap4 | Flask
/progress ┗/templates/ ┗index.html ┗app.py上記のようなディレクトリを作成したらプログレスバーはBootstrapを使うのが一番手軽なので CSSとJSのCDNをここから取得
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!-- BootstrapのCDN(CSS)をここに --> </head> <body> <div class="progress_wrap bg-dark m-5"> <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%"> <span class="progress-bar-label mx-2">0%</span> </div> </div> <input type="button" id="ajax" class="btn btn-primary d-block mx-auto" value="処理開始"> <p id="result" class="text-center my-5"></p> <!-- BootstrapのCDN(スクリプト)をここに --> <script> $(function(){ var source = new EventSource("/stream"); source.addEventListener('progress-item', function(event){ $('.progress-bar').css('width', event.data + '%').attr('aria-valuenow', event.data); $('.progress-bar-label').text(event.data + '%'); }, false); source.addEventListener('last-item', function(){ source.close(); $('.progress-bar').css('width', '100%').attr('aria-valuenow', 100); $('.progress-bar-label').text('100%'); }, false); $("#ajax").click(function(){ $.post('/ajax','data=処理開始', null,"json").done(function(data,textStatus,jqXHR) { const result = JSON.parse(data); console.log(result.data) $("#result").html('開始時間:'+ result.start + "<br>終了時間:" + result.end); }).fail(function(jqXHR, textStatus, errorThrown ) { alert("処理失敗") }); }); }); </script> </body> </html>htmlファイルにCDNと上記コードを追記したらビュー部分はOK。
from flask import Flask, Response, request, jsonify, render_template from queue import Queue import time import datetime import json app = Flask(__name__) # 進捗パーセンテージ用キュー queue = Queue() # プログレスバーストリーム @app.route('/stream') def stream(): return Response(event_stream(queue), mimetype='text/event-stream') # Queueの値を取り出してEventSourceの'progress-item'に出力(100だったら'last-item'イベントに出力) def event_stream(queue): while True: persent = queue.get(True) print("progress:{}%".format(persent)) sse_event = 'progress-item' if persent == 100: sse_event = 'last-item' yield "event:{event}\ndata:{data}\n\n".format(event=sse_event, data=persent) # トップページ @app.route("/") def index(): return render_template('index.html') @app.route("/ajax", methods=['POST']) def ajax(): if request.method == 'POST': start = str(datetime.datetime.now()) print("-------------- {} --------------".format(request.form['data'])) """ 処理runner_01が終わったら10%まで進行としてキューに追加 runner_01() queue.put(10) 処理runner_02が終わったら20%まで進行としてキューに追加 runner_02() queue.put(20) ・・・ """ # サンプル用ループ処理(2秒ごとに10パーセントづつ進行) for i in range(10,110,10): queue.put(i) time.sleep(3) end = str(datetime.datetime.now()) result = {"start": start, "end": end } return jsonify(json.dumps(result)) if __name__ == '__main__': app.run(port=5000)
# Flaskを起動 $ python app.pyFlaskを立ち上げたら127.0.0.1:5000にアクセスするとビューページが表示されます。
「処理開始」ボタンをクリックすると3秒ごとに10パーセントづつ進行していきます。
(※ソースコードの処理内容によってはキューの反映がWEBページまで出力されずに飛ばし飛ばしで反映されます。)
動的な進捗反映システムではないですが、ワンライナーで書いたコードに
「今ここまで進んでるよー」の目安を差し込んでるので、
webアプリ上でも簡易的に進捗状況が目視確認できます。