Add_periodic_callback doesn't work properly if the callback calls add_next_tick_callback?

Hi,

I am trying to drive a top-level callback ‘driver’ function by attaching it as a periodic callback. the driver function itself will make requests from a REST service, and then call add_next_tick_callback to add a subordinate callback.

However, it never displays the webpage. It does display it if the driver function is added with add_next_tick_callback, but fails if added with either add_periodic_callback or add_timeout_callback.

Any ideas why that might be? Or a possible workaround?

# test-server.py
from bokeh.io import curdoc
from bokeh.plotting import figure
from functools import partial

def init_page(doc):
    fig = figure(width=1500, height=600, title='bla')
    doc.add_root(fig)

def driver(doc):
    doc.add_next_tick_callback(partial(init_page, doc))

doc = curdoc()

# works
doc.add_next_tick_callback(partial(driver, doc))

# fail
# doc.add_periodic_callback(partial(driver, doc), 3000)
# doc.add_timeout_callback(partial(driver, doc), 3000)

Launching it, I see:

henry@henry-gs65:streamvis$ bokeh serve streamvis/test-server.py 
2023-04-05 23:30:31,452 Starting Bokeh server version 3.1.0 (running on Tornado 6.1)
2023-04-05 23:30:31,626 User authentication hooks NOT provided (default user enabled)
2023-04-05 23:30:31,628 Bokeh app running at: http://localhost:5006/test-server
2023-04-05 23:30:31,628 Starting Bokeh server with process id: 100587
2023-04-05 23:30:36,159 WebSocket connection opened
2023-04-05 23:30:36,159 ServerConnection created
in init_page
in init_page
...

Thanks in advance!

I don’t think this has anything to do with the callbacks. Rather, add_root does not currently work for “dynamic” (i.e. after init) usage.

Best current WAR is to add a top-level layout like a column once up front and modify it’s children to add or remove “roots”

1 Like

Hi Bryan,

Thanks very much. Yup, that worked:

from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import column
from functools import partial
from time import time

def init_page(doc):
    fig = figure(width=1500, height=600, title=f'Current time = {time()}')
    ch = doc.roots[0].children
    if len(ch) == 0:
        ch.append(fig)
    else:
        ch[0] = fig

def driver(doc):
    doc.add_next_tick_callback(partial(init_page, doc))

doc = curdoc()
doc.add_root(column())
doc.add_periodic_callback(partial(driver, doc), 500)

# I see the plot appear, and the title change periodically as expected
1 Like

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