python - 在烧瓶 api 中实际响应之前发送确认消息
问题描述
我正在做一个项目,客户端发送一些图像并基于这些图像生成一个 3D 网格,并在整个过程完成后返回“网格生成”消息。
目前,单个进程大约需要半个小时。并且执行时间会根据请求增加,因为生成网格软件一次只运行一次,所以其他请求必须等待执行。
我想向客户端发送一条消息,说明他们的图像已在网格创建后生成的实际响应之前上传,这样,用户不必等待太久而没有服务器端的任何响应。
我一直在研究简单的烧瓶 api 应用程序。以下是到目前为止的代码。
import os
import urllib.request
from flask import Flask, request, redirect, jsonify
from werkzeug.utils import secure_filename
from datetime import datetime
# import threading
from time import sleep
from flask_socketio import SocketIO, emit
UPLOAD_FOLDER = r'C:\Users\Pro-MechPC5\Desktop\ImageTest\Server\upload'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
app = Flask(__name__)
# socketio = SocketIO(app)
# @socketio.on('connect')
# def connect():
# emit('message', {'hello': "Hello"})
#app.secret_key = "secret key"
# app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/get_files', methods=['POST'])
def upload_file():
info = dict(request.form.items())
print(list(info.keys()))
keys = list(info.keys())
if 'meshname' not in keys:
resp = jsonify({'message' : 'Please provide us your meshname.'})
resp.status_code = 400
return resp
if 'email' not in keys:
resp = jsonify({'message' : 'Please provide us your email id.'})
resp.status_code = 400
return resp
# check if the post request has the file part
if 'files[]' not in request.files:
resp = jsonify({'message' : 'No file part in the request'})
resp.status_code = 400
return resp
files = request.files.getlist('files[]')
# datetime object containing current date and time
now = datetime.now()
# dd/mm/YY H:M:S
email_id = info['email'].split('@')[0]
sub_foldername = str(now.timestamp()) + '_' + info['meshname'] + '_' + email_id
print(sub_foldername)
folder_name = UPLOAD_FOLDER + '\\' + sub_foldername
if not os.path.exists(folder_name):
os.makedirs(folder_name)
print(folder_name)
app.config['folder_name'] = folder_name
errors = {}
success = False
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['folder_name'], filename))
success = True
else:
errors[file.filename] = 'File type is not allowed'
if success and errors:
errors['message'] = 'File(s) successfully uploaded'
resp = jsonify(errors)
resp.status_code = 500
return resp
if success:
resp = jsonify({'message' : 'Files successfully uploaded'})
resp.status_code = 201
print()
print("***************Starting MeshGen******************")
# threading.Thread(target=create_mesh).start()
#Send message (Images uploaded successfully, Mesh creation is in progress) here.
create_mesh()
print()
return resp
else:
resp = jsonify(errors)
resp.status_code = 500
return resp
def create_mesh():
print("Started Task ....")
# print(threading.current_thread().name)
sleep(10)
print('completed')
if __name__ == "__main__":
app.run(debug=True)
我尝试通过将实际的网格创建作为后台任务运行并立即发送响应来使用线程。但是,它引起了一个问题,即当有多个请求时,它为网格生成创建了多个线程,这使得所有请求并行工作,因此,所有用户都必须等待几乎相同的时间,这是我不想要的。我想以先进先出的方式执行请求。
我研究了 celery、socketio 和烧瓶,但我找不到好的参考或正确理解这些库,因为我之前没有使用烧瓶及其库的经验。
那么,我怎么能在最终响应之前向客户端发送一些消息。或者,可以说,我如何在烧瓶中为单个请求发送多个响应。
或者如何为线程生成队列(最终选项,我认为这会更复杂),以便一次只运行一个线程。
解决方案
推荐阅读
- java - API 29 (Android Q) 中未创建目录
- google-cloud-platform - 如何禁用 GCP 服务帐号来创建 VM 实例?
- android - 在回收站视图中从 firebase 数据库中检索图像和名称
- javascript - 我想在打字稿的导航选项卡之间切换
- javascript - 在过滤器中选择性地返回部分匹配对象
- r - 数据框上的 R 优化
- python - 在窗口动作odoo中调用Python函数
- events - GA 转化跟踪
- r - 在树状图中更改分支长度(pheatmap)
- visual-studio - Visual Studio - TFS 的源代码管理资源管理器 - 如何查看哪个变更集是您的本地副本