posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
41 stars 2 forks source link

Error: Decimal('503025.00') is not JSON serializable #138

Closed aman7000 closed 3 months ago

aman7000 commented 4 months ago

shiny.express issue in @render_plotly in shinywidgets when reading from pandas using psycopg2. unable to serialize Decimal data type.

Log INFO: ('127.0.0.1', 60100) - "WebSocket /websocket/" [accepted] INFO: connection open Traceback (most recent call last): File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shiny/session/_session.py", line 1086, in output_obs value = await renderer.render() ^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_render_widget_base.py", line 87, in render widget = as_widget(value) ^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_as_widget.py", line 26, in as_widget res = _as_widget(x) ^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_as_widget.py", line 75, in as_widget_plotly return go.FigureWidget(x.data, x.layout) # type: ignore ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/plotly/graph_objs/_figurewidget.py", line 633, in init super(FigureWidget, self).init(data, layout, frames, skip_invalid, kwargs) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/plotly/basewidget.py", line 108, in init super(BaseFigureWidget, self).init( File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/plotly/basedatatypes.py", line 522, in init self._data = [deepcopy(trace._props) for trace in data] ^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/plotly/basedatatypes.py", line 717, in setattr super(BaseFigure, self).setattr(prop, value) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/traitlets/traitlets.py", line 729, in set self.set(obj, value) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/traitlets/traitlets.py", line 3007, in set return super().set(obj, value) ^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/traitlets/traitlets.py", line 718, in set obj._notify_trait(self.name, old_value, new_value) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/traitlets/traitlets.py", line 1501, in _notify_trait self.notify_change( File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/ipywidgets/widgets/widget.py", line 693, in notify_change self.send_state(key=name) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/ipywidgets/widgets/widget.py", line 579, in send_state self._send(msg, buffers=buffers) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/ipywidgets/widgets/widget.py", line 818, in _send self.comm.send(data=msg, buffers=buffers) File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_comm.py", line 85, in send self._publish_msg( File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_comm.py", line 165, in _publish_msg msg_txt = json_packer(msg) ^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_serialization.py", line 20, in json_packer return json.dumps( ^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/json/init.py", line 238, in dumps kw).encode(obj) ^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/json/encoder.py", line 200, in encode chunks = self.iterencode(o, _one_shot=True) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/json/encoder.py", line 258, in iterencode return _iterencode(o, 0) ^^^^^^^^^^^^^^^^^ File "/Users/amansingh/anaconda3/lib/python3.11/site-packages/shinywidgets/_serialization.py", line 47, in json_default raise TypeError("%r is not JSON serializable" % obj) TypeError: Decimal('503025.00') is not JSON serializable

cpsievert commented 4 months ago

A (minimal) reproducible example would be much appreciated, thanks!

aman7000 commented 3 months ago

Shiny App

from shiny.express import input, render, ui
from shinywidgets import render_plotly, render_widget
import pandas as pd
import plotly.express as px
import psycopg2
conn = psycopg2.connect(host="localhost",database="db",user="postgres",password="postgres")
cur = conn.cursor()
cur.execute("select account_code, amount from tab")
rows = cur.fetchall()
dfp = pd.DataFrame(rows)
dfp.columns = [desc[0] for desc in cur.description]

with ui.card(full_screen=True):
    @render_plotly
    def pie():
        return px.pie(dfp, values='amount', names='account_code')

Postgres Database dump db.sql

CREATE TABLE tab (
    id serial primary key,
    account_code character varying(10),
    amount numeric(12,5)
);
insert into tab (account_code,amount) values ('A',10000.00);
insert into tab (account_code,amount) values ('B',50000.00);
aman7000 commented 3 months ago

A (minimal) reproducible example would be much appreciated, thanks!

A minimal reproducible example was submitted last week.