简体   繁体   English

烧瓶散景服务器 - 人物甚至在本地也不渲染

[英]flask bokeh server - figure does not render even locally

I can't run bokeh server within flask beind apache so now I'm trying to serve bokeh within flask locally.我无法在flask beind apache 中运行bokeh 服务器,所以现在我尝试在本地提供flask 中的bokeh。 The figure does not render.该图不呈现。 Here is the flask code:这是烧瓶代码:

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)

Here is the bokeh code:这是散景代码:

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()

Here is my html template:这是我的 html 模板:

<h1 style='color:blue'>Hello There!</h1>

</br>
{{ tag|safe }}
</br>
{{ tag }}

I'm running flask app via python.我正在通过 python 运行烧瓶应用程序。 And on a separate command processor I run bokeh app via,在单独的命令处理器上,我通过以下方式运行散景应用程序,

bokeh serve --allow-websocket-origin=localhost:5000 filename.py

I only get the tag without "safe" as我只得到没有“安全”的标签

<script src="/bokeh/autoload.js?bokeh-autoload-element=1001&bokeh-app-path=/bokeh" id="1001"></script>

And I have this message on flask console.我在烧瓶控制台上有这条消息。 It is a standart 404:这是一个标准的 404:

"GET /bokeh/autoload.js?bokeh-autoload-element=1000&bokeh-app-path=/bokeh HTTP/1.1" 404 -

That'a all.就这些。 No figure or button is rendered.不呈现图形或按钮。 What should I change to see the figure?我应该改变什么才能看到这个图?

Edit: I've specified the port and the prefix in the bokeh code.编辑:我已经在散景代码中指定了端口和前缀。 The outcome has not changed.结果没有改变。

Edit 2: I've add the console msj for 404 error on flask console.编辑 2:我在烧瓶控制台上为 404 错误添加了控制台 msj。

There are a few things wrong:有几件事是错误的:

  • You have not configured a port, so the Bokeh server will use its default port of 5006 (not 5000)您尚未配置端口,因此 Bokeh 服务器将使用其默认端口 5006(而非 5000)

  • You have not configured an app path, so the Bokeh server will serve the app from its default location of / (not /bokeh )您尚未配置应用程序路径,因此 Bokeh 服务器将从其默认位置/ (不是/bokeh )为应用程序提供服务

It's also worth mentioning that if you whitelist localhost as an allow websocket origin, then it literally must be localhost in the URL bar (ie not 127.0.0.1, they are not interchangeable in this context)还值得一提的是,如果您将localhost列入白名单作为允许 websocket 来源,那么它实际上必须是 URL 栏中的localhost (即不是 127.0.0.1,在这种情况下它们不可互换)

Lastly, it's a lot of extra work to put the Bokeh app code in a plain python script that calls Server manually, etc. You could just put the contents of run in a file and call bokeh serve --port=5000 app.py and then the app will be available at localhost:5000/app最后,将 Bokeh 应用程序代码放在一个手动调用Server的普通 python 脚本中需要做很多额外的工作。您可以将run的内容放在一个文件中并调用bokeh serve --port=5000 app.py和然后该应用程序将在localhost:5000/app可用

I add some details to @bigreddot's answer.我在@bigreddot 的回答中添加了一些细节。


Code didn't work for me too.代码对我也不起作用。 I even found exactly this code in some tutorial and main problem was that it was using nginx which was converting /bokeh to http://127.0.0.1/bokeh .我什至在一些教程中找到了这个代码,主要问题是它使用的是nginx/bokeh转换为http://127.0.0.1/bokeh But on local computer without nginx I have to change all urls.但是在没有nginx本地计算机上,我必须更改所有 url。

EDIT: I found tutorial with this code https://rbtechblog.com/blog/deploy_bokeh_app编辑:我找到了带有此代码的教程https://rbtechblog.com/blog/deploy_bokeh_app


I start changing code and reduce it to create minimal code which works.我开始更改代码并减少它以创建最少的代码。 I made changes similar to changes mentioned by bigreddot.我做了类似于 bigreddot 提到的更改的更改。


Bokeh散景

I put code directly in file without def and without Server我将代码直接放在没有defServer文件中

filename.py文件名.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

Now I can run it in console现在我可以在控制台中运行它

 bokeh serve filename.py 

and I can see it in web browser using url我可以使用 url 在网络浏览器中看到它

 http://localhost:5006/filename

( bokeh should display this url in console after start - if you will use different file or options then you may see different url) bokeh应该在启动后在控制台中显示此 url - 如果您将使用不同的文件或选项,那么您可能会看到不同的 url)

At this moment I don't need any other options but later I will need --allow-websocket-origin but I will describe it later.目前我不需要任何其他选项,但稍后我将需要--allow-websocket-origin但我稍后会描述它。

BTW: I not use name bokeh.py because it can make problem to import original bokeh .顺便说一句:我不使用名称bokeh.py因为导入原始bokeh可能会出现问题。


Flask烧瓶

Because I don't use nginx which could convert /bokeh to http://localhost:5006/filename so I have to use full url in serve_document因为我不使用可以将/bokeh转换为http://localhost:5006/filename nginx所以我必须在serve_document使用完整的 url

For test I used render_template_string instead of render_template so I don't have to create templates/index.html so it will easier to copy and test code.对于测试,我使用了render_template_string而不是render_template因此我不必创建templates/index.html以便更容易复制和测试代码。

I removed try/except to get more details if there will be error.如果出现错误,我删除了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)

Now I can run it现在我可以运行它

python app.py

and I can open page in web browser using standard url我可以使用标准网址在网络浏览器中打开页面

http://localhost:5000/

but I will not see plot and bokeh will display但我不会看到情节和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'}

so I have to restart bokeh with this option所以我必须用这个选项重新启动bokeh

bokeh serve filename.py --allow-websocket-origin=127.0.0.1:5000

(as bigreddot mentioned it has to be 127.0.0.1 , not localhost ) (正如 bigreddot 提到的,它必须是127.0.0.1 ,而不是localhost

And now flask should display plot.现在flask应该显示情节。

BTW: if I use template without any HTML tag顺便说一句:如果我使用没有任何 HTML 标签的模板

render_template_string('''{{ tag|safe }}''', tag=tag) 

then browser may treat all code ( <script ...></scrip> ) as part of <head></head> and it will not display it because browser never display elements which are in <head></head> even if there are correct images or plots.那么浏览器可能会将所有代码( <script ...></scrip> )视为<head></head> ,它不会显示它,因为浏览器从不显示<head></head>元素,即使如果有正确的图像或情节。


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM