Thanks. I wanted to explicitly state my appreciation for the prompt and helpful feedback you have provided several times in the short time I have engaged the Panel discourse forum.
The Serving Flask Apps PR is fundamentally different than what I am trying to accomplish in that I have a bokeh server application that is embedded in Flask.
To migrate, I want to retain all of the low-level bokeh models and interactions but replace the layout with Panel equivalents (rows, columns, grids, tabs, etc.) to permit a more dynamic layout where I can add/remove elements from the layout.
It is straightforward to do this running the plain bokeh server and making all of the Panel layout items servable. The missing connection is how to best use these servable items in the Flask app code, which really needs to work with a bokeh document, which has a unique correspondence to each client session.
At first glance, your pointer to the Django Apps does indeed seem to provide the necessary inspiration. It at least allows me to serve the bokeh Flask gunicorn embedded server application with a Panel-based layout replacing the bokeh layout.
For reference, the Flask Gunicorn Embed example, flask_gunicorn_embed.by, can be modified by changing the bkapp()
function to be the following. (The change is to comment-out the doc.add_root()
and replace it with the panel layout and use the server_doc()
method.)
CHANGES HIGHLIGHTED
#doc.add_root(column(slider, plot))
_col = pn.Column(slider, plot)
_col.server_doc(doc)
BKAPP FUNCTION
def bkapp(doc):
df = sea_surface_temperature.copy()
source = ColumnDataSource(data=df)
plot = figure(x_axis_type='datetime', y_range=(0, 25), y_axis_label='Temperature (Celsius)',
title="Sea Surface Temperature at 43.18, -70.43")
plot.line('time', 'temperature', source=source)
def callback(attr, old, new):
if new == 0:
data = df
else:
data = df.rolling('{0}D'.format(new)).mean()
source.data = ColumnDataSource.from_df(data)
slider = Slider(start=0, end=30, value=0, step=1, title="Smoothing by N Days")
slider.on_change('value', callback)
#doc.add_root(column(slider, plot))
_col = pn.Column(slider, plot)
_col.server_doc(doc)
doc.theme = Theme(filename="theme.yaml")