33import json
44import uuid
55from importlib .resources import files
6+ from typing import Any , Union
67
78from IPython .display import HTML
89
@@ -40,11 +41,37 @@ def __init__(self) -> None:
4041 with screenshot_path .open ("r" , encoding = "utf-8" ) as file :
4142 self .screenshot_svg = file .read ()
4243
43- def unsupported_field_type_error (self , e : TypeError , entity : str ) -> Exception :
44+ @staticmethod
45+ def unsupported_field_type_error (e : TypeError , entity : str ) -> Exception :
4446 if "not JSON serializable" in str (e ):
4547 return ValueError (f"A field of a { entity } object is not supported: { str (e )} " )
4648 return e
4749
50+ @staticmethod
51+ def _serialize_entity (entity : Union [Node , Relationship ]) -> dict [str , Any ]:
52+ try :
53+ entity_dict = entity .to_dict ()
54+ json .dumps (entity_dict )
55+ return entity_dict
56+ except TypeError :
57+ props_as_strings = {}
58+ for k , v in entity_dict ["properties" ].items ():
59+ try :
60+ json .dumps (v )
61+ except TypeError :
62+ props_as_strings [k ] = str (v )
63+ entity_dict ["properties" ].update (props_as_strings )
64+
65+ try :
66+ json .dumps (entity_dict )
67+ return entity_dict
68+ except TypeError as e :
69+ # This should never happen anymore, but just in case
70+ if "not JSON serializable" in str (e ):
71+ raise ValueError (f"A field of a { type (entity ).__name__ } object is not supported: { str (e )} " )
72+ else :
73+ raise e
74+
4875 def render (
4976 self ,
5077 nodes : list [Node ],
@@ -54,14 +81,8 @@ def render(
5481 height : str ,
5582 show_hover_tooltip : bool ,
5683 ) -> HTML :
57- try :
58- nodes_json = json .dumps ([node .to_dict () for node in nodes ])
59- except TypeError as e :
60- raise self .unsupported_field_type_error (e , "node" )
61- try :
62- rels_json = json .dumps ([rel .to_dict () for rel in relationships ])
63- except TypeError as e :
64- raise self .unsupported_field_type_error (e , "relationship" )
84+ nodes_json = json .dumps ([self ._serialize_entity (node ) for node in nodes ])
85+ rels_json = json .dumps ([self ._serialize_entity (rel ) for rel in relationships ])
6586
6687 render_options_json = json .dumps (render_options .to_dict ())
6788 container_id = str (uuid .uuid4 ())
0 commit comments