Embedding a bokeh app in flask
Asked Answered
W

2

20

I am trying desperately to embed a working bokeh applet into flask, and can't find a proper way to do this. I looked through all the examples, but I can't find one which includes the ability to update the data (best example: the sliders_applet).

If I'm not mistaken, I do need the bokeh-server to be able to change the data (with sliders etc.). Starting the applet this way works, e.g.:

bokeh-server --script sliders_app.py

But I can't find the proper, or at least a working way to embed the sliders_app into flask. And since it should be possible to use multiple applets, it doesn't seem clean to me to specify one single applet at the startup of the bokeh server too..

I would gladly appreciate any help - bokeh looks like a great tool for me.

Wont answered 29/4, 2015 at 16:41 Comment(0)
G
11

The other answer does not describe how to embed a Bokeh server app (it uses components to embed a standalone Bokeh document).

First, you can see lots of live examples hosted at: https://demo.bokeh.org/

For embedding apps there are two usual options:

The latter is usually used like this:

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

This will return a <script> tag similar to the one below, that you can put in your flask HTML response, wherever you'd like the app to appear:

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

Lastly, it's important to note that by default the Bokeh server opts for a fairly conservative network configuration. You'll need to start the Bokeh server with --allow-websocket-origin command line option set to be whatever host you are embedding the bokeh app into.

Givens answered 29/10, 2016 at 20:28 Comment(3)
Do you have two fully working examples to illustrate iframes and autoload_server?Galbanum
I'm not sure what you are asking. IFrames are literally just <iframe src="https://url.to.bokeh/server"></iframe>Givens
Yes the new site is at demo.bokeh.org (answer updated)Givens
C
10

EDIT by one one of the core developers of the Bokeh project The information below does not answer the question above. It is categorically impossibly to embed a Bokeh Application by using bokeh.embed.components as described below. components is only capable of embedding standalone documenents (i.e. that do NOT run on a Bokeh server)


An example of embedding bokeh with flask is present on the bokeh github repo.

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

Another idea would be to run bokeh-server and your flask web app side-by-side, and load the bokeh-code that way (server-side or via JS or an iframe), but that could be troublesome.

Chiffchaff answered 29/4, 2015 at 17:1 Comment(12)
Thank you very much! The problem for me with this example is, that it just creates a new plot with new parameters - not the kind if interactivity I'm looking for, and secondly, it doesn't involve a real bokeh applet - let's use the sliders_app.py example: It's a real bokeh app which works perfectly fine on the bokeh server directly, plus it has the kind of "real interactivity" I'm looking for. I can't find a way to just embed this applet.Wont
Mmh. Looking at the bokeh-server code I see that they're doing quite a lot of stuff. The Flask app is instantiated at the end of app.py but only later (in start.py) modified. Maybe you could reuse that code in start.py and add your routes to the app instance?Chiffchaff
That looks interesting, I will look into it, guess it will take me awhile to fully understand. So far I found two other options: (1) Don't use any bokeh controls, instead re-implement the controls myself (e.g. with jQuery). Works fine, but it feels a bit unnecessary, if bokeh itself provides the same functionality. (2) Just embed the bokeh applet url with an iFrame. Looks like it's working fine, but somehow I have a wild guess that the usage of iFrames is not really a good style.. but it is quite some years since I did something for the web, maybe that changed nowadays?Wont
iframes still make sense in some usecases, and it might be "good enough" especially if you're just using this internally or for a small web app.Chiffchaff
Yes, I thought so too, but I came across some more problem with the bokeh controls, for example the sliders don't work with touch interfaces; therefore I decided to use bokeh just for the plots and implement the controls elsewhere.Wont
@lakerz: There's a relatively new lib called Spyre that provides something similar to bokeh-server, although it's not necessarily easier to embed. You can have a look here: github.com/adamhajari/spyreChiffchaff
Thanks, that looks interesting, I'll see into it.Wont
Hey guys, did anyone manage to implement a neat integration of bokeh server with flask? If yes, posting the code as an answer would be very helpful.Howrah
I can't seem to get your example to work in bokeh 0.11: bokeh.templates became bokeh.core.templates, and there is RESOURCES but a JD_RESOURCES and a CSS_RESOURCESMusclebound
@famargar: This is an old response so that might very well be true. Could you try to find the equivalent in the new version and update the answer accordingly?Chiffchaff
@famargar: now you just load INLINE: from bokeh.resources import INLINE, and obtain JS resources like this: js_resources = INLINE.render_js(). This change is reflected in my edit, which is currently under peer review. Thanks for pointing me to a helpful example, halflings!Barreto
@CDspace didn't think your answer should be updated, even though you ask for someone to update your answer two comments above, so my edit failed peer review and someone else will have to try, halflings.Barreto

© 2022 - 2024 — McMap. All rights reserved.