How to add html and css files in bokeh server

One basic question
How can I add html and css code to bokeh serve app?
Example code

#from Filter_Data import generate_datafram,get_requied_dates,get_bp_data
button = Button(label="Foo")
l = ["yes","no"]

select = Select(title="Option:",options=l)#filt_source.data["lables"]

fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']

temp_source = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 3, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}

source = ColumnDataSource(data=temp_source)

p = figure(x_range=source.data["fruits"],plot_height=350, title="Fruit Counts by Year",
           toolbar_location=None, tools="")

p.vbar(x=dodge('fruits', -0.25, range=p.x_range), top='2015', width=0.2, source=source,
       color="#c9d9d3", legend_label="2015")

p.vbar(x=dodge('fruits',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,
       color="#718dbf", legend_label="2016")

p.vbar(x=dodge('fruits',  0.25, range=p.x_range), top='2017', width=0.2, source=source,
       color="#e84d60", legend_label="2017")



def refresh_button():
    select.options = ['A',"B","C"]


def get_data(name):
    
    if name == "A":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        
        data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 3, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
        
    elif name == "B":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        data = {'fruits' : fruits,
        '2015'   : [0, 1, 4, 3, 2, 4],
        '2016'   : [0, 3, 3, 2, 4, 6],
        '2017'   : [1, 2, 4, 4, 5, 3]}

    elif name == "C":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        data = {'fruits' : fruits,
        '2015'   : [0, 1, 4, 3, 2, 4],
        '2016'   : [0, 0, 3, 2, 4, 6],
        '2017'   : [1, 2, 4, 4, 5, 3]}

    else:
        print("No values")
    return data


def select_graph(attrname,old,new):
    #update date in ColumnDataSource chala imporatant step
    data = get_data(new)
    source.data = data
    
button.on_click(refresh_button)
select.on_change('value', select_graph)
lay_out = layout([button],[select],[p]) 
curdoc().add_root(lay_out)

It generates output like this:

I have check the Server App Examples from bokeh html template are used over there( export_csv) but dont know how it template and python code is connected??

I presume you meant templates as mentioned here: Bokeh server — Bokeh 3.3.2 Documentation

The Bokeh code checks if the templates directory with an index.html file exists. If it does, it’s used as Jinja2 template for embedding Bokeh documents.

Hello,

I have create templates folder and created index.html file in it, but I am receiving
500: Internal Server Error .
ValueError: root with ‘bokeh_jinja_figure’ name not found

I have added the figure name

p = figure(x_range=source.data["fruits"],plot_height=350, title="Fruit Counts by Year",
           toolbar_location=None, tools="",name = "bokeh_jinja_figure")

and for index template base template is given by bokeh right?
Index html

{% extends base %}

{% block contents %}
<div>
	<h1> hello</h1>
    {{ embed(roots.bokeh_jinja_figure) }}

</div>
{% endblock %}

main.py

from bokeh.models import ColumnDataSource,DataTable, DateFormatter, TableColumn
from bokeh.plotting import figure, output_file, show
from bokeh.models.widgets import Select,Button,TextInput,Paragraph
from bokeh.io import curdoc
from bokeh.layouts import column, row,layout
from bokeh.io import output_file, show
from bokeh import models
import pandas as pd
from bokeh.transform import dodge


#from Filter_Data import generate_datafram,get_requied_dates,get_bp_data
button = Button(label="Foo")
l = ["yew","no"]

select = Select(title="Option:",options=l)#filt_source.data["lables"]

fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']

temp_source = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 3, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}

source = ColumnDataSource(data=temp_source)

p = figure(x_range=source.data["fruits"],plot_height=350, title="Fruit Counts by Year",
           toolbar_location=None, tools="",name = "bokeh_jinja_figure")

p.vbar(x=dodge('fruits', -0.25, range=p.x_range), top='2015', width=0.2, source=source,
       color="#c9d9d3", legend_label="2015")

p.vbar(x=dodge('fruits',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,
       color="#718dbf", legend_label="2016")

p.vbar(x=dodge('fruits',  0.25, range=p.x_range), top='2017', width=0.2, source=source,
       color="#e84d60", legend_label="2017")



def refresh_button():
    select.options = ['A',"B","C"]


def get_data(name):
    
    if name == "A":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        
        data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 3, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
        
    elif name == "B":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        data = {'fruits' : fruits,
        '2015'   : [0, 1, 4, 3, 2, 4],
        '2016'   : [0, 3, 3, 2, 4, 6],
        '2017'   : [1, 2, 4, 4, 5, 3]}

    elif name == "C":
        fruits= ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
        data = {'fruits' : fruits,
        '2015'   : [0, 1, 4, 3, 2, 4],
        '2016'   : [0, 0, 3, 2, 4, 6],
        '2017'   : [1, 2, 4, 4, 5, 3]}

    else:
        print("No values")
    return data


def select_graph(attrname,old,new):
    #update date in ColumnDataSource chala imporatant step
    data = get_data(new)
    source.data = data
    
button.on_click(refresh_button)
select.on_change('value', select_graph)
lay_out = layout([button],[select],[p]) 
curdoc().add_root(lay_out)

python command
(Bokhe_Application) D:\Bokhe_Application>python -m bokeh serve --sh
ow Newfolder

That’s because you call add_root on the whole layout but specify name = "bokeh_jinja_figure" only for the figure. You should move the name to the call to layout.

1 Like

ohh!! :sweat_smile: :sweat_smile:
Thank you.

Hello @p-himik

how can we update values from column Data Source as template variable
** Column Data Source Values are changing as per the selection.

One method is that :
we can use Div,Pre-Text from Bokeh widgets and embed it in template
Is there any other way we can do it??

I don’t understand what you want. Do you mean you want to see values from a column data source be used in an HTML template? If so, then the answer is no. You will have to pass the values explicitly to something like Div, yes.

1 Like