0

I'm getting ready to create a communications widget for use in a Jupyter application. I'm trying to understand when the widget's "value" property can be accessed ... it looks like the "value" can be read anytime, but won't match the widget model "value" until cell execution stops (i.e., the widget's browser state isn't updated back to the widget's kernel state).

To test this, I tried creating a small slider widget, waiting for 10 seconds, and then reading the widget "value" property ... all in the same cell. In the 10 seconds, the user (i.e., me) has time to change the slider to something like "5".

Here's a small test that can be run in a cell. When the sleep() happens, I move the slider to value "5".

from ipywidgets import *
import time

slider = IntSlider(
    value=7,
    min=1,
    max=10.0,
    step=1,
    description="Input:",
)

display(slider)
time.sleep(10) # move slider to 5
print("done " + str(slider.value))

I expected "done 5" but got "done 7", implying to me that "value" is updated only after the cell completes.

Is this always true? And is there a way to force synchronization between the widget's browser state and its state in the kernel?

(I do get the expected "done 5" if I move the print() to the following cell.)

Thanks!

bdemchak
  • 263
  • 2
  • 10

2 Answers2

0

There is basically at present no way to automatically force code running in a cell to wait for an event or change in a widget. Things like time.sleep(3) will only freeze the cell and a slider created in the same cell will not display until the sleep is complete.

The user could create a slider in cell 1 and then execute a sleep in cell 2 and then adjust the slider and the code in cell 2 may see the change after the sleep but in this case the synchronization is directed by the user and is not automatic.

You can also start Python code from a widget event, but the Python code does not "run in a cell" and the "prints" will not go to the standard cell output area but the output can be captured in other ways,.

In the following screenshot I use the "Output" widget to capture output from a widget event

enter image description here

The basic problem is that all communication between widgets and kernels is via one-way messages -- there are no "return values" or "acknowledgements" of any kind.

Please see https://github.com/AaronWatters/jp_proxy_widget/blob/master/notebooks/Tutorial.ipynb for more discussion.

Aaron Watters
  • 2,784
  • 3
  • 23
  • 37
  • Thanks for your kind answer ... I have discovered a very interesting library, which I'm posting as an answer to this question. – bdemchak Nov 04 '19 at 23:12
0

As it turns out, there does seem to be a library that uses something like asyncio to achieve an inline wait. It's called jupyter-ui-poll at https://github.com/Kirill888/jupyter-ui-poll. The author says it's available on PyPI at https://pypi.org/project/jupyter-ui-poll/

Very promising! ... otherwise, I'm forced to agree with you.

bdemchak
  • 263
  • 2
  • 10