【发布时间】:2021-05-29 06:26:51
【问题描述】:
我正在 Flask 中构建一个相当简单的 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=”标签?最好以一种我可以在其他页面上为进度条重用相同工具的方式。如果我没有提供足够的信息,请告诉我。
【问题讨论】:
-
我不想给出一个编码的答案,但让我为您指出一个解决方案。一种传统的想法是启动一个线程来进行 pdf 导出。该线程将进度报告给数据库表。您的浏览器前端执行 ajax 轮询以从数据库中获取进度值。作为 ajax 轮询的替代方案,您可能希望查看 flask-socketio 以将进度值向下推送到您的浏览器。这种替代方案可能需要更多的工程努力。
-
@chfw 的想法是你应该如何处理它。但与其说是线程,不如说它应该是一个等待作业的额外进程。而不是数据库,我会使用 Redis 之类的东西并通过消息队列进行通信。最后,我推荐SSE,而不是使用 AJAX 或 WebSockets,这更容易设置。
-
@FreshCrichard - 你是如何让它最终运行的?
标签: python flask progress-bar