Flask App:功能运行时更新进度栏

我正在Flask中构建一个相当简单的WebApp,该WebApp通过网站的API执行功能。我的用户使用他们的帐户URL和API令牌填写表单;当他们提交表单时,我有一个Python脚本,可通过API从其帐户中导出PDF。此功能可能需要很长时间,因此我想在表单页面上显示引导进度条,以指示脚本在过程中进行的进度。我的问题是函数运行时如何更新进度条?这是我在说的简化版本。

views.py:

@app.route ('/export_pdf', methods = ['GET', 'POST'])

def export_pdf():

form = ExportPDF()

if form.validate_on_submit():

try:

export_pdfs.main_program(form.account_url.data,

form.api_token.data)

flash ('PDFs exported')

return redirect(url_for('export_pdf'))

except TransportException as e:

s = e.content

result = re.search('<error>(.*)</error>', s)

flash('There was an authentication error: ' + result.group(1))

except FailedRequest as e:

flash('There was an error: ' + e.error)

return render_template('export_pdf.html', title = 'Export PDFs', form = form)

export_pdf.html:

{% extends "base.html" %}

{% block content %}

{% include 'flash.html' %}

<div class="well well-sm">

<h3>Export PDFs</h3>

<form class="navbar-form navbar-left" action="" method ="post" name="receipt">

{{form.hidden_tag()}}

<br>

<div class="control-group{% if form.errors.account_url %} error{% endif %}">

<label class"control-label" for="account_url">Enter Account URL:</label>

<div class="controls">

{{ form.account_url(size = 50, class = "span4")}}

{% for error in form.errors.account_url %}

<span class="help-inline">[{{error}}]</span><br>

{% endfor %}

</div>

</div>

<br>

<div class="control-group{% if form.errors.api_token %} error{% endif %}">

<label class"control-label" for="api_token">Enter API Token:</label>

<div class="controls">

{{ form.api_token(size = 50, class = "span4")}}

{% for error in form.errors.api_token %}

<span class="help-inline">[{{error}}]</span><br>

{% endfor %}

</div>

</div>

<br>

<button type="submit" class="btn btn-primary btn-lg">Submit</button>

<br>

<br>

<div class="progress progress-striped active">

<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">

<span class="sr-only"></span>

</div>

</form>

</div>

</div>

{% endblock %}

和export_pdfs.py:

def main_program(url, token):

api_caller = api.TokenClient(url, token)

path = os.path.expanduser('~/Desktop/'+url+'_pdfs/')

pdfs = list_all(api_caller.pdf.list, 'pdf')

total = 0

count = 1

for pdf in pdfs:

total = total + 1

for pdf in pdfs:

header, body = api_caller.getPDF(pdf_id=int(pdf.pdf_id))

with open('%s.pdf' % (pdf.number), 'wb') as f:

f.write(body)

count = count + 1

if count % 50 == 0:

time.sleep(1)

在最后一个函数中,我具有要导出的PDF总数,并且在处理过程中有一个持续计数。如何将当前进度发送到我的.html文件以适合进度栏的’style =’标签?最好以一种方式,我可以将相同的工具重新用于其他页面上的进度条。让我知道我是否提供了足够的信息。

回答:

最简单的解决方案是在另一个线程中运行导出功能,并让你的客户端通过另一个请求获取进度信息。有多种方法可以处理此特定任务。根据你的需求,你可能会选择一种或多或少复杂的产品。

这是一个关于如何使用线程的非常非常少的示例:

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()

在索引路由(/)中,我们为每个导出任务生成一个线程,然后为该任务返回一个ID,以便客户端以后可以使用进度路由(/ progress / [exporting_thread])检索它。每次认为合适时,导出线程都会更新其进度值。

在客户端,你将获得如下信息(此示例使用jQuery):

function check_progress(task_id, progress_bar) {

function worker() {

$.get('progress/' + task_id, function(data) {

if (progress < 100) {

progress_bar.set_progress(progress)

setTimeout(worker, 1000)

}

})

}

}

如前所述,该示例非常简单,你可能应该使用稍微复杂一些的方法。通常,我们会将特定线程的进度存储在某种数据库或某种类型的缓存中,这样我们就不必依赖共享结构,从而避免了本示例中的大多数内存和并发问题。

以上是 Flask App:功能运行时更新进度栏 的全部内容, 来源链接: utcz.com/qa/422020.html

回到顶部