From f6b23f5975a38716652a68ec9a7432c6d6853ce3 Mon Sep 17 00:00:00 2001 From: Mark Gibbs <delsim@users.noreply.github.com> Date: Thu, 10 Nov 2022 15:18:41 -0800 Subject: [PATCH] Fix use of orjson (#428) * Ensure promises are not passed to orjson * Move patch version number Co-authored-by: delsim <dev@gibbsconsulting.ca> Addrresses #421 #404 --- django_plotly_dash/_patches.py | 31 +++++++++++++++++++++++++++---- django_plotly_dash/version.py | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/django_plotly_dash/_patches.py b/django_plotly_dash/_patches.py index cb932d7..de68374 100644 --- a/django_plotly_dash/_patches.py +++ b/django_plotly_dash/_patches.py @@ -29,11 +29,11 @@ SOFTWARE. import json -from plotly.io._json import config +from plotly.io._json import config, clean_to_json_compatible from plotly.utils import PlotlyJSONEncoder from _plotly_utils.optional_imports import get_module -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.utils.functional import Promise @@ -41,10 +41,30 @@ class DjangoPlotlyJSONEncoder(PlotlyJSONEncoder): """Augment the PlotlyJSONEncoder class with Django delayed processing""" def default(self, obj): if isinstance(obj, Promise): - return force_text(obj) + return force_str(obj) return super().default(obj) +def promise_clean_to_json_compatible(obj): + + if isinstance(obj, dict): + return {promise_clean_to_json_compatible(k): promise_clean_to_json_compatible(v) for k, v in obj.items()} + + if isinstance(obj, (list, tuple)): + if obj: + return [promise_clean_to_json_compatible(v) for v in obj] + + if isinstance(obj, Promise): + return force_str(obj) + + #try: + # return obj.to_plotly_json() + #except AttributeError: + # pass + + return obj + + def to_json_django_plotly(plotly_object, pretty=False, engine=None): """ Convert a plotly/Dash object to a JSON string representation @@ -115,6 +135,7 @@ def to_json_django_plotly(plotly_object, pretty=False, engine=None): opts |= orjson.OPT_INDENT_2 # Plotly + try: plotly_object = plotly_object.to_plotly_json() except AttributeError: @@ -132,8 +153,10 @@ def to_json_django_plotly(plotly_object, pretty=False, engine=None): datetime_allowed=True, modules=modules, ) - return orjson.dumps(cleaned, option=opts).decode("utf8") + cleaned = promise_clean_to_json_compatible(cleaned) + + return orjson.dumps(cleaned, option=opts).decode("utf8") import plotly.io.json plotly.io.json.to_json_plotly = to_json_django_plotly diff --git a/django_plotly_dash/version.py b/django_plotly_dash/version.py index a05b31b..200e795 100644 --- a/django_plotly_dash/version.py +++ b/django_plotly_dash/version.py @@ -23,4 +23,4 @@ SOFTWARE. ''' -__version__ = "2.1.1" +__version__ = "2.1.2" -- GitLab