我正在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)
}
})
}
}
如前所述,该示例非常简单,你可能应该使用稍微复杂一些的方法。通常,我们会将特定线程的进度存储在某种数据库或某种类型的缓存中,这样我们就不必依赖共享结构,从而避免了本示例中的大多数内存和并发问题。
我想知道是否有人知道一种很好的方法,可以使用Capybara/Browserstack/Cucumber按顺序启动各个浏览器堆栈测试。 我在使用Capybara时遇到了一些问题,因为browserstack不会在每次运行时都使用我的新功能进行更新,即使我关闭了浏览器,也不会更新,即:两次测试在browserstack中顺序启动,但使用相同的浏览器和操作系统设置。 摘要场景:运行登录测试假设我想测试
问题内容: 我正在开始使用Python 3在PyQt5中创建GUI。单击按钮后,我要运行“randomint”函数并将返回的整数显示到名为“lcd”的QLCDNumber。 这是我的代码: 我得到的输出: TypeError:参数1具有意外的类型’NoneType’ 如何获得LCD以显示功能“ randomint”的输出? 问题答案: 问题在于,期望使用插槽(Python可调用对象),但是返回。因
问题内容: 我有一个页面,其中发生了许多耗时的功能。我想做的是在过程的每个步骤完成后,更新网页以使用户知道刚刚完成的步骤。本质上,用户提交查询,然后服务器查询数据库,处理数据,绘制图像并在页面上显示结果。我想让网页说出该功能执行的步骤。它会说“先查询”然后“正在处理” …等等。 伪: 我已经研究过使用Ajax来更新页面而不重新加载它,但是根据我的简单理解(对Ajax零经验),客户端将向服务器请求文
单击应用程序中的“验证”按钮后,我需要将列的值从“0”更改为“1”。 默认情况下,该列保存为“0”。 我需要找到发票的正确ID并更新此值。所以我尝试了这个代码,但是我的更新功能不起作用。 视图:(每个按钮都有我的发票ID) 控制器:(从输入值中查找Id发票) 路线: 错误: 没有模型[App\发票]的查询结果。 编辑谢谢。。。
部署Hyperledger Composer后,您可能希望升级到新版本。要更新已安装的Hyperledger Composer版本,必须卸载客户端、管理员和运行时CLI组件,并使用npm重新安装它们。 过程 1.使用以下命令卸载Hyperledger Composer组件: npm uninstall -g composer-cli npm uninstall -g composer-
问题内容: 在Swift之前,在Objective-C中,我会使用混淆或钩住类中的方法。 如果有人对修改Swift的运行时以及挂钩功能(如CydiaSubstrate)和其他在此方面提供帮助的库有任何信息,请通知我。 问题答案: 我已经在Swift中成功使用方法。本示例说明如何在NSDictionary上挂钩描述方法 我的实现: 混乱的代码: 编辑: 此代码适用于从 NSObject 继承的任何自