文章内容

2022/10/10 21:09:51,作 者: 黄兵

Flask 下载进度示例

最近需要使用 Flask 完成一个加载进度的任务。主要是后端通过其他途径下载视频,在前端显示进度。

这里主要的问题是:前端如何获取进度?后端如何在主线程之外新增一个线程下载文件,并返回进度?

由于项目有些复杂,我找到了一个精简的示例代码,如下:

import random
import threading
import time

from flask import Flask


class ExportingThread(threading.Thread):
    def __init__(self):
        self.progress = 0
        super().__init__()

    def run(self):
        # Your exporting stuff goes here ...
        for _ in range(10):
            time.sleep(1)
            self.progress += 10


exporting_threads = {}
app = Flask(__name__)
app.debug = True


@app.route('/')
def index():
    global exporting_threads

    thread_id = random.randint(0, 10000)
    exporting_threads[thread_id] = ExportingThread()
    exporting_threads[thread_id].start()

    return 'task id: #%s' % thread_id


@app.route('/progress/<int:thread_id>')
def progress(thread_id):
    global exporting_threads

    return str(exporting_threads[thread_id].progress)


if __name__ == '__main__':
    app.run()

这里首先设置了一个全局变量:exporting_threads,主要是作用是线程 id 字典。

随机生成一个线程 id,之后通过主线程传递给前端,同时运行另外一个耗时的线程,前端拿到这个线程 id,之后根据线程 id,获取进度。

前端代码示例:

var interval = setInterval(update_progress, 1000);
function update_progress() {
     $.get('/progress/'+thread_id).done(function(n){
         n = n / 5;  // percent value
         if (n == 100) {
            clearInterval(interval);
            callback(); // user defined
         }
         $('.progress-bar').animate({'width': n +'%'}).attr('aria-valuenow', n);    
     }).fail(function() {
         clearInterval(interval);
         displayerror(); // user defined
     });
}

通过上面的示例代码,主要是设置定时器,每隔 1s 使用线程 id,查询获取到的进度。

再结合我们前面介绍的:Material Design Progress indicators Demo,就可以做出一个好看的进度效果了。

这就是一个主要的逻辑。


参考资料:

1、Flask App: Update progress bar while function runs

2、How to create a progress bar using flask? [duplicate]


黄兵个人博客原创。

转载请注明出处:黄兵个人博客 - Flask 下载进度示例

分享到:

发表评论

评论列表