Skip to content

Commit e580ff0

Browse files
authored
Merge pull request #2771 from plotly/fix/namespace-package-map
Dynamic loading: map namespace to package name in case they differ.
2 parents 330a2c4 + ba17593 commit e580ff0

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

dash/_callback.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ def insert_callback(
261261
"output": output,
262262
"raw_inputs": inputs,
263263
"manager": manager,
264+
"allow_dynamic_callbacks": dynamic_creator,
264265
}
265266
callback_list.append(callback_spec)
266267

dash/dash.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,10 @@ def serve_reload_hash(self):
806806
)
807807

808808
def serve_dist(self):
809-
libraries = flask.request.get_json()
809+
libraries = [
810+
ComponentRegistry.namespace_to_package.get(lib, lib)
811+
for lib in flask.request.get_json()
812+
]
810813
dists = []
811814
for dist_type in ("_js_dist", "_css_dist"):
812815
resources = ComponentRegistry.get_resources(dist_type, libraries)
@@ -1282,6 +1285,8 @@ def long_callback(
12821285
def dispatch(self):
12831286
body = flask.request.get_json()
12841287

1288+
nlibs = len(ComponentRegistry.registry)
1289+
12851290
g = AttributeDict({})
12861291

12871292
g.inputs_list = inputs = body.get( # pylint: disable=assigning-non-slot
@@ -1311,6 +1316,7 @@ def dispatch(self):
13111316

13121317
try:
13131318
cb = self.callback_map[output]
1319+
_allow_dynamic = cb.get("allow_dynamic_callbacks", False)
13141320
func = cb["callback"]
13151321
g.background_callback_manager = (
13161322
cb.get("manager") or self._background_manager
@@ -1362,6 +1368,7 @@ def dispatch(self):
13621368
except KeyError as missing_callback_function:
13631369
msg = f"Callback function not found for output '{output}', perhaps you forgot to prepend the '@'?"
13641370
raise KeyError(msg) from missing_callback_function
1371+
13651372
ctx = copy_context()
13661373
# noinspection PyArgumentList
13671374
response.set_data(
@@ -1375,6 +1382,12 @@ def dispatch(self):
13751382
)
13761383
)
13771384
)
1385+
1386+
if not _allow_dynamic and nlibs != len(ComponentRegistry.registry):
1387+
print(
1388+
"Warning: component library imported during callback, move to top-level for full support.",
1389+
file=sys.stderr,
1390+
)
13781391
return response
13791392

13801393
def _setup_server(self):

dash/development/base_component.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class ComponentRegistry:
1818

1919
registry = OrderedSet()
2020
children_props = collections.defaultdict(dict)
21+
namespace_to_package = {}
2122

2223
@classmethod
2324
def get_resources(cls, resource_name, includes=None):
@@ -44,10 +45,12 @@ def __new__(mcs, name, bases, attributes):
4445
# as it doesn't have the namespace.
4546
return component
4647

48+
_namespace = attributes.get("_namespace", module)
49+
ComponentRegistry.namespace_to_package[_namespace] = module
4750
ComponentRegistry.registry.add(module)
48-
ComponentRegistry.children_props[attributes.get("_namespace", module)][
49-
name
50-
] = attributes.get("_children_props")
51+
ComponentRegistry.children_props[_namespace][name] = attributes.get(
52+
"_children_props"
53+
)
5154

5255
return component
5356

0 commit comments

Comments
 (0)