I am trying to debug a bokeh app, and thus make explicit calls to the Server. That works fine, apart from the fact that it doesn’t see my bespoke template, i.e., I use
that serves me my app fine, but with the default bokeh template, not my index.html (and yes, I checked that index is set correctly). No error message either, so I am really stumped what I am doing wrong.
It’s possible there is a bug, or maybe it is some usage issue. There’s not really enough information here to speculate. If you can provide a complete Minimal Reproducible Example I will run it directly to investigate.
OK, a very short minimal example (to be put in a directory, to run as app):
Python code (main.py)
#!/usr/bin/python3.9
# 3.9 minimum required for type hinting
import bokeh.models as bkm
import bokeh.layouts as bkl
def main(doc) -> None:
#define a dropdown (left) for menu
menu1 = ['a','b']
dropdown1 = bkm.Dropdown(label="select discipline", menu=menu1)
pnl = bkl.column(dropdown1, name="menu")
doc.add_root(pnl)
#define a placeholder for the right
div=bkm.Div(text='Placeholder',height=40)
pn2= bkl.column(div, name="tabs")
doc.add_root(pn2)
if __name__.startswith('bokeh_app'):
#run under bokeh serve
from bokeh.plotting import curdoc
main(curdoc())
else:
#run as pythion script
from bokeh.application.handlers.function import FunctionHandler
from bokeh.application import Application
from bokeh.server.server import Server
from tornado.ioloop import IOLoop
io_loop = IOLoop.current()
server = Server(applications={'/app': Application(FunctionHandler(main))},
io_loop=io_loop, port=5001,
index='./templates/index.html'
)
server.start()
server.show('/app')
io_loop.start()
@Nirwa I think you have misunderstood what the index parameter is for. It controls whether an automatic index page (i.e. at /) is generated, that lists all the apps currently running on the server. It has nothing to do with templates for an app.
You should set the property setter doc.template and not use the private _template version. Also, FYI setting doc.template is in fact the expected mechanism to specify a template, not a workaround.
I tried the setter first, of course, and it just did not work. The private variable was used as a work around (and it does work!).
Yes, I want to use the bokeh serve in the end, but since my application is a beast (it is a transfer from static matplotlib to bokeh on the web), I have needed python debugging. I want to be able to make a seamless transfer from one to the other–and now I can.
To be honest I don’t really see how that is possible since at present all the setter does is this:
@template.setter
def template(self, template: Template) -> None:
if not isinstance(template, (Template, str)):
raise ValueError("document template must be Jinja2 template or a string")
self._template = template
Thanks Brian,
Your argument looks correct to me!
It just was a bit tired of trying to work out why doc._template = env.get_template('index.html')
works, and doc.template(env.get_template('index.html'))
doesn’t work (TypeError: ‘Template’ object is not callable)