@@ -57,6 +57,23 @@ def coerce_to_strict(const):
5757 return const
5858
5959
60+ _swap = (
61+ ("<" , "\\ u003c" ),
62+ (">" , "\\ u003e" ),
63+ ("/" , "\\ u002f" ),
64+ ("\u2028 " , "\\ u2028" ),
65+ ("\u2029 " , "\\ u2029" ),
66+ )
67+
68+
69+ def _safe (json_str ):
70+ out = json_str
71+ for unsafe_char , safe_char in _swap :
72+ if unsafe_char in out :
73+ out = out .replace (unsafe_char , safe_char )
74+ return out
75+
76+
6077def to_json_plotly (plotly_object , pretty = False , engine = None ):
6178 """
6279 Convert a plotly/Dash object to a JSON string representation
@@ -120,7 +137,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
120137
121138 from _plotly_utils .utils import PlotlyJSONEncoder
122139
123- return json .dumps (plotly_object , cls = PlotlyJSONEncoder , ** opts )
140+ return _safe ( json .dumps (plotly_object , cls = PlotlyJSONEncoder , ** opts ) )
124141 elif engine == "orjson" :
125142 JsonConfig .validate_orjson ()
126143 opts = orjson .OPT_NON_STR_KEYS | orjson .OPT_SERIALIZE_NUMPY
@@ -136,7 +153,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
136153
137154 # Try without cleaning
138155 try :
139- return orjson .dumps (plotly_object , option = opts ).decode ("utf8" )
156+ return _safe ( orjson .dumps (plotly_object , option = opts ).decode ("utf8" ) )
140157 except TypeError :
141158 pass
142159
@@ -146,7 +163,7 @@ def to_json_plotly(plotly_object, pretty=False, engine=None):
146163 datetime_allowed = True ,
147164 modules = modules ,
148165 )
149- return orjson .dumps (cleaned , option = opts ).decode ("utf8" )
166+ return _safe ( orjson .dumps (cleaned , option = opts ).decode ("utf8" ) )
150167
151168
152169def to_json (fig , validate = True , pretty = False , remove_uids = True , engine = None ):
0 commit comments