ipywidgets icon indicating copy to clipboard operation
ipywidgets copied to clipboard

Pickle an ipywidget

Open mhangaard opened this issue 5 years ago • 7 comments
trafficstars

It would be amazing if it was possible to pickle an ipywidget. I can pickle and unpickle a plotly.graph_objects.FigureWidget with no problem, so why not ipywidgets?

If I attempt to pickle an ipywidget.Button for example, I get this: Log

---------------------------------------------------------------------------
PicklingError                             Traceback (most recent call last)
<ipython-input-47-210db5043c03> in <module>
      1 mybutton = ipywidgets.Button(description="Test")
      2 with open('test_ipywidget.pkl', 'wb') as f:
----> 3     pickle.dump(mybutton, f)

PicklingError: Can't pickle <built-in function input>: it's not the same object as builtins.input

To reproduce

import pickle
import ipywidgets

mybutton = ipywidgets.Button(description="Test")
with open('test_ipywidget.pkl', 'wb') as f:
    pickle.dump(mybutton, f)

My environment

Environment
Python 3.8.2
[GCC 7.3.0] on linux
...
nodejs 13.9.0
ipython 7.14.0
ipywidgets 7.5.1
JupyterLab v2.0.1
@jupyter-widgets/base v3.0.0 enabled OK
@jupyter-widgets/jupyterlab-manager v2.0.0 enabled OK
...

mhangaard avatar May 19 '20 10:05 mhangaard

I'm also interested in this — would be great to be able to pickle/restore ipywidgets, if that's at all possible?

alexstaravoitau avatar Jun 17 '20 14:06 alexstaravoitau

Not sure if this solves it, but you can pickle the state: pickle.dump(mybutton.getState(), f) and restore it that way

cabreraalex avatar Jul 24 '20 23:07 cabreraalex

How to solve it? ipywidgets can not be saved withpickle.dump. I tried to use get_state and send_state, but it does not work.

w_is =  widgets.IntSlider(
        value=7,
        min=0,
        max=10,
        step=1,
        description='Test:',
        disabled=False,
        continuous_update=False,
        orientation='horizontal',
        readout=True,
        readout_format='d'
        )

# pickle.dump(w_is,open('w_is.pkl','wb'))
# PicklingError: Can't pickle <function <lambda> at 0x0000023391B3FEE0>: attribute lookup <lambda> on jupyter_client.session failed

w_is_state = w_is.get_state()
pickle.dump(w_is_state,open('w_is_state.pkl','wb'))
w_is_state = pickle.load(open('w_is_state.pkl','rb'))
type(w_is_state) # dict

w_is_new = widgets.IntSlider() # dummy
w_is_new.send_state(w_is_state)
w_is_new # does not recieve arguments from w_is_state

# OR

w_is_new.set_state(w_is_state)
w_is_new # does not recieve arguments from w_is_state

itsergiu avatar Jul 15 '21 12:07 itsergiu

I'm not sure if send_state is the right function. Is there a set_state()?

cabreraalex avatar Jul 15 '21 14:07 cabreraalex

I tried w_is_new.send_state(w_is_state) and it does not work either.

itsergiu avatar Jul 16 '21 06:07 itsergiu

Is there any other way to download the entire widget (including the children widgets) as a file, so that it can be loaded again next time?

kirk0306 avatar Aug 23 '23 14:08 kirk0306

The exception raised when attempting to pickle an ipywidget is very ambiguous. In my case the widget was one attribute of a larger class instance, so it took me days to find this page. I think it would be very helpful if a custom, more descriptive exception was raised

@kirk0306 the workaround to pickle a set of widgets is to just pickle a class instance that has a .create_and_display_widgets() method. You just need to make sure to overide the attribute that stores the displayed widgets created by that call before calling pickle.dump(). This workaround solved the problem for my use case.

AyhamSaffar avatar Jun 28 '24 12:06 AyhamSaffar