将Bokeh应用嵌入Flask中

20

我正在拼命尝试将一个可工作的Bokeh小应用程序嵌入到Flask中,但是找不到合适的方法。我浏览了所有示例,但没有找到包括更新数据功能的示例(最好的示例:sliders_applet)。

如果我没错的话,我需要bokeh-server才能够更改数据(例如使用滑块等)。以这种方式启动applet可以起作用,例如:

bokeh-server --script sliders_app.py

但我找不到适合的,或者至少是一个能够嵌入到Flask中的工作方式。而且由于应该可以使用多个小应用程序,因此在启动bokeh服务器时指定一个单一的小应用程序对我来说似乎不太干净。

我将非常感激任何帮助 - bokeh看起来对我来说是一个很棒的工具。

2个回答

12

另一个答案没有详细说明如何嵌入Bokeh服务器应用程序(它使用components来嵌入独立的Bokeh文档)。

首先,您可以在以下链接中看到许多实时示例:https://demo.bokeh.org/

对于嵌入应用程序,通常有两个选项:

后者通常像这样使用:

from bokeh.embed import server_document
script = server_document("https://demo.bokeh.org/sliders")

这将返回一个类似下面的<script>标签,您可以将其放在flask HTML响应中的任何位置,以便应用程序出现:

<script
    src="https://demo.bokeh.org/sliders/autoload.js?bokeh-autoload-element=1000&bokeh-app-path=/sliders&bokeh-absolute-url=https://demo.bokeh.org/sliders"
    id="1000">
</script>

最后,重要的是要注意,默认情况下,Bokeh服务器选择了相当保守的网络配置。您需要使用命令行选项--allow-websocket-origin启动Bokeh服务器,将其设置为嵌入bokeh应用程序的主机。


3
你有两个完全可用的示例来说明iframes和autoload_server吗? - mr.bjerre
我不确定你在问什么。IFrame 就是 <iframe src="https://url.to.bokeh/server"></iframe> - bigreddot
是的,新网站位于 demo.bokeh.org(已更新答案)。 - bigreddot

10

Bokeh 项目的核心开发人员之一编辑: 下面的信息无法回答上述问题。按照下文所述,使用 bokeh.embed.components 嵌入 Bokeh 应用程序 是绝对不可能的。 components 只能嵌入独立文档(即不在 Bokeh 服务器上运行的文档)。


一个在 Flask 中嵌入 Bokeh 的示例可以在 Bokeh 的 Github 代码库中找到。

import flask

from bokeh.embed import components
from bokeh.plotting import figure
from bokeh.resources import INLINE
from bokeh.templates import RESOURCES
from bokeh.util.string import encode_utf8

app = flask.Flask(__name__)

colors = {
    'Black': '#000000',
    'Red':   '#FF0000',
    'Green': '#00FF00',
    'Blue':  '#0000FF',
}


def getitem(obj, item, default):
    if item not in obj:
        return default
    else:
        return obj[item]


@app.route("/")
def polynomial():
    """ Very simple embedding of a polynomial chart"""
    # Grab the inputs arguments from the URL
    # This is automated by the button
    args = flask.request.args

    # Get all the form arguments in the url with defaults
    color = colors[getitem(args, 'color', 'Black')]
    _from = int(getitem(args, '_from', 0))
    to = int(getitem(args, 'to', 10))

    # Create a polynomial line graph
    x = list(range(_from, to + 1))
    fig = figure(title="Polynomial")
    fig.line(x, [i ** 2 for i in x], color=color, line_width=2)

    # Configure resources to include BokehJS inline in the document.
    # For more details see:
    #   http://docs.bokeh.org/en/latest/docs/reference/resources_embedding.html#module-bokeh.resources
    plot_resources = RESOURCES.render(
        js_raw=INLINE.js_raw,
        css_raw=INLINE.css_raw,
        js_files=INLINE.js_files,
        css_files=INLINE.css_files,
    )

    # For more details see:
    #   http://docs.bokeh.org/en/latest/docs/user_guide/embedding.html#components
    script, div = components(fig, INLINE)
    html = flask.render_template(
        'embed.html',
        plot_script=script, plot_div=div, plot_resources=plot_resources,
        color=color, _from=_from, to=to
    )
    return encode_utf8(html)


def main():
    app.debug = True
    app.run()

if __name__ == "__main__":
    main()
另一个想法是同时运行bokeh-server和你的flask web应用程序,并以这种方式加载bokeh代码(在服务器端或通过JS或iframe),但可能会有麻烦。

1
非常感谢!对我来说,这个例子的问题在于它只是使用新参数创建了一个新的图表 - 这不是我正在寻找的交互方式,其次,它并没有涉及到真正的bokeh applet - 让我们使用sliders_app.py例子:这是一个真正的bokeh app,可以直接在bokeh服务器上完美运行,并且具有我正在寻找的“真正的交互性”。我找不到一种方法来嵌入这个applet。 - lakerz
1
嗯,看着bokeh-server代码,我发现他们做了很多事情。Flask应用程序在app.py的末尾被实例化,但只有稍后(在start.py中)被修改。也许你可以在start.py中重用那段代码,并将你的路由添加到app实例中? - halflings
1
看起来很有趣,我会研究一下,猜想需要一段时间才能完全理解。到目前为止,我发现了另外两个选项:(1)不使用任何bokeh控件,而是重新实现控件自己(例如使用jQuery)。这样做可以正常工作,但感觉有点不必要,如果bokeh本身提供相同的功能。(2)只需使用iFrame嵌入bokeh应用程序网址。看起来它可以正常工作,但我有一个疯狂的猜测,即使用iFrames并不是一个真正好的风格...但是我已经有几年没有为网络做过什么事情了,也许现在已经改变了? - lakerz
1
@lakerz:有一个相对较新的库叫做Spyre,它提供了类似于bokeh-server的功能,尽管它不一定更容易嵌入。你可以在这里看看:https://github.com/adamhajari/spyre - halflings
8
大家好,有人成功地将bokeh server与flask进行了整合吗?如果是的话,发布代码作为回答会非常有帮助。 - multigoodverse
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接