Skip to content

Commit 8919edf

Browse files
committed
is a Valid Prop
1 parent 9140d3a commit 8919edf

File tree

4 files changed

+87
-13
lines changed

4 files changed

+87
-13
lines changed

dash/_callback.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,13 @@
3737
from . import _validate
3838
from .long_callback.managers import BaseLongCallbackManager
3939
from ._callback_context import context_value
40+
from ._no_update import NoUpdate
4041

4142

4243
def _invoke_callback(func, *args, **kwargs): # used to mark the frame for the debugger
4344
return func(*args, **kwargs) # %% callback invoked %%
4445

4546

46-
class NoUpdate:
47-
def to_plotly_json(self): # pylint: disable=no-self-use
48-
return {"_dash_no_update": "_dash_no_update"}
49-
50-
@staticmethod
51-
def is_no_update(obj):
52-
return isinstance(obj, NoUpdate) or (
53-
isinstance(obj, dict) and obj == {"_dash_no_update": "_dash_no_update"}
54-
)
55-
56-
5747
GLOBAL_CALLBACK_LIST = []
5848
GLOBAL_CALLBACK_MAP = {}
5949
GLOBAL_INLINE_SCRIPTS = []

dash/_no_update.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class NoUpdate:
2+
def to_plotly_json(self): # pylint: disable=no-self-use
3+
return {"_dash_no_update": "_dash_no_update"}
4+
5+
@staticmethod
6+
def is_no_update(obj):
7+
return isinstance(obj, NoUpdate) or (
8+
isinstance(obj, dict) and obj == {"_dash_no_update": "_dash_no_update"}
9+
)

dash/_validate.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import flask
77

88
from ._grouping import grouping_len, map_grouping
9+
from ._no_update import NoUpdate
910
from .development.base_component import Component
1011
from . import exceptions
1112
from ._utils import (
@@ -211,8 +212,10 @@ def validate_multi_return(output_lists, output_values, callback_id):
211212

212213

213214
def fail_callback_output(output_value, output):
214-
valid_children = (str, int, float, type(None), Component)
215-
valid_props = (str, int, float, type(None), tuple, MutableSequence)
215+
valid_children = (str, int, float, type(None), Component, NoUpdate)
216+
valid_props = (str, int, float, type(None), tuple, MutableSequence, NoUpdate)
217+
218+
print("================================")
216219

217220
def _raise_invalid(bad_val, outer_val, path, index=None, toplevel=False):
218221
bad_type = type(bad_val).__name__
@@ -261,6 +264,7 @@ def _valid_prop(val):
261264
return isinstance(val, valid_props)
262265

263266
def _can_serialize(val):
267+
print("checking ability to serialize")
264268
if not (_valid_child(val) or _valid_prop(val)):
265269
return False
266270
try:
@@ -272,6 +276,7 @@ def _can_serialize(val):
272276
def _validate_value(val, index=None):
273277
# val is a Component
274278
if isinstance(val, Component):
279+
print("Is Component")
275280
unserializable_items = []
276281
# pylint: disable=protected-access
277282
for p, j in val._traverse_with_paths():
@@ -332,6 +337,7 @@ def _validate_value(val, index=None):
332337

333338
if isinstance(output_value, list):
334339
for i, val in enumerate(output_value):
340+
print(val)
335341
_validate_value(val, index=i)
336342
else:
337343
_validate_value(output_value)

test.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from types import SimpleNamespace
2+
3+
import dash_bootstrap_components as dbc
4+
import plotly.graph_objects as go
5+
from dash import html, Dash, dcc, Input, Output, no_update, callback, dash_table
6+
7+
8+
app = Dash()
9+
10+
app.layout = html.Div(
11+
[
12+
dbc.Alert(id="alert", is_open=False, duration=4000),
13+
dcc.DatePickerRange(
14+
id="date_picker",
15+
start_date="2021-01-01",
16+
end_date="2021-01-31",
17+
),
18+
dcc.Graph(id="figcontainer"),
19+
dash_table.DataTable(id="table"),
20+
]
21+
)
22+
23+
24+
@callback(
25+
Output(component_id="figcontainer", component_property="figure"),
26+
Output(component_id="table", component_property="data"),
27+
Output(component_id="alert", component_property="is_open"),
28+
Output(component_id="alert", component_property="children"),
29+
Input(component_id="date_picker", component_property="start_date"),
30+
Input(component_id="date_picker", component_property="end_date"),
31+
)
32+
def update_graph(start, end):
33+
df = get_bookings_in_interval(start, end)
34+
# if there is no data, keep previous states and use alert
35+
if type(df) is AssertionError:
36+
return no_update, no_update, True, df
37+
38+
fig = go.Figure()
39+
40+
return (
41+
fig.to_dict(),
42+
{},
43+
no_update,
44+
no_update,
45+
)
46+
47+
mock_response = SimpleNamespace(
48+
status_code=404,
49+
)
50+
51+
# either returns a df or an AssertionError
52+
def get_bookings_in_interval(start, end):
53+
df = None
54+
try:
55+
data = mock_response
56+
assert data.status_code == 200, "Failed to fetch bookings"
57+
parsed_data = dict(data.json())
58+
assert len(parsed_data["bookings"]) > 0, "No items in Response"
59+
# do something
60+
61+
except AssertionError as e:
62+
print(e)
63+
return e
64+
65+
return data
66+
67+
68+
if __name__ == '__main__':
69+
app.run(debug=True)

0 commit comments

Comments
 (0)