Example runs as a jupyterlab notebook but fails as a standalone server app?

I have the following example, which successfully runs as a jupyterlab notebook, but will not run as a standalone server app.

Here is the code that runs inside JupyterLab (v3.3.2), Bokeh (v3.2.0)

from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CheckboxButtonGroup, CustomJS
from bokeh.plotting import show, figure, output_notebook
import pandas as pd
output_notebook()

def create_plot(doc):
    
    # create fake data
    x = [2, 4, 8, 5, 9, 3]
    y = [4, 8, 2, 7, 4, 6]
    id_ = ['1001', '1002', '1003', '1004', '1005', '1006']
    color = ['red'] + ['green']*5
    df = pd.DataFrame({'x': x, 'y': y, 'ids': id_, 'color': color})

    # create column data source
    cds = ColumnDataSource(data=df)

    # create figure
    p = figure(width=300, height=200)
    p.circle(x='x', y='y', size=5, source=cds, color='color')

    # Create widget (checkbox button)
    checkbox_button_group = CheckboxButtonGroup(labels=id_, active=[0])

    # Update the colors after a click on an id
    checkbox_button_group.js_on_change("active", CustomJS(code="""
        console.log('checkbox_button_group: active=' + this.active, this.toString())
        """))

    def set_col(row, red_ids):
        color = 'red' if row in red_ids else 'green'
        return color

    def update_data(df, red_ids=None):
        if red_ids is None:
            red_ids = []
        
        df['color'] = df['ids'].apply(lambda x: set_col(x, red_ids))
        cds.data = df

    def update(attr, old, new):
        red_ids = [checkbox_button_group.labels[i] for i in checkbox_button_group.active]
        update_data(df, red_ids)

    checkbox_button_group.on_change('active', update)

    # display button & plot in a column
    doc.add_root(column(checkbox_button_group, p))

show(create_plot, notebook_url="localhost:8891")

Here is the modified code, to be run as a bokeh-server app:

# test-app.py

from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CheckboxButtonGroup, CustomJS
from bokeh.plotting import show, figure, curdoc
import pandas as pd

def create_plot(doc):

    # create fake data
    x = [2, 4, 8, 5, 9, 3]
    y = [4, 8, 2, 7, 4, 6]
    id_ = ['1001', '1002', '1003', '1004', '1005', '1006']
    color = ['red'] + ['green']*5
    df = pd.DataFrame({'x': x, 'y': y, 'ids': id_, 'color': color})

    # create column data source
    cds = ColumnDataSource(data=df)

    # create figure
    p = figure(width=300, height=200)
    p.circle(x='x', y='y', size=5, source=cds, color='color')

    # Create widget (checkbox button)
    checkbox_button_group = CheckboxButtonGroup(labels=id_, active=[0])

    # Update the colors after a click on an id
    checkbox_button_group.js_on_change("active", CustomJS(code="""
        console.log('checkbox_button_group: active=' + this.active, this.toString())
        """))

    def set_col(row, red_ids):
        color = 'red' if row in red_ids else 'green'
        return color

    def update_data(df, red_ids=None):
        if red_ids is None:
            red_ids = []

        df['color'] = df['ids'].apply(lambda x: set_col(x, red_ids))
        cds.data = df

    def update(attr, old, new):
        red_ids = [checkbox_button_group.labels[i] for i in checkbox_button_group.active]
        update_data(df, red_ids)

    checkbox_button_group.on_change('active', update)

    # display button & plot in a column
    doc.add_root(column(checkbox_button_group, p))

if __name__ == "__main__":
    create_plot(curdoc)

When I run this with the following command:
bokeh serve --show test-app.py

I get a blank page inside the browser.

curdoc is function that needs to be called

create_plot(curdoc())

Also you need to remove the __main__ check. The module is not main, it is not being run itself, it is being executed inside another python app (the bokeh server)

@mbilyanov there are a lot of examples you can refer to in the repo:

https://github.com/bokeh/bokeh/tree/branch-3.3/examples/server/app

We created all these specifically for users to emulate and get started with.

Your solution has worked, thank you.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.