Question: How to wait (in a blocking way) for messages from widget frontend?
See original GitHub issueI 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.
class My_Custom_Widget(widgets.DOMWidget):
...
def wait_for_change(self, value):
future = Future()
# Callback for visual data
def get_value(change):
future.set_result(change.new)
self.unobserve(get_value, value)
self.observe(get_value, value)
return future
async def extract_data_async(self, visual_name):
# "extract_data_request" is part of widget model (a traitlet)
# Changing this model initiates the JS logic on frontend, data will be returned back by updating another model variable "visual_data"
self.extract_data_request = {
'visualName': visual_name
}
res = await self.wait_for_change('visual_data_response')
return res
In the Jupyter notebook, I run the following:
extracted_data = await my_widget.extract_data_async(visual_name='vis_id#4')
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 the get_value()
never executes due to kernel being blocked, kinda deadlock 😦
According to ipywidget docs,
You may want to pause your Python code to wait for some user interaction with a widget from the frontend. Typically this would be hard to do since running Python code blocks any widget messages from the frontend until the Python code is done.
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 helpful
Thanks in advance!
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (5 by maintainers)
Top GitHub Comments
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:
@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?