- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作我的第一个 flask /python 网络应用程序。该应用程序最初显示一个邀请用户填写的表单,然后他们单击“提交”按钮,然后服务器运行模拟并创建一个带有显示结果的图形的 PNG 文件,最后页面被重绘显示的图表。我的python代码大致是这种形式:
# flask_app.py
@app.route("/", methods=["POST", "GET"])
def home():
if request.method == 'POST':
# bunch of request.form things to scoop the contents of the form
if form_answers_all_good:
for i in range(huge_number):
# some maths
# create png file with results
return render_template("index.htm", foo=bar)
huge_number
循环可能需要几十秒。所以我想要的是某种进度指示器——它不一定是一个漂亮的动画——即使是百分比进度的字符串读数也可以。
for i in range(huge_number):
# some maths
percentage_done = str(i * 100/huge_number)
percentage_done
所以我放了类似的东西:
Completed {% percentage_done %}% so far.
index.htm
.顺便说一句,我对 Javascript、AJAX 之类的知识或想到它,客户端上的几乎所有东西(除了 HTML)都是初学者水平。
pythonanywhere.com
上托管我的网络应用程序.包含的模块列表是
here .
最佳答案
你提到你是 flask 的新手,所以我假设你是 flask 的新手,但对 python 很熟悉,而且你对可以使用的东西非常有限,因为你在使用 pythonanywhere。主要的事情之一是它是单线程的,因此很难扩展任何东西。此外,最好坚持使用纯 python,因为在任何地方管理 python 中的依赖项将是一个额外的问题,最终只使用 python 内置函数是可行的。
我专注于展示一个可行的解决方案,您可以简单地在 pythonanywhere 或本地复制和粘贴,而不是显示代码片段。我会试着去:
flask_app.py
和
index.html
from queue import Queue
import time
import random
import threading
from PIL import Image
import flask
from flask import request
import json
import io
import uuid
import base64
### You create a Queue and start a scheduler, Start flask after that
def run_scheduler(app):
sleep_time = 5
while True:
time.sleep(sleep_time)
print("\n"*5)
print(f'images Completed:{app.images_completed}')
print('-----'*20)
if(app.images_toBe_processed.qsize() > 0):
next_image_name = app.images_toBe_processed.get()
print(f"No Images being processed so scheduler will start processing the next image {next_image_name} from the queue")
app.function_to_process_image(next_image_name, app)
else:
pass
def function_to_process_image(image_name, app):
huge_number = 5
R = random.randint(0,256)
G = random.randint(0,256)
B = random.randint(0,256)
for i in range(huge_number):
# some maths
percentage_done = str((i+1)*100/huge_number)
app.images_processing_status[image_name] = percentage_done
time.sleep(1)
app.images_processing_status[image_name] = str(100.0)
img = Image.new('RGB', (60, 30), color =(R,G,B))
b=io.BytesIO()
img.save(b, "jpeg")
app.images_completed[image_name] = {"status":1,"file": b}
print(f"IC from function: {app.images_completed} **************************")
if app.images_processing_status.get("!!total!!",False): app.images_processing_status["!!total!!"]+= 1
else: app.images_processing_status["!!total!!"] = 1
del app.images_processing_status[image_name]
return 0 #process sucessful
class Webserver(flask.Flask):
def __init__(self,*args,**kwargs):
scheduler_func = kwargs["scheduler_func"]
function_to_process_image = kwargs["function_to_process_image"]
queue_MAXSIZE = kwargs["queue_MAXSIZE"]
del kwargs["function_to_process_image"], kwargs["scheduler_func"], kwargs["queue_MAXSIZE"]
super(Webserver, self).__init__(*args, **kwargs)
self.start_time = time.strftime("%d/%m/%Y %H:%M")
self.queue_MAXSIZE = queue_MAXSIZE
self.active_processing_threads = []
self.images_processing_status = {}
self.images_completed = {}
self.images_toBe_processed = Queue(maxsize=queue_MAXSIZE)
self.function_to_process_image = function_to_process_image
self.scheduler_thread = threading.Thread(target=scheduler_func, args=(self,))
app = Webserver(__name__,
template_folder="./templates",
static_folder="./",
static_url_path='',
scheduler_func = run_scheduler,
function_to_process_image = function_to_process_image,
queue_MAXSIZE = 20,
)
### You define a bunch of views
@app.route("/",methods=["GET"])
def send_index_view():
if not flask.current_app.scheduler_thread.isAlive():
flask.current_app.scheduler_thread.start()
return flask.render_template('index.html',queue_size = flask.current_app.images_toBe_processed.qsize(),
max_queue_size =flask.current_app.queue_MAXSIZE , being_processed=len(flask.current_app.active_processing_threads),
total=flask.current_app.images_processing_status.get("!!total!!",0), start_time=flask.current_app.start_time )
@app.route("/process_image",methods=["POST"])
def receive_imageProcessing_request_view():
image_name = json.loads(request.data)["image_name"]
if(flask.current_app.images_toBe_processed.qsize() >= flask.current_app.queue_MAXSIZE ):
while(not flask.current_app.images_toBe_processed.empty()):
flask.current_app.images_toBe_processed.get()
requestedImage_status = {"name":image_name, "id":uuid.uuid1()}
flask.current_app.images_toBe_processed.put(image_name)
return flask.jsonify(requestedImage_status)
@app.route("/check_image_progress",methods=["POST"])
def check_image_progress():
print(f'Current Image being processed: {flask.current_app.images_processing_status}')
print(f'Current Images completed: {flask.current_app.images_completed}')
image_name = json.loads(request.data)["image_name"]
is_finished = flask.current_app.images_completed \
.get(image_name,{"status":0,"file": ''})["status"]
requestedImage_status = {
"is_finished": is_finished,
"progress": flask.current_app.images_processing_status.get(image_name,"0")
}
return flask.jsonify(requestedImage_status) #images_processing_status[image_name]})
@app.route("/get_image",methods=["POST"])
def get_processed_image():
image_name = json.loads(request.data)["image_name"]
file_bytes = flask.current_app.images_completed[image_name]["file"] #open("binary_image.jpeg", 'rb').read()
file_bytes = base64.b64encode(file_bytes.getvalue()).decode()
flask.current_app.images_completed.clear()
return flask.jsonify({image_name:file_bytes}) #images_processing_status[image_name]})
<html>
<head>
</head>
<body>
<h5> welcome to the index page, give some inputs and get a random RGB image back after some time</h5>
<h5> Wait 10 seconds to be able to send an image request to the server </h5>
<h5>When the page was loaded there were {{queue_size}} images on the queue to be processed, and {{being_processed}} images being processed</h5>
<h5> The max size of the queue is {{max_queue_size}}, and it will be reseted when reaches it</h5>
<h5>A total of {{total}} images were processed since the server was started at {{start_time}}</h5>
<form>
<label for="name">Image name:</label><br>
<input type="text" id="name" name="name" value="ImageName" required><br>
</form>
<button onclick="send();" disabled>Send request to process image </button>
<progress id="progressBar" value="0" max="100"></progress>
<img style="display:block" />
<script>
window.image_name = "";
window.requests = "";
function send(){
var formEl = document.getElementsByTagName("form")[0];
var input = formEl.getElementsByTagName("input")[0];
var RegEx = /^[a-zA-Z0-9]+$/;
var Valid = RegEx.test(input.value);
if(Valid){
window.image_name = input.value;
var xhttp = new XMLHttpRequest();
xhttp.onload = function() {
result=JSON.parse(xhttp.response)
window.requests = setTimeout(check_image_progress, 3000);
};
xhttp.open("POST", "/process_image", true);
xhttp.send(JSON.stringify({"image_name":input.value}));
var buttonEl = document.getElementsByTagName("button")[0];
buttonEl.disabled = true;
buttonEl.innerHTML = "Image sent to process;only one image per session allowed";
}
else{
alert("input not valid, only alphanumeric characters");
}
}
function check_image_progress(){
var xhttp = new XMLHttpRequest();
xhttp.onload = function() {
result=JSON.parse(xhttp.response)
var progressBarEl = document.getElementsByTagName("progress")[0];
if(progressBarEl.value < result["progress"]){
progressBarEl.value=result["progress"];
} else {}
if(result["is_finished"] == true){
clearTimeout(window.requests);
window.requests = setTimeout(get_image,5);
}
else {
window.requests = setTimeout(check_image_progress, 3000);
}
};
xhttp.open("POST", "/check_image_progress", true);
xhttp.send(JSON.stringify({"image_name":window.image_name}));
}
function get_image(){
var xhttp = new XMLHttpRequest();
xhttp.onload = function() {
result=JSON.parse(xhttp.response)
img_base64 = result[window.image_name];
var progressBarEl = document.getElementsByTagName("progress")[0];
progressBarEl.value=100;
clearTimeout(window.requests);
var imgEl = document.getElementsByTagName("img")[0];
console.log(result)
imgEl.src = 'data:image/jpeg;base64,'+img_base64;
};
xhttp.open("POST", "/get_image", true);
xhttp.send(JSON.stringify({"image_name":window.image_name}));
}
setTimeout(function(){document.getElementsByTagName("button")[0].disabled=false;},100);
function hexToBase64(str) {
return btoa(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
</script>
</body>
</html>
web
中的 Web 应用程序选项卡wsgi
开始您的flask app
,它基本上会导入你的app
来自 flask_app.py
并运行它。 wsgi
在您的 /home/{username}
中运行文件夹而不是 /home/{username}/{flask_folder}
,您可以根据需要更改此设置。 Threads
, Flask
将在 wsgi
运行的主线程中我们将运行一个子线程scheduler
这将跟踪 Queue
并安排下一个要处理的图像。 Flask
类:app,处理用户请求并将处理请求发送到Queue
的组件Queue
, 一个 Queue按顺序存储用户处理图像的请求Scheduler
, 决定是否可以运行新函数 process_image 调用以及是否可以运行的组件。需要独立运行Thread
比 flask 。 Webserver
然后能够轻松访问(pythonanywhere 使用 wsgi,这使得跟踪本地创建的变量变得困难)#lot of imports
+-- 14 lines: from queue import Queue-----------------------------------------------------------------------------------------
# this function will check periodically if there's no images being processed at the moment.
# if no images are being processed check in the queue if there's more images to be processd
# and start the first one in the queue
def run_scheduler(app):
+-- 12 lines: sleep_time = 5 -------------------------------------------------------------------------------------------------
# this function do the math and creates an random RGB image in the end.
def function_to_process_image(image_name, app):
+-- 21 lines: {---------------------------------------------------------------------------------------------------------------
# This class encapsulates all the data structures("state") from our application
# in order to easily access the progress and images information
class Webserver(flask.Flask):
def __init__(self,*args,**kwargs):
+-- 13 lines: scheduler_func = kwargs["scheduler_func"]-----------------------------------------------------------------------
# Here we're instatiating the class
app = Webserver(__name__,
+-- 5 lines: template_folder="./templates",----------------------------------------------------------------------------------
queue_MAXSIZE = 20,
)
### You define a bunch of views
+-- 39 lines: @app.route("/",methods=["GET"]) --------------------------------------------------------------------------------
send
当用户点击 send request to process image
时触发的函数按钮 check_progress
由 send function
触发的函数反复请求 check_progress
在 flask 中查看以获取有关进度的信息。处理结束后,我们删除重复。 get_image
由 check_progress
触发的函数处理结束时 ('is_finished' = 1) <html>
<head>
</head>
<body>
<!-- JUST THE INITIAL HTML elements -->
+-- 12 lines: <h5> welcome to the index page, give some inputs and get a random RGB image back after some time</h5>-----------
<script>
window.image_name = "";
window.requests = "";
function send(){
// SEND image process request when click button and set a timer to call periodically check_image_process
+-- 20 lines: var formEl = document.getElementsByTagName("form")[0];----------------------------------------------------------
}
function check_image_progress(){
// SEND a request to get processing status for a certain image_name
+-- 18 lines: var xhttp = new XMLHttpRequest();-------------------------------------------------------------------------------
}
function get_image(){
// SEND a request to get the image when image_status 'is_processed' = 1
+--- 13 lines: var xhttp = new XMLHttpRequest();------------------------------------------------------------------------------
}
setTimeout(function(){document.getElementsByTagName("button")[0].disabled=false;},100);
</script>
</body>
</html>
关于python - 如何让客户端使用 flask 从服务器读取变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61292483/
谁能解释一下 Server.MapPath(".")、Server.MapPath("~")、Server.MapPath(@"之间的区别\") 和 Server.MapPath("/")? 最佳答案
我不知道,为什么我们要使用 Server.UrlEncode() & Server.UrlDecode()?!在 QueryString 中我们看到 URL 中的任何内容,那么为什么我们要对它们进行编
我已经通过 WHM 在我的一个域上安装了 ssl 证书。网站正在使用 https://xyz.com . 但是它不适用于 https://www.xyz.com .我已经检查了证书,它也适用于 www
我已经使用 WMI 检测操作系统上是否存在防病毒软件,itz 正常工作并通过使用命名空间向我显示防病毒信息,例如 win xp 和 window7 上的名称和实例 ID:\root\SecurityC
我们有 hive 0.10 版本,我们想知道是否应该使用 Hive Server 1 或 Hive Server2。另一个问题是连接到在端口 10000 上运行的 Hive 服务器,使用 3rd 方工
我想在 C++ 中使用 Windows Server API 设置一个 HTTPS 服务器,我使用了示例代码,它在 HTTP 上工作正常,但我就是不能让它在 HTTPS 上工作。 (我不想要客户端 S
我写了一个非常基本的类来发送电子邮件。我用 smtp 服务器对其进行了测试,它工作正常,但是当我尝试使用我公司的交换服务器时,它给出了这个异常: SMTP 服务器需要安全连接或客户端未通过身份验证。服
我的应用程序包含一个“网关”DataSnap REST 服务器,它是所有客户端的第一个访问点。根据客户端在请求中传递的用户名(基本身份验证),请求需要重定向到另一个 DataSnap 服务器。我的问题
我有一个 Tomcat 服务器和一个 Glassfish4 服务器。我的 Servlet 在 Tomcat 服务器上启动得很好,但在 Glassfish4 服务器上给我一个“HTTP Status 4
我在 vmware 上创建了一个 ubuntu 服务器。我用它作为文件服务器。如果我通过托管虚拟机的计算机进行连接,则可以访问它。我无法从同一网络上的其他计算机执行此操作。提前致谢! 最佳答案 首先确
如何重启 Rails 服务器?我从 开始 rails server -d 所以服务器是分离的 我知道的唯一方法就是去做ps 辅助 | grep rails 并 kill -9关于过程#但是像这样杀死进
我实际上正在尝试找到编写一个简单的 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的服务器。我只关心XMPP的核心功能(状态、消息传递、群组消息传递)。目前还在学习 XMPP 协议(proto
我实际上正在尝试找到编写简单 XMPP 服务器的最佳方法,或者找到一个占用空间非常小的方法。我只关心 XMPP 的核心功能(统计、消息、组消息)。目前也在学习 XMPP 协议(protocol),所以
我们正在尝试从 Java JAX-RS 适配器访问 SOAP 1.1 Web 服务。 我们正在使用从 WSDL 生成的 SOAP 客户端。 但是当解码 SOAP 故障时,我们得到以下异常: ... C
目前,我和许多其他人正在多个平台(Windows、OS X 和可能的 Linux)上使用 Python HTTP 服务器。我们正在使用 Python HTTP 服务器来测试 JavaScript 游戏
我有一个连续运行的服务器程序(C#/.NET 2.0 on Linux with mono),我想从 PHP 脚本连接到它以在网站上显示状态信息。 目的是创建一个(某种)实时浏览器游戏(无 Flash
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
我们刚刚将测试 Web 服务器从 Server 2008 升级到 Server 2012 R2。我们有一个部署我们网站的批处理脚本。当它将站点推送到服务器时,它现在失败了。奇怪的是,我可以使用相同的发
建议一些加载SpagoBI服务器的方法,我尝试了所有方法来解析spagobi服务器。在 Catalina 中,错误是 - * SEVERE: Unable to process Jar entry [
当我们点击应用程序服务器(apache tomcat)时,它会创建一个线程来处理我们的请求并与 tomcat 连接,建立连接,tomcat 创建另一个线程来处理请求并将其传递给连接,连接线程将其传递给
我是一名优秀的程序员,十分优秀!