Reputation: 837
I am building an app using the Flask-AppBuilder framework, and have successfully embedded a bokeh plot using autoload_server
to insert the script src into my html template. At the moment, I have a widget button inside the bokeh app which triggers a python callback to update the plot. What I would like to know is if it is possible to trigger the same behaviour but using a button which sits inside the flask app. It seems to me that this should be possible but I just don't know how to communicate the UI event from a flask button to the bokeh server.
Below is simplified code.
Has a callback button to change plot from 'cos' to 'sin'.
import numpy as np
from bokeh.plotting import figure, output_file, show
from bokeh.io import curdoc, reset_output
from bokeh.layouts import column, row
from bokeh.models import Button
def plotRoutine(input):
x = np.linspace(0,10)
if input=='cos':
y = np.cos(x)
if input=='sin':
y = np.sin(x)
plot = figure(title = input)
plot.line(x, y)
return plot
def callback():
plot = plotRoutine('sin')
layout.children[1] = plot
plot = plotRoutine('cos')
button = Button(label="Callback button in bokeh server")
button.on_click(callback)
layout = column(button, plot)
curdoc().add_root(layout)
curdoc().title = "bokeh"
Embeds the bokeh app using bokeh server. I am first running bokeh serve --allow-websocket-connection=localhost:5006 --allow-websocket-connection=localhost:8080 bokeh.py
in command prompt to start the bokeh server. Then I start my flask app on localhost:8080.
from flask import render_template, request, g
from flask_appbuilder import ModelView, BaseView, expose, has_access
from bokeh.embed import autoload_server
class Bokeh(BaseView):
default_view = 'bokeh'
@expose("/")
@has_access
def bokeh(self):
script = autoload_server(model=None, url="http://localhost:5006/bokeh")
return self.render_template('bokeh.html', bokeh_script=script)
appbuilder.add_view(Bokeh(), "Bokeh", href="/bokeh/")
Has a button that I would like to somehow trigger the callback inside the bokeh.py.
{% extends "appbuilder/base.html" %}
{% block content %}
<script>
$(document).ready(function () {
document.getElementById("flaskButton").onclick = function () {
// CODE HERE TO TRIGGER CALLBACK?
};
});
</script>
<div id="bokeh_app">
{{ bokeh_script|safe }}
</div>
<button id="flaskButton">Callback button in Flask</button>
{% endblock %}
Upvotes: 21
Views: 1731
Reputation: 116
A quick and dirty way looks to be to right-click on the Bokeh button in your browser and select 'Inspect Element'. You should see the defined onClick function. From there you should be able to provide that same onClick function to your button in your Flask app:
$(document).ready(function () {
document.getElementById("flaskButton").onclick = [onClick function from Bokeh button];
});
The above only applies if you wish to keep both buttons.
Upvotes: 1