How can I use Asynchronous Widgets on jupyter lab?

冷暖自知 提交于 2021-02-07 13:12:47

问题


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


回答1:


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




回答2:


I've had luck with jupyter-ui-poll to synchronize widget activity with the Jupyter Python kernal:

https://github.com/Kirill888/jupyter-ui-poll

In particular I used it here:

https://github.com/AaronWatters/jp_doodle/blob/master/jp_doodle/auto_capture.py

Works for me. Hope that helps!



来源:https://stackoverflow.com/questions/58996358/how-can-i-use-asynchronous-widgets-on-jupyter-lab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!