I use the following function to setup a bokeh server programmatically.
def setup_bokeh_server(data):
'''
Sets up Bokeh Application instances on server.
'''
def run_server(url_func_map):
server = Server(url_func_map,
allow_websocket_origin=['localhost:8888',
'localhost:5006'])
server.start()
server.io_loop.start()
url_func_map = {}
for name, app in data['bokeh_apps'].items():
url_func_map['/'+name] = app
p = multiprocessing.Process(target=run_server, args=(url_func_map,))
p.start()
p.join()
Before I setup the server I create Bokeh applications and add them to data['bokeh_apps'].
def setup_plot_data(data):
'''
Creates Bokeh Application to be rendered by server.
'''
def plot_maker(doc, x=[], y=[], name=''):
source = ColumnDataSource(data={'x':x, 'y':y})
fig = figure(title=name)
fig.line(x='x', y='y', source=source)
doc.add_root(fig)
return doc
args_dict = {'1':{'x':[1,2,3,4],'y':[4,3,2,1],'name':'plot_1'},
'2':{'x':[1,2,3,4],'y':[4,3,2,1],'name':'plot_2'}}
for args_num, args in args_dict.items():
render_foo = lambda doc: plot_maker(doc, **args)
handler = FunctionHandler(render_foo)
app = Application(handler)
data['bokeh_apps'][args['name']] = app
Using this approach results in the same plot being rendered on both bokeh server URL:s (the last Application to be added to data['bokeh_apps'] is rendered on both URL:s). However, when I skip the for loop and add the apps one at a time:
render_foo = lambda doc: plot_maker([1,2,3,4], [1,2,3,4], 'plot_1', doc)
handler = FunctionHandler(render_foo)
app = Application(handler)
data['bokeh_apps']['plot_1'] = app
render_foo = lambda doc: plot_maker([1,2,3,4], [4,3,2,1], 'plot_2', doc)
handler = FunctionHandler(render_foo)
app = Application(handler)
data['bokeh_apps']['plot_2'] = app
Everything is hunky-dory, I get individual plots on both URL:s. I'm curious why this happens and want to find out if I can avoid having to create all Applications and add them individually?