flask 散景服务器 - 图甚至不在本地呈现
flask bokeh server - figure does not render even locally
我不能 运行 在 Apache 后面的 Flask 中使用散景服务器,所以现在我正在尝试在本地的 Flask 中提供散景服务。该图不渲染。
这是烧瓶代码:
from flask import Flask, render_template
app = Flask(__name__)
from bokeh.embed import server_document
@app.route("/")
def techblog():
try:
tag = server_document(url=r'/bokeh', relative_urls=True)
return render_template('techblog.html', tag=tag)
except Exception as e:
return str(e)
if __name__ == '__main__':
app.run(debug=True)
这是散景代码:
from numpy.random import random
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox
from bokeh.models import Button, ColumnDataSource
from bokeh.server.server import Server
def run(doc):
fig = figure(title='random data', width=400, height=200, tools='pan,box_zoom,reset,save')
source = ColumnDataSource(data={'x': [], 'y': []})
fig.line('x', 'y', source=source)
def click(n=100):
source.data = {'x': range(n), 'y': random(n)}
button = Button(label='update', button_type='success')
button.on_click(click)
layout = column(widgetbox(button), fig)
doc.add_root(layout)
click()
# configure and run bokeh server
kws = {'port': 5000, 'prefix':'/bokeh','allow_websocket_origin': ['127.0.0.1']}
server = Server(run, **kws)
server.start()
# if __name__ == '__main__':
server.io_loop.add_callback(server.show, '/')
server.io_loop.start()
这是我的 html 模板:
<h1 style='color:blue'>Hello There!</h1>
</br>
{{ tag|safe }}
</br>
{{ tag }}
我通过 python 运行ning Flask 应用程序。在一个单独的命令处理器上,我 运行 散景应用程序通过,
bokeh serve --allow-websocket-origin=localhost:5000 filename.py
我只得到没有"safe"的标签,因为
<script src="/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh" id="1001"></script>
我在 Flask 控制台上收到了这条消息。这是一个标准的 404:
"GET /bokeh/autoload.js?bokeh-autoload-element=1000&bokeh-app-path=/bokeh HTTP/1.1" 404 -
就这些了。没有图形或按钮被呈现。看图应该改什么?
编辑:我已经在散景代码中指定了端口和前缀。结果没有改变。
编辑 2:我在 Flask 控制台上添加了 404 错误的控制台 msj。
有几处错误:
您没有配置端口,因此 Bokeh 服务器将使用其默认端口 5006(不是 5000)
您尚未配置应用程序路径,因此 Bokeh 服务器将从其默认位置 /
(不是 /bokeh
)
[提供应用程序=31=]
还值得一提的是,如果您将 localhost
列入白名单作为允许的 websocket 来源,那么它实际上必须是 URL 栏中的 localhost
(即不是 127.0.0.1,它们在这种情况下不可互换)
最后,将 Bokeh 应用程序代码放入手动调用 Server
的纯 python 脚本中需要做很多额外的工作,等等。您可以将 [=15= 的内容放入] 在一个文件中调用 bokeh serve --port=5000 app.py
然后该应用程序将在 localhost:5000/app
可用
我在@bigreddot 的回答中添加了一些细节。
代码对我也不起作用。我什至在一些教程中找到了这段代码,主要问题是它使用 nginx
将 /bokeh
转换为 http://127.0.0.1/bokeh
。但是在没有 nginx
的本地计算机上,我必须更改所有 urls.
编辑: 我用这段代码找到了教程 https://rbtechblog.com/blog/deploy_bokeh_app
我开始更改代码并减少它以创建最少的有效代码。我做了类似于 bigreddot 提到的更改。
散景
我直接把代码放在文件里,没有def
也没有Server
filename.py
from numpy.random import random
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox
from bokeh.models import Button, ColumnDataSource
def click(n=100):
source.data = {'x': range(n), 'y': random(n)}
fig = figure(title='random data', width=800, height=400, tools='pan,box_zoom,reset,save')
source = ColumnDataSource(data={'x': [], 'y': []}) # place for data
fig.line('x', 'y', source=source) # draw plot
button = Button(label='update', button_type='success') # create button
button.on_click(click) # assign function to button
layout = column(fig, widgetbox(button)) # create layout
curdoc().add_root(layout) # add all to document
click() # generate random data at start
现在我可以在控制台运行它
bokeh serve filename.py
我可以使用 url
在网络浏览器中看到它
http://localhost:5006/filename
(bokeh
应该在启动后在控制台中显示此 url - 如果您将使用不同的文件或选项,那么您可能会看到不同的 url)
目前我不需要任何其他选项,但稍后我将需要--allow-websocket-origin
但我稍后会描述它。
顺便说一句: 我没有使用名称 bokeh.py 因为它可能会导致导入原始 bokeh
的问题。
烧瓶
因为我不使用 nginx
可以将 /bokeh
转换为 http://localhost:5006/filename
所以我必须在 serve_document
[=45 中使用完整的 url =]
为了测试,我使用了 render_template_string
而不是 render_template
,所以我不必创建 templates/index.html
,这样复制和测试代码会更容易。
如果出现错误,我删除了 try/except
以获取更多详细信息。
app.py
from flask import Flask, render_template, render_template_string
from bokeh.embed import server_document
app = Flask(__name__)
@app.route("/")
def index():
tag = server_document(url='http://localhost:5006/filename')
#return render_template('index.html', tag=tag)
return render_template_string('''<div>{{ tag|safe }}</div>''', tag=tag)
if __name__ == '__main__':
app.run(debug=True)
现在我可以运行了
python app.py
而且我可以使用标准 url
在网络浏览器中打开页面
http://localhost:5000/
但我不会看到剧情,bokeh
会显示
Refusing websocket connection from Origin 'http://127.0.0.1:5000';
use --allow-websocket-origin=127.0.0.1:5000
or set BOKEH_ALLOW_WS_ORIGIN=127.0.0.1:5000 to permit this;
currently we allow origins {'localhost:5006'}
所以我必须用这个选项
重新启动bokeh
bokeh serve filename.py --allow-websocket-origin=127.0.0.1:5000
(正如 bigreddot 提到的,它必须是 127.0.0.1
,而不是 localhost
)
现在flask
应该显示剧情了。
顺便说一句: 如果我使用没有任何 HTML 标签的模板
render_template_string('''{{ tag|safe }}''', tag=tag)
然后浏览器可能会将所有代码 (<script ...></scrip>
) 视为 <head></head>
的一部分并且不会显示它,因为浏览器永远不会显示 <head></head>
中的元素,即使有正确的图片或图表。
我不能 运行 在 Apache 后面的 Flask 中使用散景服务器,所以现在我正在尝试在本地的 Flask 中提供散景服务。该图不渲染。 这是烧瓶代码:
from flask import Flask, render_template
app = Flask(__name__)
from bokeh.embed import server_document
@app.route("/")
def techblog():
try:
tag = server_document(url=r'/bokeh', relative_urls=True)
return render_template('techblog.html', tag=tag)
except Exception as e:
return str(e)
if __name__ == '__main__':
app.run(debug=True)
这是散景代码:
from numpy.random import random
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox
from bokeh.models import Button, ColumnDataSource
from bokeh.server.server import Server
def run(doc):
fig = figure(title='random data', width=400, height=200, tools='pan,box_zoom,reset,save')
source = ColumnDataSource(data={'x': [], 'y': []})
fig.line('x', 'y', source=source)
def click(n=100):
source.data = {'x': range(n), 'y': random(n)}
button = Button(label='update', button_type='success')
button.on_click(click)
layout = column(widgetbox(button), fig)
doc.add_root(layout)
click()
# configure and run bokeh server
kws = {'port': 5000, 'prefix':'/bokeh','allow_websocket_origin': ['127.0.0.1']}
server = Server(run, **kws)
server.start()
# if __name__ == '__main__':
server.io_loop.add_callback(server.show, '/')
server.io_loop.start()
这是我的 html 模板:
<h1 style='color:blue'>Hello There!</h1>
</br>
{{ tag|safe }}
</br>
{{ tag }}
我通过 python 运行ning Flask 应用程序。在一个单独的命令处理器上,我 运行 散景应用程序通过,
bokeh serve --allow-websocket-origin=localhost:5000 filename.py
我只得到没有"safe"的标签,因为
<script src="/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh" id="1001"></script>
我在 Flask 控制台上收到了这条消息。这是一个标准的 404:
"GET /bokeh/autoload.js?bokeh-autoload-element=1000&bokeh-app-path=/bokeh HTTP/1.1" 404 -
就这些了。没有图形或按钮被呈现。看图应该改什么?
编辑:我已经在散景代码中指定了端口和前缀。结果没有改变。
编辑 2:我在 Flask 控制台上添加了 404 错误的控制台 msj。
有几处错误:
您没有配置端口,因此 Bokeh 服务器将使用其默认端口 5006(不是 5000)
您尚未配置应用程序路径,因此 Bokeh 服务器将从其默认位置
[提供应用程序=31=]/
(不是/bokeh
)
还值得一提的是,如果您将 localhost
列入白名单作为允许的 websocket 来源,那么它实际上必须是 URL 栏中的 localhost
(即不是 127.0.0.1,它们在这种情况下不可互换)
最后,将 Bokeh 应用程序代码放入手动调用 Server
的纯 python 脚本中需要做很多额外的工作,等等。您可以将 [=15= 的内容放入] 在一个文件中调用 bokeh serve --port=5000 app.py
然后该应用程序将在 localhost:5000/app
我在@bigreddot 的回答中添加了一些细节。
代码对我也不起作用。我什至在一些教程中找到了这段代码,主要问题是它使用 nginx
将 /bokeh
转换为 http://127.0.0.1/bokeh
。但是在没有 nginx
的本地计算机上,我必须更改所有 urls.
编辑: 我用这段代码找到了教程 https://rbtechblog.com/blog/deploy_bokeh_app
我开始更改代码并减少它以创建最少的有效代码。我做了类似于 bigreddot 提到的更改。
散景
我直接把代码放在文件里,没有def
也没有Server
filename.py
from numpy.random import random
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column, widgetbox
from bokeh.models import Button, ColumnDataSource
def click(n=100):
source.data = {'x': range(n), 'y': random(n)}
fig = figure(title='random data', width=800, height=400, tools='pan,box_zoom,reset,save')
source = ColumnDataSource(data={'x': [], 'y': []}) # place for data
fig.line('x', 'y', source=source) # draw plot
button = Button(label='update', button_type='success') # create button
button.on_click(click) # assign function to button
layout = column(fig, widgetbox(button)) # create layout
curdoc().add_root(layout) # add all to document
click() # generate random data at start
现在我可以在控制台运行它
bokeh serve filename.py
我可以使用 url
在网络浏览器中看到它 http://localhost:5006/filename
(bokeh
应该在启动后在控制台中显示此 url - 如果您将使用不同的文件或选项,那么您可能会看到不同的 url)
目前我不需要任何其他选项,但稍后我将需要--allow-websocket-origin
但我稍后会描述它。
顺便说一句: 我没有使用名称 bokeh.py 因为它可能会导致导入原始 bokeh
的问题。
烧瓶
因为我不使用 nginx
可以将 /bokeh
转换为 http://localhost:5006/filename
所以我必须在 serve_document
[=45 中使用完整的 url =]
为了测试,我使用了 render_template_string
而不是 render_template
,所以我不必创建 templates/index.html
,这样复制和测试代码会更容易。
如果出现错误,我删除了 try/except
以获取更多详细信息。
app.py
from flask import Flask, render_template, render_template_string
from bokeh.embed import server_document
app = Flask(__name__)
@app.route("/")
def index():
tag = server_document(url='http://localhost:5006/filename')
#return render_template('index.html', tag=tag)
return render_template_string('''<div>{{ tag|safe }}</div>''', tag=tag)
if __name__ == '__main__':
app.run(debug=True)
现在我可以运行了
python app.py
而且我可以使用标准 url
在网络浏览器中打开页面http://localhost:5000/
但我不会看到剧情,bokeh
会显示
Refusing websocket connection from Origin 'http://127.0.0.1:5000';
use --allow-websocket-origin=127.0.0.1:5000
or set BOKEH_ALLOW_WS_ORIGIN=127.0.0.1:5000 to permit this;
currently we allow origins {'localhost:5006'}
所以我必须用这个选项
重新启动bokeh
bokeh serve filename.py --allow-websocket-origin=127.0.0.1:5000
(正如 bigreddot 提到的,它必须是 127.0.0.1
,而不是 localhost
)
现在flask
应该显示剧情了。
顺便说一句: 如果我使用没有任何 HTML 标签的模板
render_template_string('''{{ tag|safe }}''', tag=tag)
然后浏览器可能会将所有代码 (<script ...></scrip>
) 视为 <head></head>
的一部分并且不会显示它,因为浏览器永远不会显示 <head></head>
中的元素,即使有正确的图片或图表。