Skip to content

Commit 221c29c

Browse files
support pattern matching (#307)
* support for component with pattern as ids * add a NotImplementedError for the pattern match case when updating current state (todo: implement it) Co-authored-by: GFJ138 <sebastien.dementen@engie.com>
1 parent b2d160f commit 221c29c

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

django_plotly_dash/dash_wrapper.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,15 @@ def run(self, *args, **kwargs):
383383
def register_blueprint(self, *args, **kwargs):
384384
pass
385385

386+
387+
def compare(id_python, id_dash):
388+
"""Compare an id of a dash component as a python object with an id of a component
389+
in dash syntax. It handles both id as str or as dict (pattern-matching)"""
390+
if isinstance(id_python, dict):
391+
return "{" in id_dash and id_python == json.loads(id_dash)
392+
return id_python == id_dash
393+
394+
386395
class WrappedDash(Dash):
387396
'Wrapper around the Plotly Dash application instance'
388397
# pylint: disable=too-many-arguments, too-many-instance-attributes
@@ -436,10 +445,16 @@ def augment_initial_layout(self, base_response, initial_arguments=None):
436445
if initial_arguments:
437446
if isinstance(initial_arguments, str):
438447
initial_arguments = json.loads(initial_arguments)
448+
else:
449+
initial_arguments = {}
450+
451+
# Define overrides as self._replacements updated with initial_arguments
452+
overrides = dict(self._replacements)
453+
overrides.update(initial_arguments)
439454

440455
# Walk tree. If at any point we have an element whose id
441456
# matches, then replace any named values at this level
442-
reworked_data = self.walk_tree_and_replace(baseData, initial_arguments)
457+
reworked_data = self.walk_tree_and_replace(baseData, overrides)
443458

444459
response_data = json.dumps(reworked_data,
445460
cls=PlotlyJSONEncoder)
@@ -473,10 +488,15 @@ def walk_tree_and_replace(self, data, overrides):
473488
replacements = {}
474489
# look for id entry
475490
thisID = data.get('id', None)
476-
if thisID is not None:
477-
replacements = overrides.get(thisID, None) if overrides else None
478-
if not replacements:
479-
replacements = self._replacements.get(thisID, {})
491+
if isinstance(thisID, dict):
492+
# handle case of thisID being a dict (pattern) => linear search in overrides dict
493+
for k, v in overrides.items():
494+
if compare(id_python=thisID, id_dash=k):
495+
replacements = v
496+
break
497+
elif thisID is not None:
498+
# handle standard case of string thisID => key lookup
499+
replacements = overrides.get(thisID, {})
480500
# walk all keys and replace if needed
481501
for k, v in data.items():
482502
r = replacements.get(k, None)
@@ -628,15 +648,15 @@ def dispatch_with_args(self, body, argMap):
628648

629649
for component_registration in callback_info['inputs']:
630650
for c in inputs:
631-
if c['property'] == component_registration['property'] and c['id'] == component_registration['id']:
651+
if c['property'] == component_registration['property'] and compare(id_python=c['id'],id_dash=component_registration['id']):
632652
v = c.get('value', None)
633653
args.append(v)
634654
if da:
635655
da.update_current_state(c['id'], c['property'], v)
636656

637657
for component_registration in callback_info['state']:
638658
for c in states:
639-
if c['property'] == component_registration['property'] and c['id'] == component_registration['id']:
659+
if c['property'] == component_registration['property'] and compare(id_python=c['id'],id_dash=component_registration['id']):
640660
v = c.get('value', None)
641661
args.append(v)
642662
if da:
@@ -670,6 +690,9 @@ def dispatch_with_args(self, body, argMap):
670690
if da.have_current_state_entry(output_id, output_property):
671691
value = root_value.get(output_id,{}).get(output_property, None)
672692
da.update_current_state(output_id, output_property, value)
693+
else:
694+
# todo: implement saving of state for pattern matching ouputs
695+
raise NotImplementedError("Updating state for dict keys (pattern matching) is not yet implemented")
673696

674697
return res
675698

0 commit comments

Comments
 (0)