Skip to content

Fix args_grouping to handle "id" in the id #2087

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactored args_grouping
  • Loading branch information
AnnMarieW committed Jun 11, 2022
commit 84b6b6731dca2e4b371f9767c95941e65fd0adc5
58 changes: 2 additions & 56 deletions dash/_callback_context.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import functools
import warnings
import json
from copy import deepcopy
import flask

from . import exceptions
from ._utils import stringify_id, AttributeDict
from ._utils import AttributeDict


def has_context(func):
Expand Down Expand Up @@ -147,60 +146,7 @@ def display(btn1, btn2):
return "No clicks yet"

"""
triggered = getattr(flask.g, "triggered_inputs", [])
triggered = [item["prop_id"] for item in triggered]
grouping = getattr(flask.g, "args_grouping", {})

def update_args_grouping(g):
if isinstance(g, dict) and "id" in g and "property" in g:
str_id = stringify_id(g["id"])
prop_id = f"{str_id}.{g['property']}"

new_values = {
"value": g.get("value"),
"str_id": str_id,
"triggered": prop_id in triggered,
"id": AttributeDict(g["id"])
if isinstance(g["id"], dict)
else g["id"],
}
g.update(new_values)

def recursive_update(g):
if isinstance(g, (tuple, list)):
for i in g:
update_args_grouping(i)
if not isinstance(i.get("id"), dict):
recursive_update(i)
if isinstance(g, dict):
for i in g.values():
update_args_grouping(i)
recursive_update(i)

recursive_update(grouping)

return grouping

# todo not sure whether we need this, but it removes a level of nesting so
# you don't need to use `.value` to get the value.
@property
@has_context
def args_grouping_values(self):
grouping = getattr(flask.g, "args_grouping", {})
grouping = deepcopy(grouping)

def recursive_update(g):
if isinstance(g, (tuple, list)):
for i in g:
recursive_update(i)
if isinstance(g, dict):
for k, v in g.items():
if isinstance(v, dict) and "id" in v:
g[k] = v["value"]
recursive_update(v)

recursive_update(grouping)
return grouping
return getattr(flask.g, "args_grouping", [])

@property
@has_context
Expand Down
16 changes: 15 additions & 1 deletion dash/_grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""
from dash.exceptions import InvalidCallbackReturnValue
from ._utils import AttributeDict
from ._utils import AttributeDict, stringify_id


def flatten_grouping(grouping, schema=None):
Expand Down Expand Up @@ -222,3 +222,17 @@ def validate_grouping(grouping, schema, full_schema=None, path=()):
)
else:
pass


def update_args_group(g, triggered):
if isinstance(g, dict):
str_id = stringify_id(g["id"])
prop_id = f"{str_id}.{g['property']}"

new_values = {
"value": g.get("value"),
"str_id": str_id,
"triggered": prop_id in triggered,
"id": AttributeDict(g["id"]) if isinstance(g["id"], dict) else g["id"],
}
g.update(new_values)
14 changes: 9 additions & 5 deletions dash/dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@
from . import _watch
from . import _get_app

from ._grouping import (
flatten_grouping,
map_grouping,
grouping_len,
)
from ._grouping import flatten_grouping, map_grouping, grouping_len, update_args_group

from . import _pages
from ._pages import (
Expand Down Expand Up @@ -1431,6 +1427,14 @@ def dispatch(self):
inputs_state = inputs + state
inputs_state = convert_to_AttributeDict(inputs_state)

# update args_grouping attributes
for g in inputs_state:
# check for pattern matching: list of inputs or state
if isinstance(g, list):
for pattern_match_g in g:
update_args_group(pattern_match_g, changed_props)
update_args_group(g, changed_props)

args_grouping = map_grouping(
lambda ind: inputs_state[ind], inputs_state_indices
)
Expand Down