FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Simple widget persistence by jdfreder · Pull Request #5900 · ipython/ipython · GitHub

Simple widget persistence - #5900

Closed
jdfreder wants to merge 23 commits into
ipython:masterfrom
jdfreder:widgetpersistance
Closed

Simple widget persistence#5900
jdfreder wants to merge 23 commits into
ipython:masterfrom
jdfreder:widgetpersistance

Conversation

Copy link
Copy Markdown
Contributor

Widgets are persisted to a widgets key in the notebook json and widgets key in the cell json for now. Works with page refresh and kernel restart. Widgets are disabled when the comm connection is lost. Persistence also works with nbconvert html output. When the page is refreshed, the Widgets attempt to reconnect to their counterparts in the back-end.

The default nbconvert html output dumps the necessary JS file into the same folder as the output:
nbc notebook.ipynb --to html

To embed the necessary Javascript into your nbconvert output (no extra files):
nbc notebook.ipynb --to html --InlineHTMLPreprocessor.inline_js=True

Enabling these behaviors in nbconvert requires the developers to install r.js via npm and fun fab js in the html directory whenever changes are made to the widget framework.

Copy link
Copy Markdown
Contributor Author

Status update: I'm working on nbconvert support. Investigating using require.js's optimizer.

Copy link
Copy Markdown
Contributor Author

Status update: r.js optimization success. Both embeded and external widget JS works with nbconvert output.

Copy link
Copy Markdown
Contributor Author

Status update: The last commit adds a new fab js command.

jdfreder commented Jun 2, 2014

Copy link
Copy Markdown
Contributor Author

Status update: Widgets will now reconnect on page refresh.

Copy link
Copy Markdown
Member

So if there is a kernel running, and you refresh the page, it will reconnect with the currently-running kernel? Could there be missed messages? What happens if there were missed messages?

jdfreder commented Jun 2, 2014

Copy link
Copy Markdown
Contributor Author

So if there is a kernel running, and you refresh the page, it will reconnect with the currently-running kernel? Could there be missed messages? What happens if there were missed messages?

Hi @jasongrout ! Very glad you came to check-in on this. I was going to ping you for your feedback after making another review pass- I don't want to break any of your single cell server stuff and I value your feedback with the widget stuff because it has helped a lot so far!

Yeah, that's how it's intended to work. Messages shouldn't be lost- I've added a closure that is created if the underlying socket hasn't been created yet. If that's the case, the closure(s) get called when the sockets are reconnected.

If the kernel is new, i.e. a kernel restart, I don't attempt to create any widgets in the back-end. So if you save your notebook with widgets, close ipython, start ipython, and open the same notebook, the widgets will display (with "disabled" = true) but any messages at that point will be discarded (an error will appear in the sys console saying that comm id blah blah doesn't exist).

jdfreder commented Jun 2, 2014

Copy link
Copy Markdown
Contributor Author

jdfreder changed the title Simple widget persistance Simple widget persistence Jun 2, 2014

Copy link
Copy Markdown
Member

Thanks; I've been keeping a close watch on this, though I haven't been looking at the code. I hope to soon, though.

jdfreder commented Jun 5, 2014

Copy link
Copy Markdown
Contributor Author

@ellisonbg when it's convenient, could you post the text from our in person review here?

Copy link
Copy Markdown
Member

notebook.js

  • The disabled widgets should also show up if a notebook is loaded, but no
    kernel is started. This state will be possible in IPython 3.0 when users
    are selecting which kernel to run. Right now, this state is sort of probed
    when a kernel is restarting.
  • Think about renaming WidgetManager.get_model to reflect that it will
    create a model too.
  • I am not sure we have a consistent way of naming private methods in
    notebook.js: _load_widgets and
    _save_widgets.
  • _load_widgets should also work if this.kernel is null.
  • Look into creating WidgetManager.toJSON/fromJSON and then use that from
    Notebook.
  • this.widgets -> this.widgets_data

