python - 如何在 Flask 网页中创建流?
问题描述
我正在运行一个机器人,我试图将机器人的日志作为 HTML 内容流输出到一个简单的网页(每个日志都以<p>{log}</p>
. 如果我将流输出到路由“/log_stream”然后转到该路由,我可以看到日志并且它们会更新并且一切都按预期工作。但是,我不知道如何将该流合并到另一个网页中。我尝试使用<iframe>
“/log_stream”路由作为 src 嵌入它,但是 iframe 根本不会渲染。知道如何进行这项工作吗?
注意:请不要将其标记为从 Flask 视图流式传输的显示数据的副本,因为它会更新那里的答案要么已过时,要么不正确。尽管您不能在模板在服务器上渲染后直接更新模板,但您绝对可以使用 iframe 或 img 在该模板中嵌入动态内容,就像在本教程中他使用图像动态创建视频流一样。不能动态更新模板本身与不能动态更新该模板中的内容不同。
应用程序.py:
from flask import Flask, render_template
from threading import Thread
from bot import Bot
from logger import Logger
from config import config
application = Flask(__name__)
logger = Logger()
@application.route('/')
def index():
return render_template('index.html.jinja', products=config['targets'], status='running')
@application.route('/log_stream')
def log_stream():
return logger.printerStream()
if __name__ == '__main__':
bot = Bot(logger)
botThread = Thread(target=bot.run)
botThread.start()
application.run(host='0.0.0.0', debug=True)
logger.py(相关部分):
def getLogHTML(self, logObj):
if logObj['type'] == INFO:
return "<p style=\"color:green\">"+logObj['text']+"</p>\n"
if logObj['type'] == WARN:
return "<p style=\"color:yellow\">"+logObj['text']+"</p>\n"
if logObj['type'] == ERROR:
return "<p style=\"color:red\">"+logObj['text']+"</p>\n"
if logObj['type'] == EXCITE:
return "<p style=\"color:blue\">"+logObj['text']+"</p>\n"
return "<p style=\"color:white\">"+logObj['text']+"</p>\n"
def printerStream(self):
self.isStreaming = True
self.logs = self.getStoredLogs()
self.logs.extend(self.secondaryLogs)
self.storeLogs(self.secondaryLogs)
self.secondaryLogs = deque()
def generate():
try:
while True:
if len(self.logsToStore) > 0:
self.storeLogs(self.logsToStore)
self.logsToStore = deque()
nextLog = self.getNextLog()
nextLogHTML = self.getLogHTML(nextLog)
yield nextLogHTML
except GeneratorExit:
self.isStreaming = False
self.isStreaming = False
return Response(generate(), mimetype='text/html') # maybe text/html?
index.html.jinja:
<!doctype html>
<head>
<title>Title</title>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
body {
color: green
}
.title {
display: flex;
flex-direction: row;
justify-content:center
}
h1 {
margin-bottom: 6px;
}
.row {
display: flex;
}
.column {
flex: 50%
}
</style>
</head>
<body>
<div class="title">
<h1>Title</h1>
<h2>Subtitle</h2>
</div>
<div class="row">
<div class="column">
</iframe src="{{ url_for('log_stream')}}">
</div>
<div class="column">
<div class="row">
<div class="column">
<p>Products: </p>
</div>
<div class="column">
{% for product in products %}
<p>{{product.name}}</p>
{% endfor %}
</div>
</div>
<div class="row">
<div class="column">
<p>Status: </p>
</div>
<div class="column">
<p>{{ status }}</p>
</div>
</div>
</div>
</div>
</body>
解决方案
实际上,我通过向<iframe>
. 将其更改为:
<iframe frameborder='0' noresize='noresize'
style='position: absolute; background: transparent; width: 100%; height:100%;'
src="{{ url_for('log_stream')}}"
frameborder="0"></iframe>
几乎完成了我想要的!
推荐阅读
- xcode - XCode 和 RubyMotion - rake 规范 - 权限错误
- c# - 单击母版页上的按钮时,Response.Redirect 不起作用
- java - 位图图像从库中选择未在 android 版本 5.0.2 的 imageview 中显示
- python - 使用 Python 将系统 verilog 打包数组转换为解包数组语法
- generics - 在没有 reified 关键字的 Kotlin 中获取泛型类型参数的运行时类
- newline - 新行在 PHP 5.6 中不起作用
- load-balancing - 负载均衡器是否需要负载均衡器?
- java - ASM - 使用 LocalVariableSorter 中的 newLocal 的奇怪 localVar 索引
- python - SciPy 偏斜法线拟合
- algorithm - IEEE754 单精度 - 表示数字一半的通用算法