Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Asynchronous Widgets on jupyter lab?

How can I use Asynchronous Widgets on jupyter lab?

I'm trying to reproduce the official Asynchronous Widgets-Example on jupyter lab, but the await never continues.

Setup / reproduction

  1. docker run --rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/datascience-notebook start-notebook.sh --NotebookApp.token=''
  2. firefox 0.0.0.0:8888
  3. create a new python3 notebook
  4. create a cell and enter the code below
  5. run cell
  6. move slider

code for the cell

%gui asyncio

import asyncio
def wait_for_change(widget, value):
    future = asyncio.Future()
    def getvalue(change):
        # make the new value available
        future.set_result(change.new)
        widget.unobserve(getvalue, value)
    widget.observe(getvalue, value)
    return future

from ipywidgets import IntSlider
slider = IntSlider()

async def f():
    for i in range(10):
        print('did work %s'%i)
        #x = await asyncio.sleep(1)
        x = await wait_for_change(slider, 'value')
        print('async function continued with value %s'%x)
asyncio.ensure_future(f())
#task = asyncio.create_task(f())
slider

Expected result

The cell outputs

did work 0
async function continued with value 1
did work 1
async function continued with value 2
[...]

Actual output

nothing after the first did work 0

Notes

  • I'm specifically talking about jupyter lab and not about regular jupyter notebooks

  • There is no error-message or anything. The expected output just doesn't happen

  • The minimal asyncio-example does work in jupyter lab:

import asyncio
async def main():
    print('hello')
    await asyncio.sleep(1)
    print('world')
await main()
  • when you leave out the -e JUPYTER_ENABLE_LAB=yes, then you get a regular jupyter notebook without jupyter lab and the expected result happens.

  • this is not a duplicate of ipywidgets widgets values not changing or Jupyter Interactive Widget not executing properly, because these questions nether include jupyter lab nor asyncio

like image 314
wotanii Avatar asked Nov 22 '19 14:11

wotanii


1 Answers

Actually it works, but jupyter lose print output. Try this code:

from IPython.display import display
import ipywidgets as widgets

out = widgets.Output()

import asyncio
def wait_for_change(widget, value):
    future = asyncio.Future()
    def getvalue(change):
        # make the new value available
        future.set_result(change.new)
        widget.unobserve(getvalue, value)
    widget.observe(getvalue, value)
    return future



from ipywidgets import IntSlider
slider = IntSlider()

# Now the key: the container is displayed (while empty) in the main thread
async def f():
    for i in range(10):
        out.append_stdout('did work %s'%i)
        x = await wait_for_change(slider, 'value')
        out.append_stdout('async function continued with value %s'%x)
asyncio.ensure_future(f())

display(slider)
display(out)

You can find more details here: https://github.com/jupyter-widgets/ipywidgets/issues/2567#issuecomment-535971252

like image 154
Algis Avatar answered Oct 02 '22 12:10

Algis