codecell.js

  • this.saved_widgets -> this.widgets_data
  • CodeCell._load_widgets should work without kernel.
  • Naming of methods with leading underscores
  • this.widgets -> this.widget_ids or this.widget_model_ids

On Thu, Jun 5, 2014 at 4:55 PM, Jonathan Frederic notifications@github.com
wrote:

@ellisonbg https://github.com/ellisonbg when it's convenient, could you
post the text from our in person review here?


Reply to this email directly or view it on GitHub
#5900 (comment).

Brian E. Granger
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgranger@calpoly.edu and ellisonbg@gmail.com

jdfreder commented Jul 8, 2014

Copy link
Copy Markdown
Contributor Author

TODO: #5997

Copy link
Copy Markdown
Member

It would probably make sense to not disable widgets when the comm is closed, but notify the user via a broken link icon or something like this. Indeed, in the case when certain widget models are linked on the JavaScript side (Using things like @jasongrout 's link widget), it would make sense to keep the widgets active to maintain this interaction even if the comm is closed.

Copy link
Copy Markdown
Contributor Author

I talked to @SylvainCorlay in person and I agree, I shouldn't use disabled for the reason he mentions above. How about using http://fontawesome.io/icon/chain-broken/ to symbolize the link is broken?

Copy link
Copy Markdown
Member

I am reading / testing this in the meanwhile. This is related to #6151, #6194 and #6216, in terms of lifetime of widget models and comms.

Copy link
Copy Markdown
Contributor Author

This PR will wait for the PR's @SylvainCorlay mentions. I'll rebase this after they are merged and then I'll implement a comm_alive trait or something similar and use the link icon to denote whether or not the widget is running in a detached state.

Comment thread IPython/html/fabfile.py Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Re-add this line

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

In case where view is not a DOMWidgetView, one should probably not make the widget area visible. Calling view.trigger('displayed') after this line should do the job right?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

How about instead of depending on the class hierarchy to determine visibility, just appending view.el if view.el is not null? (or not falsey?)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Because backbone always has an element...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

backbone views initially set an element, but if I change it, is it ever changed back? What if, in my constructor, I set the this.el to null?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

That would be another method.

In any case, view.trigger('displayed') should be added after the element is appended to the DOM because other things depend on this event, and the line thiswidget_area.show() should probably be removed.

Copy link
Copy Markdown
Contributor Author

There are still a few things to be done here, in addition to the comments above:

  • Fix the nbconvert content (broken after rebase).
  • Make this work with undisplayed models. This will require reference counting.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

It's generally not a good idea to call methods like this on import. A better place is probably in the init stages of the interactive shell object (e.g. init_comm, which already exists).

Copy link
Copy Markdown
Member

Following the hangout of yesterday on this matter with @ellisonbg @minrk @takluyver @jdfreder and @jasongrout .

One of the reservations of @minrk against the persistence of model states in the notebook file format is that it seems to imply that we would need future versions of IPython's widgets to be compatible with these models.

However, the "nbconverted" notebook embeds the optimized version of the JavaScript code, meaning that it will always be usable regardless of the changes in IPython's code. Readablility of the file only depends on the ability of future browsers to execute today's JavaScript.

We would only be sensible to changes in IPython code when loading a notebook ipynb file with a different version of ipython.
In that case, the simple addition of a model version number in widget would solve the issue. If the version numbers don't match, we should not try to re-instantiate models and views from those states.

In doing so, there would not be incremental backward incompatibility due to the persistence. (Backward incompatibility is already introduced when changing the Python API of widgets anyway.)

jdfreder commented Oct 7, 2014

Copy link
Copy Markdown
Contributor Author

This PR is probably going to be broken into small bites as described in the For 3.0 section of the widget Trello: https://trello.com/b/5Xaj8Z7j/widgets

Copy link
Copy Markdown
Contributor Author

Superseded by #6789

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants


Back | FazBrowse Home | New Git URL