Hi all,
I have a bokeh app that, depending on user input, may require a lengthy (~10 second) processing/calculation step. Because I don’t want to the user to just sit there thinking the app is broken, I’d like to use a PreText field that displays the status. So normally the PreText text will be something like “Please select an option”, but when a user select the option that triggers the long calculation, I’d like to update that text with “Pulling data from the database”, “Calculating metrics”, etc.
The example below shows the concept of what I’d like to do. It’s just a select widget and a PreText field. The select widget has a callback that triggers a set_selection
method, which runs a for-loop that should result in the PreText reading ‘testing 1’, followed by a 1 second delay, then ‘testing 2’, etc. However, the increments are never displayed. The app waits until the loop is completely finished and then displays the final ‘testing 3’. How can I get the PreText field to update at each stage of the loop - not just the last one?
I looked at the slideshow example in the repository, but that relies on cursession
, which doesn’t seem to work when loading a script into bokeh server from the command line.
Many thanks,
Schaun
from bokeh.properties import Instance, String
from bokeh.models.widgets.markups import PreText
from bokeh.models.widgets.layouts import VBox, VBoxForm
from bokeh.models.widgets.inputs import Select
from bokeh.server.app import bokeh_app
from bokeh.server.utils.plugins import object_page
from bokeh.plotting import curdoc
from time import sleep
class Progress(VBox):
extra_generated_classes = [[“Progress”, “Progress”, “VBox”]]
jsmodel = “VBox”
layout boxes
input_box = Instance(VBoxForm)
paragraph = Instance(PreText)
inputs
type_select = Instance(Select)
types = String(default=‘1’)
def init(self, *args, **kwargs):
super(Progress, self).init(*args, **kwargs)
@classmethod
def create(cls):
obj = cls()
obj.input_box = VBoxForm()
obj.paragraph = PreText(text=‘Select something.’)
obj.set_inputs()
obj.set_children()
return obj
def set_inputs(self):
self.type_select = Select(value=‘1’, options=[‘1’, ‘2’, ‘3’])
def set_children(self):
self.input_box.children = [self.type_select]
self.children = [self.input_box, self.paragraph]
curdoc().add(self)
def set_selection(self, obj, attr, old, new):
if obj == self.type_select:
self.types = new
for i in range(1, 4):
self.paragraph.text = ‘testing {ind}’.format(ind=i)
self.set_children()
sleep(1.0)
def setup_events(self):
super(Progress, self).setup_events()
if self.type_select:
self.type_select.on_change(‘value’, self, ‘set_selection’)
@bokeh_app.route("/bokeh/progress/")
@object_page(“progress”)
def make_menu():
app = Progress.create()
return app
``