Any Bokeh server with Flask example?

Bokeh server is a wonderful tool and I am planning to use it in a project, but I first wanted to make sure it can be embedded in Flask. So far, I haven’t found any working example on the web.

The closest I came through is the following code:

The bokeh script:

#bokeh_plot.py

import pandas as pd

from bokeh.layouts import row, widgetbox

from bokeh.models import Select

from bokeh.palettes import Spectral5

from bokeh.plotting import curdoc, figure, show

from bokeh.sampledata.autompg import autompg

from bokeh.io import output_notebook

df = autompg.copy()

SIZES = list(range(6, 22, 3))

COLORS = Spectral5

ORIGINS = [‘North America’, ‘Europe’, ‘Asia’]

data cleanup

df.cyl = [str(x) for x in df.cyl]

df.origin = [ORIGINS[x-1] for x in df.origin]

df[‘year’] = [str(x) for x in df.yr]

del df[‘yr’]

df[‘mfr’] = [x.split()[0] for x in df.name]

df.loc[df.mfr==‘chevy’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘chevroelt’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘maxda’, ‘mfr’] = ‘mazda’

df.loc[df.mfr==‘mercedes-benz’, ‘mfr’] = ‘mercedes’

df.loc[df.mfr==‘toyouta’, ‘mfr’] = ‘toyota’

df.loc[df.mfr==‘vokswagen’, ‘mfr’] = ‘volkswagen’

df.loc[df.mfr==‘vw’, ‘mfr’] = ‘volkswagen’

del df[‘name’]

columns = sorted(df.columns)

discrete = [x for x in columns if df.dtype == object]

continuous = [x for x in columns if x not in discrete]

quantileable = [x for x in continuous if len(df.unique()) > 20]

def create_figure():

xs = df[x.value].values

ys = df[y.value].values

x_title = x.value.title()

y_title = y.value.title()

kw = dict()

if x.value in discrete:

    kw['x_range'] = sorted(set(xs))

if y.value in discrete:

    kw['y_range'] = sorted(set(ys))

kw['title'] = "%s vs %s" % (x_title, y_title)

p = figure(plot_height=600, plot_width=800, tools='pan,box_zoom,reset', **kw)

p.xaxis.axis_label = x_title

p.yaxis.axis_label = y_title

if x.value in discrete:

    p.xaxis.major_label_orientation = pd.np.pi / 4

sz = 9

if size.value != 'None':

    groups = pd.qcut(df[size.value].values, len(SIZES))

    sz = [SIZES[xx] for xx in groups.codes]

c = "#31AADE"

if color.value != 'None':

    groups = pd.qcut(df[color.value].values, len(COLORS))

    c = [COLORS[xx] for xx in groups.codes]

p.circle(x=xs, y=ys, color=c, size=sz, line_color="white", alpha=0.6, hover_color='white', hover_alpha=0.5)

return p

def update(attr, old, new):

layout.children[1] = create_figure()

x = Select(title=‘X-Axis’, value=‘mpg’, options=columns)

x.on_change(‘value’, update)

y = Select(title=‘Y-Axis’, value=‘hp’, options=columns)

y.on_change(‘value’, update)

size = Select(title=‘Size’, value=‘None’, options=[‘None’] + quantileable)

size.on_change(‘value’, update)

color = Select(title=‘Color’, value=‘None’, options=[‘None’] + quantileable)

color.on_change(‘value’, update)

controls = widgetbox([x, y, color, size], width=200)

layout = row(controls, create_figure())

curdoc().add_root(layout)

curdoc().title = “Crossfilter”

The flask code:

#flask_app.py
from bokeh_plot import layout

from flask import render_template, Flask

from bokeh.embed import autoload_server

from bokeh.client import push_session

from bokeh.io import curdoc

from bokeh.resources import Resources

from bokeh.client import pull_session

app = Flask(name)

@app.route(‘/’)

def index():

session = pull_session(session_id=None, url='default')

curdoc().add_root(layout)

curdoc().title="Crossfilter"

push_session(curdoc())

tag = autoload_server(next(iter(session.document.roots)), session_id=session.id,

                      app_path='/unkn2', loglevel='debug')

session.close()

#tag = autoload_server(layout)

return render_template('app.html', tag=tag)

if name == ‘main’:

print("STARTED")

app.run(debug=True)

``

