タグ: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アプリ上でも簡易的に進捗状況が目視確認できます。
