[IPython-dev] 'Stateless' interact: a widget experiment
Thomas Kluyver
takowl at gmail.com
Mon Jul 13 16:05:10 EDT 2015
I've been building a skunkworks prototype for the last couple of days, and
I've shown it to a few people this morning. It's a different model for the
high level 'interact' widget interface, to explore how that might be built
on top of raw comms without the synced-model widget architecture.
The key difference is that there's no widget state stored on the kernel
side. Instead, it uses a request/reply pattern, so the frontend sends the
state of the whole collection of widgets on each update. If you open
multiple clients (i.e. the same notebook in two browsers), they interact
with the widgets independently: dragging the sliders on one updates the
result displayed in that one without affecting the other browser. This
works best with pure functions, i.e. not affecting global state.
Before I go further, here's the code:
https://github.com/takluyver/altwidgets-prototype/blob/master/Demo.ipynb
Clone, run the Demo notebook, and fiddle with the widgets.
It doesn't use traitlets, backbone or the widget area in the notebook. It's
pure Python and JS (+jQuery), and the visible widgets sit in an output area
in the notebook.
This has some key benefits: as regular Javascript output, the widgets are
persisted as part of the notebook. Their state is not saved for now (more
on that below), but when you reopen it, the widgets will be in their
starting position, with the initial output shown. If they can connect to
the kernel-side part, they will be enabled and usable; if not, they'll show
up disabled. It should even be possible to show them (disabled) on
nbviewer, but that's not working yet.
Things it doesn't do yet but could fairly easily:
- Widgets other than sliders
- Display of output other than plain text
- Widgets visible on nbviewer
- A nicer Python API (decorators, widget abbreviations, etc.)
Things I'd like that may require some changes in Jupyter:
- Persistence of widget state: I think the key here is a way for JS output
areas to get a handle on the output object that will be stored in the
notebook document. Then they could store this kind of info in the output
metadata.
- Better handling of kernel disconnection/reconnection: e.g. at present, it
disables the widgets on the kernel restarting event, but if I have the
notebook open in two browsers, the event only fires in the one where I
asked for a restart. I'm not sure exactly what happens with comms - it
doesn't look like they're closed when the kernel disconnects or restarts.
- Not dumping duplicate JS in the notebook: we've discussed this before.
There's a chunk of JS that I send each time an interact() displays, and
it's only going to get longer as this project expands. It would be good to
store just one copy of this. I would like it to be saved as part of the
notebook, though, so the widgets can be shown without involving the kernel.
- Showing widgets in untrusted notebooks: this would require the JS to
construct them to be installed as an extension (or part of the notebook) so
we can run that without security issues. I'd probably then use display_json
to put widgets on the page.
Currently, there's no way to update widget state from code in the kernel.
I'm not sure that this really makes sense, since there can be multiple
clients with independent states, but it would probably be possible to
broadcast an update message to the connected clients if we did want that.
I want to emphasise this is very much a *prototype*, not something you want
to use today. I think it's worth exploring because it feels like a much
simpler system than synced-model widgets, and it has the potential to give
us an easier story around persistence. It will never do all the things you
can do with synced-model widgets, and that's quite deliberate.
Thanks,
Thomas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ipython-dev/attachments/20150713/3c513d75/attachment.html>
More information about the IPython-dev
mailing list