holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.84k stars 520 forks source link

A way to create panes using ReactiveHTML - TypeError: Object of type Chart is not JSON serializable #3149

Open MarcSkovMadsen opened 2 years ago

MarcSkovMadsen commented 2 years ago

I'm trying to create a Pane in Panel using ReactiveHTML. The problem is that the object is not serializable.

I use another parameter spec to send the json spec across.

Solution

Either provide a way to not include a parameter in the "datamodel" or document how this case should be handled.

import panel as pn
import param
import altair as alt
import pandas as pd

class Component(pn.reactive.ReactiveHTML):
    object = param.ClassSelector(class_=alt.TopLevelMixin)
    spec = param.String(doc="The json spec of the object")

    _template = """<div id="view">Hello</div>"""

    @param.depends("object", watch=True, on_init=True)
    def _update_spec(self):
        self.spec="something"

source = pd.DataFrame({
    'a': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'b': [28, 55, 43, 91, 81, 53, 19, 87, 52]
})

chart=alt.Chart(source).mark_bar().encode(
    x='a',
    y='b'
)

Component(object=chart).servable()
$ panel serve 'script.py' --auto --show
2022-01-28 06:46:58,034 Starting Bokeh server version 2.4.2 (running on Tornado 6.1)
2022-01-28 06:46:58,040 User authentication hooks NOT provided (default user enabled)
2022-01-28 06:46:58,041 Bokeh app running at: http://localhost:5006/script        
2022-01-28 06:46:58,042 Starting Bokeh server with process id: 35360
2022-01-28 06:46:58,494 WebSocket connection opened
2022-01-28 06:46:58,495 ServerConnection created
2022-01-28 06:46:58,498 error handling message
 message: Message 'PULL-DOC-REQ' content: {} 
 error: TypeError('Object of type Chart is not JSON serializable')
Traceback (most recent call last):
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\server\protocol_handler.py", line 97, in handle
    work = await handler(message, connection)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\server\session.py", line 93, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\server\session.py", line 258, in _handle_pull
    return connection.protocol.create('PULL-DOC-REPLY', message.header['msgid'], self.document)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\protocol\__init__.py", line 137, in create
    return self._messages[msgtype].create(*args, **kwargs)  # type: ignore [attr-defined]
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\protocol\messages\pull_doc_reply.py", line 85, in create
    content = PullDoc(doc=document.to_json())
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\document\document.py", line 758, in to_json
    doc_json = self.to_json_string()
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\document\document.py", line 790, in to_json_string
    return serialize_json(json, indent=indent)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\core\json_encoder.py", line 171, in serialize_json
    return json.dumps(obj, cls=BokehJSONEncoder, allow_nan=False, indent=indent, separators=separators, sort_keys=True, **kwargs)
  File "C:\Program Files\Python39\lib\json\__init__.py", line 234, in dumps       
    return cls(
  File "C:\Program Files\Python39\lib\json\encoder.py", line 199, in encode       
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Program Files\Python39\lib\json\encoder.py", line 257, in iterencode   
    return _iterencode(o, 0)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\core\json_encoder.py", line 265, in default
    return self.transform_python_types(obj)
  File "c:\repos\private\panel-vegafusion\.venv\lib\site-packages\bokeh\core\json_encoder.py", line 234, in transform_python_types
    return super().default(obj)
  File "C:\Program Files\Python39\lib\json\encoder.py", line 179, in default      
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Chart is not JSON serializable
2022-01-28 06:47:06,676 WebSocket connection closed: code=1001, reason=None
philippjfr commented 2 years ago

precedence=-1 is the way to not include it.

MarcSkovMadsen commented 2 years ago

Or _rename = {"object": None}. I used that one.

It might be an idea to keep this one open until its been documented.