问题
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
docker run --rm -p 8888:8888 -e JUPYTER_ENABLE_LAB=yes jupyter/datascience-notebook start-notebook.sh --NotebookApp.token=''
firefox 0.0.0.0:8888
- create a new python3 notebook
- create a cell and enter the code below
- run cell
- 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