首页 > 解决方案 > 在 Google Cloud 上部署 Bokeh Flask

问题描述

我正在尝试通过 Flask 将我的 Bokeh Dashboard 部署到 Google Cloud。我正在尝试将 Bokeh Dashboard 嵌入到 Flask 网站中,但无法将其关闭localhost以正确部署它。我一直在寻找一个典型的例子,但还没有看到一些简单的东西,以便我可以推断出一个更复杂的系统。

我的 git hub 存储库的当前文件结构看起来像,

app.yaml
requirements.txt
bokeh-sliders.py
hello.py
templates/
     hello.html

我的 bokeh-sliders.py 文件是

import numpy as np

from bokeh.io import curdoc
from bokeh.layouts import row, widgetbox
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import Slider, TextInput
from bokeh.plotting import figure

# Set up data
N = 200
x = np.linspace(0, 4*np.pi, N)
y = np.sin(x)
source = ColumnDataSource(data=dict(x=x, y=y))


# Set up plot
plot = figure(plot_height=400, plot_width=400, title="my sine wave",
              tools="crosshair,pan,reset,save,wheel_zoom",
              x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])

plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)


# Set up widgets
text = TextInput(title="title", value='my sine wave')
offset = Slider(title="offset", value=0.0, start=-5.0, end=5.0, step=0.1)
amplitude = Slider(title="amplitude", value=1.0, start=-5.0, end=5.0)
phase = Slider(title="phase", value=0.0, start=0.0, end=2*np.pi)
freq = Slider(title="frequency", value=1.0, start=0.1, end=5.1)


# Set up callbacks
def update_title(attrname, old, new):
    plot.title.text = text.value

text.on_change('value', update_title)

def update_data(attrname, old, new):

    # Get the current slider values
    a = amplitude.value
    b = offset.value
    w = phase.value
    k = freq.value

    # Generate the new curve
    x = np.linspace(0, 4*np.pi, N)
    y = a*np.sin(k*x + w) + b

    source.data = dict(x=x, y=y)

for w in [offset, amplitude, phase, freq]:
    w.on_change('value', update_data)


# Set up layouts and add to document
inputs = widgetbox(text, offset, amplitude, phase, freq)

curdoc().add_root(row(inputs, plot, width=800))
curdoc().title = "Sliders"

我的 hello.py 文件是,

from flask import Flask, flash, redirect, render_template, request, session, abort
from bokeh.embed import server_document

app = Flask(__name__)

@app.route("/")
def hello():
    script=server_document("http://localhost:5006/bokeh-sliders")
    print(script)
    return render_template('hello.html',bokS=script)

if __name__ == "__main__":
    app.run()

我嵌套的 hello.html 文件是,

<html>
<head>
    <title>Website</title>
<style>
@import url(http://fonts.googleapis.com/css?family=Amatic+SC:700);
body{
    text-align: center;
}
h1{
    font-family: 'Amatic SC', cursive;
    font-weight: normal;
    color: #8ac640;
    font-size: 2.5em;
}
</style>

</head>
<body>
 <p>Flask embedding Bokeh test</p>
{{ bokS|indent(4)|safe }}

</body>
</html>

我知道这可能是 MWE 的一些代码,但这是我迄今为止所做的。还有一个 app.yaml 文件和一个 requirements.txt 文件,但我不知道它们是否需要回答这个问题。

如果我运行,python hello.py则可以查看交互式文档,但如果我尝试部署应用程序,则会收到 502 Bad Gateway Error。关于通过正确部署 Bokeh 仪表板,我是否遗漏了server_document什么?

编辑:

我使用时的外壳响应bokeh serve bokeh-sliders.py --allow-websocket-origin=*是,

(hello_world) brycechudomelka@cloudshell:~/mlcdashboard (mlcdashboard)$ bokeh serve bokeh-sliders.py --allow-websocket-origin=*
2019-08-06 12:53:31,636 Starting Bokeh server version 1.3.2 (running on Tornado 6.0.3)
2019-08-06 12:53:31,638 Host wildcard '*' will allow connections originating from multiple (or possibly all) hostnames or IPs. Use non-wildcard values to restrict access explicitly
2019-08-06 12:53:31,642 Bokeh app running at: http://localhost:5006/bokeh-sliders
2019-08-06 12:53:31,643 Starting Bokeh server with process id: 421
2019-08-06 12:55:38,205 302 GET /?authuser=0 (127.0.0.1) 1.20ms
2019-08-06 12:55:38,694 200 GET /bokeh-sliders (127.0.0.1) 332.15ms
2019-08-06 12:55:39,369 404 GET /favicon.ico (127.0.0.1) 0.91ms
2019-08-06 12:55:39,796 101 GET /bokeh-sliders/ws?bokeh-protocol-version=1.0&bokeh-session-id=70lK44usV1edkGRZmGWWpKMVn3DxhOsUlM5xSqqw6p5p (127.0.0.1) 1.38ms
2019-08-06 12:55:39,797 WebSocket connection opened
2019-08-06 12:55:39,798 ServerConnection created

因此,Bokeh Serve 可以工作,但没有嵌入,因此无法部署它。

标签: pythonflaskgoogle-cloud-platformbokeh

解决方案


我推断您正在尝试在 App Engine 中部署此应用程序。

请参阅上一个问题以了解有关在 App Engine 上使用 Bokeh 和 Numpy 的限制的更多信息。

另请参阅此文档以了解有关在 App 引擎标准中使用套接字的限制的更多信息。

并且此文档可进一步了解 App Engine Flex 的beta功能以允许Websockets 连接

总之,由于持久连接的限制,在 App Engine 上部署需要套接字连接的应用程序可能会很棘手。使用 Compute Engine 实例来为您的应用程序提供服务可能会更好(或 Kubernetes,具体取决于您的用例,这里有一个关于如何使用 Bokeh 和 BigQuery 创建自定义交互式仪表板的示例)


推荐阅读