Important
This documentation covers IPython versions 6.0 and higher. Beginning with version 6.0, IPython stopped supporting compatibility with Python versions lower than 3.3 including all versions of Python 2.7.
If you are looking for an IPython version compatible with Python 2.7, please use the IPython 5.x LTS release and refer to its documentation (LTS is the long term support release).
Migrating Widgets to IPython 3¶
Upgrading Notebooks¶
The first thing you’ll notice when upgrading an IPython 2.0 widget notebook to IPython 3.0 is the “Notebook converted” dialog. Click “ok”.
All of the widgets distributed with IPython have been renamed. The “Widget” suffix was removed from the end of the class name. i.e.
ButtonWidget
is nowButton
.ContainerWidget
was renamed toBox
.PopupWidget
was removed from IPython, because bootstrapjs was problematic (creates global variables, etc.). If you use thePopupWidget
, try using aBox
widget instead. If your notebook can’t live without the popup functionality, subclass theBox
widget (both in Python and JS) and use JQuery UI’sdraggable()
andresizable()
methods to mimic the behavior.add_class
andremove_class
were removed. More often than not a new attribute exists on the widget that allows you to achieve the same explicitly. i.e. theButton
widget now has abutton_style
attribute which you can set to ‘primary’, ‘success’, ‘info’, ‘warning’, ‘danger’, or ‘’ instead of usingadd_class
to add the bootstrap class.VBox
andHBox
classes (flexibleBox
subclasses) were added that allow you to avoid usingadd_class
andremove_class
to make flexible box model layouts. As a last resort, if you can’t find a built in attribute for the class you want to use, a new_dom_classes
list trait was added, which combinesadd_class
andremove_class
into one stateful list.set_css
andget_css
were removed in favor of explicit style attributes -visible
,width
,height
,padding
,margin
,color
,background_color
,border_color
,border_width
,border_radius
,border_style
,font_style
,font_weight
,font_size
, andfont_family
are a few. If you can’t find a trait to see the css attribute you need, you can, in order of preference, (A) subclass to create your own custom widget, (B) use CSS and the_dom_classes
trait to set_dom_classes
, or (C) use the_css
dictionary to set CSS styling likeset_css
andget_css
.For selection widgets, such as
Dropdown
, thevalues
argument has been renamed tooptions
.
Upgrading Custom Widgets¶
Javascript¶
If you are distributing your widget and decide to use the deferred loading technique (preferred), you can remove all references to the WidgetManager and the register model/view calls (see the Python section below for more information).
In 2.0 require.js was used incorrectly, that has been fixed and now loading works more like Python’s import. Requiring
widgets/js/widget
doesn’t import theWidgetManager
class, instead it imports a dictionary that exposes the classes within that module:{ 'WidgetModel': WidgetModel, 'WidgetView': WidgetView, 'DOMWidgetView': DOMWidgetView, 'ViewList': ViewList, }
If you decide to continue to use the widget registry (by registering your widgets with the manager), you can import a dictionary with a handle to the WidgetManager class by requiring
widgets/js/manager
. Doing so will import:{'WidgetManager': WidgetManager}
Don’t rely on the
IPython
namespace for anything. To inherit from the DOMWidgetView, WidgetView, or WidgetModel, requirewidgets/js/widget
aswidget
. If you were inheriting from DOMWidgetView, and the code looked like this:IPython.DOMWidgetView.extend({...})
It would become this:
widget.DOMWidgetView.extend({...})
Custom models are encouraged. When possible, it’s recommended to move your code into a custom model, so actions are performed 1 time, instead of N times where N is the number of displayed views.
Python¶
Generally, custom widget Python code can remain unchanged. If you
distribute your custom widget, you may be using display
and
Javascript
to publish the widget’s Javascript to the front-end. That
is no longer the recommended way of distributing widget Javascript.
Instead have the user install the Javascript to his/her nbextension
directory or their profile’s static directory. Then use the new
_view_module
and _model_module
traitlets in combination with
_view_name
and _model_name
to instruct require.js on how to load
the widget’s Javascript. The Javascript is then loaded when the widget
is used for the first time.
Details¶
Asynchronous¶
In the IPython 2.x series the only way to register custom widget views
and models was to use the registry in the widget manager. Unfortunately,
using this method made distributing and running custom widgets difficult. The widget
maintainer had to either use the rich display framework to push the
widget’s Javascript to the notebook or instruct the users to install the
Javascript by hand in a custom profile. With the first method, the
maintainer would have to be careful about when the Javascript was pushed
to the front-end. If the Javascript was pushed on Python widget
import
, the widgets wouldn’t work after page refresh. This is
because refreshing the page does not restart the kernel, and the Python
import
statement only runs once in a given kernel instance (unless
you reload the Python modules, which isn’t straight forward). This meant
the maintainer would have to have a separate push_js()
method that
the user would have to call after importing the widget’s Python code.
Our solution was to add support for loading widget views and models using require.js paths. Thus the comm and widget frameworks now support lazy loading. To do so, everything had to be converted to asynchronous code. HTML5 promises are used to accomplish that (#6818, #6914).
Symmetry¶
In IPython 3.0, widgets can be instantiated from the front-end (#6664). On top of this, a widget persistence API was added (#7163, #7227). With the widget persistence API, you can persist your widget instances using Javascript. This makes it easy to persist your widgets to your notebook document (with a small amount of custom JS). By default, the widgets are persisted to your web browsers local storage which makes them reappear when your refresh the page.
Smaller Changes¶
Latex math is supported in widget
description
s (#5937).Widgets can be display more than once within a single container widget (#5963, #6990).
FloatRangeSlider
andIntRangeSlider
were added (#6050).“Widget” was removed from the ends of all of the widget class names (#6125).
ContainerWidget
was renamed toBox
(#6125).HBox
andVBox
widgets were added (#6125).add\_class
andremove\_class
were removed in favor of a_dom_classes
list (#6235).get\_css
andset\_css
were removed in favor of explicit traits for widget styling (#6235).An
Output
widget was added, which allows you toprint
anddisplay
within widgets (#6670).PopupWidget
was removed (#7341).A visual cue was added for widgets with ‘dead’ comms (#7227).
A
SelectMultiple
widget was added (aSelect
widget that allows multiple things to be selected at once) (#6890).A class was added to help manage children views (#6990).
A warning was added that shows on widget import because it’s expected that the API will change again by IPython 4.0. This warning can be suppressed (#7107, #7200, #7201, #7204).
Comm and Widget PR Index¶
Here is a chronological list of PRs affecting the widget and comm frameworks for IPython 3.0. Note that later PRs may revert changes made in earlier PRs:
Add placeholder attribute to text widgets #5652
Add latex support in widget labels, #5937
Allow widgets to display more than once within container widgets. #5963
use require.js, #5980
Range widgets #6050
Interact on_demand option #6051
Allow text input on slider widgets #6106
support binary buffers in comm messages #6110
Embrace the flexible box model in the widgets #6125
Widget trait serialization #6128
Make Container widgets take children as the first positional argument #6153
once-displayed #6168
Validate slider value, when limits change #6171
Unregistering comms in Comm Manager #6216
Add EventfulList and EventfulDict trait types. #6228
Remove add/remove_class and set/get_css. #6235
avoid unregistering widget model twice #6250
Widget property lock should compare json states, not python states #6332
Strip the IPY_MODEL_ prefix from widget IDs before referencing them. #6377
“event” is not defined error in Firefox #6437
Javascript link #6454
Bulk update of widget attributes #6463
Creating a widget registry on the Python side. #6493
Allow widget views to be loaded from require modules #6494
Fix Issue #6530 #6532
Make comm manager (mostly) independent of InteractiveShell #6540
Add semantic classes to top-level containers for single widgets #6609
Selection Widgets: forcing ‘value’ to be in ‘values’ #6617
Allow widgets to be constructed from Javascript #6664
Output widget #6670
Minor change in widgets.less to fix alignment issue #6681
Make Selection widgets respect values order. #6747
Widget persistence API #6789
Add promises to the widget framework. #6818
SelectMultiple widget #6890
Tooltip on toggle button #6923
Allow empty text box *while typing* for numeric widgets #6943
Ignore failure of widget MathJax typesetting #6948
Refactor the do_diff and manual child view lists into a separate ViewList object #6990
Add warning to widget namespace import. #7107
lazy load widgets #7120
Fix padding of widgets. #7139
Persist widgets across page refresh #7163
Make the widget experimental error a real python warning #7200
Make the widget error message shorter and more understandable. #7201
Make the widget warning brief and easy to filter #7204
Add visual cue for widgets with dead comms #7227
Widget values as positional arguments #7260
Remove the popup widget #7341
document and validate link, dlink #7468
Document interact 5637 #7525
Update some broken examples of using widgets #7547
Use Output widget with Interact #7554
don’t send empty execute_result messages #7560
Validation on the python side #7602
only show prompt overlay if there’s a prompt #7661
Allow predictate to be used for comparison in selection widgets #7674
Fix widget view persistence. #7680
Revert “Use Output widget with Interact” #7703