Log*_*ang 10 python ajax flask pandas tqdm
我已经搜寻了一段时间,却想不出办法。我有一个简单的Flask应用程序,它需要一个CSV文件,将其读入Pandas数据框,将其转换并输出为新的CSV文件。我已经成功上传并成功使用HTML进行了转换
<div class="container">
<form method="POST" action="/convert" enctype="multipart/form-data">
<div class="form-group">
<br />
<input type="file" name="file">
<input type="submit" name="upload"/>
</div>
</form>
</div>
Run Code Online (Sandbox Code Playgroud)
单击“提交”后,它将在后台运行转换一段时间,并在完成后自动触发下载。接受result_df并触发下载的代码如下所示
@app.route('/convert', methods=["POST"])
def convert(
if request.method == 'POST':
# Read uploaded file to df
input_csv_f = request.files['file']
input_df = pd.read_csv(input_csv_f)
# TODO: Add progress bar for pd_convert
result_df = pd_convert(input_df)
if result_df is not None:
resp = make_response(result_df.to_csv())
resp.headers["Content-Disposition"] = "attachment; filename=export.csv"
resp.headers["Content-Type"] = "text/csv"
return resp
Run Code Online (Sandbox Code Playgroud)
我想添加一个进度条,pd_convert
从本质上来说这是一个熊猫应用操作。我发现该方法tqdm
现在可用于熊猫,并且它具有progress_apply
而不是的方法apply
。但是我不确定是否与在网页上制作进度条有关。我猜应该是因为它可以在Jupyter笔记本上使用。如何pd_convert()
在此处添加进度栏?
我想要的最终结果是:
现在完成1和2。接下来的问题是如何触发下载。现在,我的convert
函数可以毫无问题地触发下载,因为响应是由文件组成的。如果要渲染页面,请使用进行响应return render_template(...)
。由于我只能有一个回复,因此仅通过一个呼叫就可以有3和4 /convert
吗?
不是Web开发人员,仍在学习基础知识。提前致谢!
====编辑====
我在这里尝试了一些修改的示例。我从数据帧上for循环中的行索引中获取进度,并将其放入Redis中。客户端通过询问此新端点,从流中获得Redis的进度/progress
。就像是
@app.route('/progress')
def progress():
"""Get percentage progress for the dataframe process"""
r = redis.StrictRedis(
host=redis_host, port=redis_port, password=redis_password, decode_responses=True)
r.set("progress", str(0))
# TODO: Problem, 2nd submit doesn't clear progress to 0%. How to make independent progress for each client and clear to 0% on each submit
def get_progress():
p = int(r.get("progress"))
while p <= 100:
p = int(r.get("progress"))
p_msg = "data:" + str(p) + "\n\n"
yield p_msg
logging.info(p_msg)
if p == 100:
r.set("progress", str(0))
time.sleep(1)
return Response(get_progress(), mimetype='text/event-stream')
Run Code Online (Sandbox Code Playgroud)
它目前正在运行,但存在一些问题。原因肯定是我对这种解决方案缺乏了解。
问题:
submit
按下按钮时将进度重置为0 。我尝试了几个地方将其重置为0,但尚未找到有效的版本。这与我对流的工作原理缺乏了解有关。现在,它仅在刷新页面时重置。job_id
为每个submit
事件提供随机数,并使其成为Redis的关键。由于完成每个作业后都不需要该条目,因此我将在完成后删除该条目。我觉得我缺少的部分是对的理解text/event-stream
。感觉我已经接近可行的解决方案。请分享您对执行此操作的“正确”方法的看法。我只是在猜测并试图将一些我非常有限的理解有效的东西组合在一起。
好的,我缩小了我所缺少的问题并弄清楚了。我需要的概念包括
后端
/progress
可以为事件流查询进度(HTML5)text/event-stream
MIME类型响应前端
示例HTML
<script>
function getProgress() {
var source = new EventSource("/progress");
source.onmessage = function(event) {
$('.progress-bar').css('width', event.data+'%').attr('aria-valuenow', event.data);
$('.progress-bar-label').text(event.data+'%');
// Event source closed after hitting 100%
if(event.data == 100){
source.close()
}
}
}
</script>
<body>
<div class="container">
...
<form method="POST" action="/autoattr" enctype="multipart/form-data">
<div class="form-group">
...
<input type="file" name="file">
<input type="submit" name="upload" onclick="getProgress()" />
</div>
</form>
<div class="progress" style="width: 80%; margin: 50px;">
<div class="progress-bar progress-bar-striped active"
role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
<span class="progress-bar-label">0%</span>
</div>
</div>
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
示例后端Flask代码
redis_host = "localhost"
redis_port = 6379
redis_password = ""
r = redis.StrictRedis(
host=redis_host, port=redis_port, password=redis_password, decode_responses=True)
@app.route('/progress')
def progress():
"""Get percentage progress for auto attribute process"""
r.set("progress", str(0))
def progress_stream():
p = int(r.get("progress"))
while p < 100:
p = int(r.get("progress"))
p_msg = "data:" + str(p) + "\n\n"
yield p_msg
# Client closes EventSource on 100%, gets reopened when `submit` is pressed
if p == 100:
r.set("progress", str(0))
time.sleep(1)
return Response(progress_stream(), mimetype='text/event-stream')
Run Code Online (Sandbox Code Playgroud)
剩下的就是熊猫写循环到Redis的代码。
我从Googling的几个小时中收集了很多结果,所以我觉得最好在此记录那些也需要此基本功能的人员:在Flask Web应用程序中添加进度栏以处理Pandas数据框。
一些有用的参考
• https://medium.com/code-zen/python-generator-and-html-server-sent-events-3cdf14140e56
• https://codeburst.io/polling-vs-sse-vs-websocket-how-to-choose-the-right-one-1859e4e13bd9
• 什么是长轮询,Websocket,服务器发送事件(SSE)和Comet?
归档时间: |
|
查看次数: |
553 次 |
最近记录: |