Open anant-k-singh opened 3 years ago
I think this is a tricky problem that has not yet been fully solved. There was some good discussion here: https://github.com/martinRenou/ipycanvas/issues/77
Two people who maybe are interested are @martinRenou and @jtpio
imjoy is an alternative framework on which to build widgets and has implemented https://github.com/imjoy-team/imjoy-rpc which allows for what you want. So also cc. @oeway
I think the relevant lines of how imjoy-rpc does it are these: https://github.com/imjoy-team/imjoy-rpc/blob/30835b1e36d3868ea80a8e2cb3339b9e3048a230/python/imjoy_rpc/rpc.py#L324
It would be really nice to have something like that available through ipywidgets as well.
@ianhi Thanks for tagging me here and advertise ImJoy!
@anant-k-singh To clarify, we had the same issue as you describe here, and I think there isn't a good solution yet. As I understand, this limitation is come form the ipykernel, you can see it also here: https://github.com/ipython/ipykernel/issues/65. There is a work around by caching the jupyter command with https://github.com/kafonek/ipython_blocking, but I think it won't solve the issue you have. I was told that there is an async kernel might solve this, but I haven't figure it out yet. For now, what we did is to avoid using top-level await
.
BTW, I saw you also posted another issue here. If that's the same task you are trying to solve, you might want to try imjoy-jupyter-extension indeed. It is a complementary solution for making interactive widgets. Instead of using a data binding model, we provide an RPC interface which allows you call your JS function in python and vice versa. Here are two examples that works in Jupyter notebooks with the imjoy-jupyter-extension: Kaibu in VueJS and vizarr in react (click the "Open in Binder" badge to run the demo). Briefly, assuming you have a web app in react/vuejs and you want to use it in jupyter notebook, what you do is to load the imjoy-rpc js library into your app, then export some js functions (e.g. process_in_js()), that's it. To use your web app in a notebook as a plugin, you can call imjoy api(api.createWindow(src="URL_OF_YOUR_APP")
) to to instantiate an iframe window for your web app, then you can just call the js function as if they are defined in python. If you pass a callback function from python to js, then you can call that function also from your frontend. To learn more, a more complete tutorial is here.
Here is a possibly helpful snippet to try to get an unblocked await: https://gist.github.com/minrk/feaf2022bf43d1a94e03ceaf9a4ef355
@jasongrout how do you mean by unblocked
? Does that mean it doesn't prevent the message processing?
Also in re-searching about this I came across https://github.com/jupyter-widgets/ipywidgets/issues/2417 and with some more clicking to https://gitter.im/jupyter-widgets/Lobby?at=5e86fe9381a582042e972b4d which looks like it may be the best way to solve awaiting a message from the frontend?
I was told that there is an async kernel might solve this, but I haven't figure it out yet.
akernel is a new Python asynchronous kernel I'm working on. It is still very experimental, but it allows to write the example in the documentation without creating a task, i.e. you can await at the top-level and it won't prevent receiving the value change:
for i in range(10):
print('did work %s'%i)
x = await wait_for_change(slider, 'value')
print('async function continued with value %s'%x)
I have created a custom widget whose frontend renders a plot (using a NPM library). That library has an API that extracts the underlying data of the plot.
In the Jupyter notebook, I run the following:
I want to use this extracted data for ML purposes.
Current behavior: The kernel is blocked at line
res = await self.wait_for_change(...
forever since theget_value()
never executes due to kernel being blocked, kinda deadlock :(According to ipywidget docs,
Since the kernel is blocked (due to await), it doesn't execute the
get_value()
method hence future is never resolved/completed.Please suggest an alternate approach. An approach where kernel is not blocked by the data is received in the
extracted_data
variable after some time would also be helpfulThanks in advance!