Skip to content

Commit d19f04c

Browse files
committed
extended ctx.arg_grouping and changed it to AttributeDict
1 parent 2728d83 commit d19f04c

File tree

5 files changed

+65
-4
lines changed

5 files changed

+65
-4
lines changed

dash/_callback_context.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import functools
22
import warnings
33
import json
4+
from copy import deepcopy
45
import flask
56

67
from . import exceptions
@@ -69,7 +70,58 @@ def triggered_ids(self):
6970
@property
7071
@has_context
7172
def args_grouping(self):
72-
return getattr(flask.g, "args_grouping", [])
73+
triggered = getattr(flask.g, "triggered_inputs", [])
74+
triggered = [item["prop_id"] for item in triggered]
75+
grouping = getattr(flask.g, "args_grouping", {})
76+
77+
def update_args_grouping(g):
78+
if isinstance(g, dict) and "id" in g:
79+
prop_id = ".".join((g["id"], g["property"]))
80+
81+
new_values = {
82+
"value": g.get("value"),
83+
"id": g["id"]
84+
if not g["id"].startswith("{")
85+
else json.loads(g["id"]),
86+
"property": g["property"],
87+
"triggered": prop_id in triggered,
88+
}
89+
g.update(new_values)
90+
91+
def recursive_update(g):
92+
if isinstance(g, (tuple, list)):
93+
for i in g:
94+
update_args_grouping(i)
95+
recursive_update(i)
96+
if isinstance(g, dict):
97+
for i in g.values():
98+
update_args_grouping(i)
99+
recursive_update(i)
100+
101+
recursive_update(grouping)
102+
103+
return grouping
104+
105+
# todo not sure whether we need this, but it removes a level of nesting so
106+
# you don't need to use `.value` to get the value.
107+
@property
108+
@has_context
109+
def args_grouping_values(self):
110+
grouping = getattr(flask.g, "args_grouping", {})
111+
grouping = deepcopy(grouping)
112+
113+
def recursive_update(g):
114+
if isinstance(g, (tuple, list)):
115+
for i in g:
116+
recursive_update(i)
117+
if isinstance(g, dict):
118+
for k, v in g.items():
119+
if isinstance(v, dict) and "id" in v:
120+
g[k] = v["value"]
121+
recursive_update(v)
122+
123+
recursive_update(grouping)
124+
return grouping
73125

74126
@property
75127
@has_context

dash/_grouping.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
1515
"""
1616
from dash.exceptions import InvalidCallbackReturnValue
17+
from ._utils import AttributeDict
1718

1819

1920
def flatten_grouping(grouping, schema=None):
@@ -127,14 +128,14 @@ def map_grouping(fn, grouping):
127128
return [map_grouping(fn, g) for g in grouping]
128129

129130
if isinstance(grouping, dict):
130-
return {k: map_grouping(fn, g) for k, g in grouping.items()}
131+
return AttributeDict({k: map_grouping(fn, g) for k, g in grouping.items()})
131132

132133
return fn(grouping)
133134

134135

135136
def make_grouping_by_key(schema, source, default=None):
136137
"""
137-
Create a grouping from a schema by ujsing the schema's scalar values to look up
138+
Create a grouping from a schema by using the schema's scalar values to look up
138139
items in the provided source object.
139140
140141
:param schema: A grouping of potential keys in source

dash/_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def stringify_id(id_):
159159

160160

161161
def inputs_to_dict(inputs_list):
162-
inputs = {}
162+
inputs = AttributeDict()
163163
for i in inputs_list:
164164
inputsi = i if isinstance(i, list) else [i]
165165
for ii in inputsi:

dash/_validate.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ def validate_and_group_input_args(flat_args, arg_index_grouping):
136136
if isinstance(arg_index_grouping, dict):
137137
func_args = []
138138
func_kwargs = args_grouping
139+
for key in func_kwargs:
140+
if not key.isidentifier():
141+
raise exceptions.CallbackException(
142+
f"{key} is not a valid Python variable name"
143+
)
139144
elif isinstance(arg_index_grouping, (tuple, list)):
140145
func_args = list(args_grouping)
141146
func_kwargs = {}

dash/dash.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,7 @@ def callback(_triggers, user_store_data, user_callback_args):
12751275

12761276
def dispatch(self):
12771277
body = flask.request.get_json()
1278+
12781279
flask.g.inputs_list = inputs = body.get( # pylint: disable=assigning-non-slot
12791280
"inputs", []
12801281
)
@@ -1309,9 +1310,11 @@ def dispatch(self):
13091310
# Add args_grouping
13101311
inputs_state_indices = cb["inputs_state_indices"]
13111312
inputs_state = inputs + state
1313+
inputs_state = [AttributeDict(i) for i in inputs_state]
13121314
args_grouping = map_grouping(
13131315
lambda ind: inputs_state[ind], inputs_state_indices
13141316
)
1317+
13151318
flask.g.args_grouping = args_grouping # pylint: disable=assigning-non-slot
13161319
flask.g.using_args_grouping = ( # pylint: disable=assigning-non-slot
13171320
not isinstance(inputs_state_indices, int)

0 commit comments

Comments
 (0)