Notebook (almost) turned to webapp with ipywidgets - first attempt

1,657 views
Skip to first unread message

oscar6echo

unread,
Sep 5, 2016, 9:29:20 AM9/5/16
to Project Jupyter

This Black Scholes calculator is an attempt to turn a Jupyter notebook into something that looks a bit like a traditional web page.
This kind of notebook, coupled with Jupyterhub, enables building and deploying webapps (admittedly limited in terms of UI) simply and fast.
This is what I am trying to do in a corporate LAN.

In this exemple, I put a relatively complex input form and the results associated within a single composite ipywidget.
Then I hide the code cells with a button and offer an 'Init' button (restart kernel & run all cells).
So the only thing a user needs to do is click it when the notebook starts.

Beyond the official documentation (https://ipywidgets.readthedocs.io/en/latest/index.html) I have seen few examples so far.
So I hope it can help people to build simili web apps inside the notebook.
Also I would be glad to have to feedback particularly if what I wrote can be improved or does not follow best practises. 


Here are some remarks / questions about ipywidgets and frontend js derived from this attempt:

1/
I found that the (Bounded)FloatText change event triggers as soon as a single digit changes.
As a result, it triggers before you can input a number with several digits. Which can be too often.
Example: the case where the FloatText is used to control a max boundary, any change with triggers all observe methods with a single digit number to start with.

Is there a way to have more control over what triggers a change event ?
For example a 'blur' event on the input box

To avoid this unfortunate behavior, I created custom widgets based on HTML input type='number'. Its behavior (and little arrows) is more appropriate, I think, and maybe it could become the default ? I think it would be convenient to have direct access to most possible values of type available in http://www.w3schools.com/tags/att_input_type.asp. One can always create custom widgets to do that, but people won't know what is available, so maybe it could be in the main lib. What do you think ?

2/
Re ipywidgets styling, all widgets have a background_color property but it does not seem to have any styling effect.
Should this property be ignored ?
More generally, is there a way to pass arbitrary css to the widgets ?
To change colors, fonts, etc

3/
Re the list of available widgets, where can I read their python class and javascript code ?
If they are accessible, then it is easy for everyone to make a small variation from a custom widget with a simple copy/paste/adjust.
Exemple: I would like to modify the layout of the RadioButton widget to put the name above the radio buttons, not on the left, so as to take less horizontal space.

4/
Can you recommend a concise way to make the 'Init' and 'Show/Hide' code buttons with ipywidgets.
As opposed to 'manual javascript', as I have done.

5/
The 'save notebook with snapshot' works partly, it seems.
When I reopen the notebook, I get a glimpse of the image soon replaced by some text.
In nbviewer, the image appears twice along with the same parasite text.
Is this behavior identified ?


I am aware that I am asking a lot of questions and that people have little spare time.
But I would be grateful for even rough directions or pointers.

By the way, I find Jupyter & its ecosystem more and more exciting !

Thx

Sylvain Corlay

unread,
Sep 5, 2016, 9:59:05 AM9/5/16
to jup...@googlegroups.com
Dear Olivier,

It is nice to see you on the mailing list. On the subject of ipywidgets-based web applications, another example is the embedding of static widgets in web pages. An example of this can be seen on the jupyter web site: http://jupyter.org/widgets. In this page, widgets are live in that the javascript side of the code is run, but there is no python backend.

For the next version of ipywidgets, one of the goals is 
 - to enable this sort of thing with a backend for the computation using services like binder.
 - to enable the rendering of static widgets in nbviewer
 - to work in jupyterlab out of the box.

Regarding your specific questions, I will respond inline

1/
I found that the (Bounded)FloatText change event triggers as soon as a single digit changes.
As a result, it triggers before you can input a number with several digits. Which can be too often.
Example: the case where the FloatText is used to control a max boundary, any change with triggers all observe methods with a single digit number to start with.

Is there a way to have more control over what triggers a change event ?
For example a 'blur' event on the input box

To avoid this unfortunate behavior, I created custom widgets based on HTML input type='number'. Its behavior (and little arrows) is more appropriate, I think, and maybe it could become the default ? I think it would be convenient to have direct access to most possible values of type available in http://www.w3schools.com/tags/att_input_type.asp. One can always create custom widgets to do that, but people won't know what is available, so maybe it could be in the main lib. What do you think ?

In the case of the slider, we have a `continuous_update` boolean attribute which causes the even to be triggered only when the handle of the slider is released.

For the `FloatText` widget, we do not have this ability at the moment. However, I had a pull request that we did not merge at the time but should be soon reopened, which enabled a differentiation between the change of the content of the input field, and when the value is "submitted" (by hitting enter or focusing to a different area of the page).

2/
Re ipywidgets styling, all widgets have a background_color property but it does not seem to have any styling effect.
Should this property be ignored ?
More generally, is there a way to pass arbitrary css to the widgets ?
To change colors, fonts, etc

Regarding the styling of the widgets in ipywidgets, we *deprecated* all the top-level styling attributes in 5.0. The layout-related attributes are regrouped under the `layout` attribute. The `Widget Styling` example notebook shows how you can leverage the layout attribute to create complex reactive layouts with widgets. Basically, we expose the entire css spec for layout, including flexbox. The example notebook shows how you can use this to generate example such as forms / caroussels etc.

On the subject of top-level styling attributes, the fact that they ceased to function in the latest 5.2 release is a regression and should be fixed in the next minor release of 5.x which I will do soonish. But in any case, a future-proof code should not use these because they conflict with the new approach for widget styling which is to regroup things under "style" attributes.

3/
Re the list of available widgets, where can I read their python class and javascript code ?
If they are accessible, then it is easy for everyone to make a small variation from a custom widget with a simple copy/paste/adjust.
Exemple: I would like to modify the layout of the RadioButton widget to put the name above the radio buttons, not on the left, so as to take less horizontal space.

Indeed, having a joint documentation for the python and the javascript would be interesting. What we really want to get to is live widgets in the RTD documentation. We have a working prototype, but we need some bandwidth / time to complete the work.


4/
Can you recommend a concise way to make the 'Init' and 'Show/Hide' code buttons with ipywidgets.
As opposed to 'manual javascript', as I have done.


from ipywidgets import IntSlider
slider = IntSlider()
slider.layout.visibility = 'hidden'  # 'visible'

or even better

from ipywidgets import ToggleButton, IntSlider, VBox
from traitlets import dlink

def showhide(widget, **kwargs):
    toggle = ToggleButton(value=kwargs.pop('value', True), **kwargs)
    dlink((toggle, 'value'), (widget.layout, 'visibility'),
          lambda val: 'visible' if val else 'hidden')
    return VBox([toggle, widget])

showhide(IntSlider())
 
5/
The 'save notebook with snapshot' works partly, it seems.
When I reopen the notebook, I get a glimpse of the image soon replaced by some text.
In nbviewer, the image appears twice along with the same parasite text.
Is this behavior identified ?

I am not aware of this. Can you please post an issue on GitHub?

Thanks

Sylvain

oscar6echo

unread,
Sep 6, 2016, 6:51:18 PM9/6/16
to Project Jupyter
Sylvain

Thank you for your fast and comprehensive answer.

Re the imperfect behaviour of the 'save notebook with snapshot' function, I posted this issue on GitHub https://github.com/ipython/ipywidgets/issues/754.

I have modified my repo to write the 'Toggle Code Cell' function in 2 ways - 1/ using ipywidgets and 2/ 'manual' javascript.

You can see the result in through nbviewer there.

As expected the custom widget is frozen into a snapshot and could not work as there is no python kernel running.
And the 'manual' javascript is still fully functional as it is pure js embedded in the page.

Question: Is it possible to write pure front end custom widgets (storing some state - in my case boolean code_shown) that will still work in nbviewer ?

If this is possible, then I believe that such exemple could be in the official examples, as many people try to hide the code cells in the context of blogs or live notebook (from what I have read around), and surely would often use such widget.

If not, I think such pure frontend 'half ipywidget' would be very useful to many people. Of course one can do without but a framework is convenient and helps standardize code patterns (Just sharing an opinion).

Anyway thx again for this very useful lib !



Reply all
Reply to author
Forward
0 new messages