To execute this, I am first running bokeh serve and then python flask_app.py in another terminal, but that giving me this error when I visit localhost:5006:

  • File “D:\Dropbox\pi_pp\Bokeh examples\Flask\Unknown2\flask-app.py”, line 25, in index

    <img src="http://localhost:5000/?__debugger__=yes&amp;cmd=resource&amp;f=console.png" title="Open an interactive python shell in this frame" style="float: right; padding: 2px; margin-top: -3px; margin-right: 2px; display: block;">tag = autoload_server(next(iter(session.document.roots)), session_id=session.id,
    

StopIteration
Anyone have any idea how to fix this?

Note sure what you want to do with "next(iter(session.document.roots)"

But to embed a booked server app in Flask, here is a simple example: GitHub - beenje/flask_bokeh_app
Note that there is a bug in 0.12.0 (fixed in the coming release). See Incorrect rendering of embedded Bokeh server app in 0.12 · Issue #4693 · bokeh/bokeh · GitHub

/Benjamin

In the same line as examples indicated by Benjamin, you can try the following with the bokeh_plot.py example:

#flask_app.py

import subprocess

import atexit

from flask import render_template, render_template_string, Flask

from bokeh.embed import autoload_server

from bokeh.client import pull_session

app_html="""

{{ bokeh_script|safe }}

“”"

app = Flask(name)

bokeh_process = subprocess.Popen(

[‘bokeh’, ‘serve’,’–allow-websocket-origin=localhost:5000’,‘bokeh_plot.py’], stdout=subprocess.PIPE)

@atexit.register

def kill_server():

bokeh_process.kill()

@app.route(’/’)

def index():

session=pull_session(app_path=’/bokeh_plot’)

bokeh_script=autoload_server(None,app_path="/bokeh_plot",session_id=session.id)

return render_template(‘app.html’, bokeh_script=bokeh_script)

return render_template_string(app_html, bokeh_script=bokeh_script)

if name == ‘main’:

print(“STARTED”)

app.run(debug=True)

``

``

All the best,

Anton

Thank you Benjamin and Anton.

I tried Anton’s code and it’s working great.

I now trying to deploy it on Heroku. I deployed Anton’s code without changing anything, but I only get some HTML paragraph text that I added to the HTML code. The Bokeh part is not displaying. Here is the app: https://bokehapp.herokuapp.com/

I probably need to change something in the bokeh_process line, but not sure what. I tried this:

#bokeh_process = subprocess.Popen([“bokeh”, “serve”, “–allow-websocket-origin=bokehapp.herokuapp”,“–port=$PORT”, “–host=bokehapp.herokuapp.com”, “–host=*”, “–address=0.0.0.0”, “–use-xheaders”, “bokeh_plot.py”],stdout=subprocess.PIPE)

But got an application error.

I’d appreciate any help here.

···

On Tuesday, July 19, 2016 at 12:23:17 PM UTC+2, Adi wrote:

Bokeh server is a wonderful tool and I am planning to use it in a project, but I first wanted to make sure it can be embedded in Flask. So far, I haven’t found any working example on the web.

The closest I came through is the following code:

The bokeh script:

#bokeh_plot.py

import pandas as pd

from bokeh.layouts import row, widgetbox

from bokeh.models import Select

from bokeh.palettes import Spectral5

from bokeh.plotting import curdoc, figure, show

from bokeh.sampledata.autompg import autompg

from bokeh.io import output_notebook

df = autompg.copy()

SIZES = list(range(6, 22, 3))

COLORS = Spectral5

ORIGINS = [‘North America’, ‘Europe’, ‘Asia’]

data cleanup

df.cyl = [str(x) for x in df.cyl]

df.origin = [ORIGINS[x-1] for x in df.origin]

df[‘year’] = [str(x) for x in df.yr]

del df[‘yr’]

df[‘mfr’] = [x.split()[0] for x in df.name]

df.loc[df.mfr==‘chevy’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘chevroelt’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘maxda’, ‘mfr’] = ‘mazda’

df.loc[df.mfr==‘mercedes-benz’, ‘mfr’] = ‘mercedes’

df.loc[df.mfr==‘toyouta’, ‘mfr’] = ‘toyota’

df.loc[df.mfr==‘vokswagen’, ‘mfr’] = ‘volkswagen’

df.loc[df.mfr==‘vw’, ‘mfr’] = ‘volkswagen’

del df[‘name’]

columns = sorted(df.columns)

discrete = [x for x in columns if df.dtype == object]

continuous = [x for x in columns if x not in discrete]

quantileable = [x for x in continuous if len(df.unique()) > 20]

def create_figure():

xs = df[x.value].values
ys = df[y.value].values
x_title = x.value.title()
y_title = y.value.title()
kw = dict()
if x.value in discrete:
    kw['x_range'] = sorted(set(xs))
if y.value in discrete:
    kw['y_range'] = sorted(set(ys))
kw['title'] = "%s vs %s" % (x_title, y_title)
p = figure(plot_height=600, plot_width=800, tools='pan,box_zoom,reset', **kw)
p.xaxis.axis_label = x_title
p.yaxis.axis_label = y_title
if x.value in discrete:
    p.xaxis.major_label_orientation = pd.np.pi / 4
sz = 9
if size.value != 'None':
    groups = pd.qcut(df[size.value].values, len(SIZES))
    sz = [SIZES[xx] for xx in groups.codes]
c = "#31AADE"
if color.value != 'None':
    groups = pd.qcut(df[color.value].values, len(COLORS))
    c = [COLORS[xx] for xx in groups.codes]
p.circle(x=xs, y=ys, color=c, size=sz, line_color="white", alpha=0.6, hover_color='white', hover_alpha=0.5)
return p

def update(attr, old, new):

layout.children[1] = create_figure()

x = Select(title=‘X-Axis’, value=‘mpg’, options=columns)

x.on_change(‘value’, update)

y = Select(title=‘Y-Axis’, value=‘hp’, options=columns)

y.on_change(‘value’, update)

size = Select(title=‘Size’, value=‘None’, options=[‘None’] + quantileable)

size.on_change(‘value’, update)

color = Select(title=‘Color’, value=‘None’, options=[‘None’] + quantileable)

color.on_change(‘value’, update)

controls = widgetbox([x, y, color, size], width=200)

layout = row(controls, create_figure())

curdoc().add_root(layout)

curdoc().title = “Crossfilter”

The flask code:

#flask_app.py
from bokeh_plot import layout

from flask import render_template, Flask

from bokeh.embed import autoload_server

from bokeh.client import push_session

from bokeh.io import curdoc

from bokeh.resources import Resources

from bokeh.client import pull_session

app = Flask(name)

@app.route(‘/’)

def index():

session = pull_session(session_id=None, url='default')
curdoc().add_root(layout)
curdoc().title="Crossfilter"
push_session(curdoc())
tag = autoload_server(next(iter(session.document.roots)), session_id=[session.id](http://session.id),
                      app_path='/unkn2', loglevel='debug')
session.close()
#tag = autoload_server(layout)
return render_template('app.html', tag=tag)

if name == ‘main’:

print("STARTED")
app.run(debug=True)

``

To execute this, I am first running bokeh serve and then python flask_app.py in another terminal, but that giving me this error when I visit localhost:5006:

  • File “D:\Dropbox\pi_pp\Bokeh examples\Flask\Unknown2\flask-app.py”, line 25, in index

    <img src="https://lh6.googleusercontent.com/proxy/Uinmq1I-5kNpRXzMHubSWKu_d4ykyZnCpc8hyodNRD5RAyLZNNTHB63tcrEjIjy3OnpN_i2D2HF16AbIG61mYRsyjnV098Uj1t7uM1qgHyUoaCEbqA=w5000-h5000" title="Open an interactive python shell in this frame" style="float:right;padding:2px;margin-right:2px;display:block">tag = autoload_server(next(iter(session.document.roots)), session_id=[session.id](http://session.id),
    

StopIteration
Anyone have any idea how to fix this?

Hi Adi,

I am experiencing the same problem. It seems that your app is working now. What did you do to the bokeh_process to make it work? Thanks!

···

On Thursday, July 21, 2016 at 7:25:22 AM UTC-4, Adi wrote:

Thank you Benjamin and Anton.

I tried Anton’s code and it’s working great.

I now trying to deploy it on Heroku. I deployed Anton’s code without changing anything, but I only get some HTML paragraph text that I added to the HTML code. The Bokeh part is not displaying. Here is the app: https://bokehapp.herokuapp.com/

I probably need to change something in the bokeh_process line, but not sure what. I tried this:

#bokeh_process = subprocess.Popen([“bokeh”, “serve”, “–allow-websocket-origin=bokehapp.herokuapp”,“–port=$PORT”, “–host=bokehapp.herokuapp.com”, “–host=*”, “–address=0.0.0.0”, “–use-xheaders”, “bokeh_plot.py”],stdout=subprocess.PIPE)

But got an application error.

I’d appreciate any help here.

On Tuesday, July 19, 2016 at 12:23:17 PM UTC+2, Adi wrote:

Bokeh server is a wonderful tool and I am planning to use it in a project, but I first wanted to make sure it can be embedded in Flask. So far, I haven’t found any working example on the web.

The closest I came through is the following code:

The bokeh script:

#bokeh_plot.py

import pandas as pd

from bokeh.layouts import row, widgetbox

from bokeh.models import Select

from bokeh.palettes import Spectral5

from bokeh.plotting import curdoc, figure, show

from bokeh.sampledata.autompg import autompg

from bokeh.io import output_notebook

df = autompg.copy()

SIZES = list(range(6, 22, 3))

COLORS = Spectral5

ORIGINS = [‘North America’, ‘Europe’, ‘Asia’]

data cleanup

df.cyl = [str(x) for x in df.cyl]

df.origin = [ORIGINS[x-1] for x in df.origin]

df[‘year’] = [str(x) for x in df.yr]

del df[‘yr’]

df[‘mfr’] = [x.split()[0] for x in df.name]

df.loc[df.mfr==‘chevy’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘chevroelt’, ‘mfr’] = ‘chevrolet’

df.loc[df.mfr==‘maxda’, ‘mfr’] = ‘mazda’

df.loc[df.mfr==‘mercedes-benz’, ‘mfr’] = ‘mercedes’

df.loc[df.mfr==‘toyouta’, ‘mfr’] = ‘toyota’

df.loc[df.mfr==‘vokswagen’, ‘mfr’] = ‘volkswagen’

df.loc[df.mfr==‘vw’, ‘mfr’] = ‘volkswagen’

del df[‘name’]

columns = sorted(df.columns)

discrete = [x for x in columns if df.dtype == object]

continuous = [x for x in columns if x not in discrete]

quantileable = [x for x in continuous if len(df.unique()) > 20]

def create_figure():

xs = df[x.value].values
ys = df[y.value].values
x_title = x.value.title()
y_title = y.value.title()
kw = dict()
if x.value in discrete:
    kw['x_range'] = sorted(set(xs))
if y.value in discrete:
    kw['y_range'] = sorted(set(ys))
kw['title'] = "%s vs %s" % (x_title, y_title)
p = figure(plot_height=600, plot_width=800, tools='pan,box_zoom,reset', **kw)
p.xaxis.axis_label = x_title
p.yaxis.axis_label = y_title
if x.value in discrete:
    p.xaxis.major_label_orientation = pd.np.pi / 4
sz = 9
if size.value != 'None':
    groups = pd.qcut(df[size.value].values, len(SIZES))
    sz = [SIZES[xx] for xx in groups.codes]
c = "#31AADE"
if color.value != 'None':
    groups = pd.qcut(df[color.value].values, len(COLORS))
    c = [COLORS[xx] for xx in groups.codes]
p.circle(x=xs, y=ys, color=c, size=sz, line_color="white", alpha=0.6, hover_color='white', hover_alpha=0.5)
return p

def update(attr, old, new):

layout.children[1] = create_figure()

x = Select(title=‘X-Axis’, value=‘mpg’, options=columns)

x.on_change(‘value’, update)

y = Select(title=‘Y-Axis’, value=‘hp’, options=columns)

y.on_change(‘value’, update)

size = Select(title=‘Size’, value=‘None’, options=[‘None’] + quantileable)

size.on_change(‘value’, update)

color = Select(title=‘Color’, value=‘None’, options=[‘None’] + quantileable)

color.on_change(‘value’, update)

controls = widgetbox([x, y, color, size], width=200)

layout = row(controls, create_figure())

curdoc().add_root(layout)

curdoc().title = “Crossfilter”

The flask code:

#flask_app.py
from bokeh_plot import layout

from flask import render_template, Flask

from bokeh.embed import autoload_server

from bokeh.client import push_session

from bokeh.io import curdoc

from bokeh.resources import Resources

from bokeh.client import pull_session

app = Flask(name)

@app.route(‘/’)

def index():

session = pull_session(session_id=None, url='default')
curdoc().add_root(layout)
curdoc().title="Crossfilter"
push_session(curdoc())
tag = autoload_server(next(iter(session.document.roots)), session_id=[session.id](http://session.id),
                      app_path='/unkn2', loglevel='debug')
session.close()
#tag = autoload_server(layout)
return render_template('app.html', tag=tag)

if name == ‘main’:

print("STARTED")
app.run(debug=True)

``

To execute this, I am first running bokeh serve and then python flask_app.py in another terminal, but that giving me this error when I visit localhost:5006:

  • File “D:\Dropbox\pi_pp\Bokeh examples\Flask\Unknown2\flask-app.py”, line 25, in index

    <img src="https://lh6.googleusercontent.com/proxy/Uinmq1I-5kNpRXzMHubSWKu_d4ykyZnCpc8hyodNRD5RAyLZNNTHB63tcrEjIjy3OnpN_i2D2HF16AbIG61mYRsyjnV098Uj1t7uM1qgHyUoaCEbqA=w5000-h5000" title="Open an interactive python shell in this frame" style="float:right;padding:2px;margin-right:2px;display:block">tag = autoload_server(next(iter(session.document.roots)), session_id=[session.id](http://session.id),
    

StopIteration
Anyone have any idea how to fix this?