Reusable dash components in nested Python packages

Hi folks,

We’re working on an application which aims to dynamically load multiple dashboards into a single Python process. In order to avoid conflicts, we put each dashboard into its own Python package. This works, but it falls apart the moment we add in a reusable component.

In this particular case, we tried to use video_engine from https://github.com/SkyRatInd/Video-Engine-Dash, and bundle it within the dashboard which makes use of it. This didn’t work out of the box, because video_engine assumes it sits in the root import namespace, and hard-codes this into the load_components call, and in the _js_dist, which makes dash fail with a traceback that looks like this:

Exception on /dash/mobile_net/17/ [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.6/site-packages/dash/dash.py", line 529, in index
    scripts = self._generate_scripts_html()
  File "/usr/local/lib/python3.6/site-packages/dash/dash.py", line 446, in _generate_scripts_html
    dev_bundles=self._dev_tools.serve_dev_bundles
  File "/usr/local/lib/python3.6/site-packages/dash/dash.py", line 398, in _collect_and_register_resources
    namespace=resource['namespace']
  File "/usr/local/lib/python3.6/site-packages/dash/dash.py", line 370, in _relative_url_path
    os.path.dirname(sys.modules[namespace].__file__),
KeyError: 'video_engine'

I tried to fix this by changing the hard-coded references to video_engine in the component to __name__, but now, from the point that this dashboard gets loaded, all further attempts to load any dashboard from the same process fail (even ones that worked before) with this:

Exception on /dash/mobile_net/17/_dash-component-suites/dash_renderer/react-dom@15.4.2.min.js [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
    return original_handler(e)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python3.6/site-packages/dash/dash.py", line 497, in serve_component_suites
    .format(package_name, list(self.registered_paths.keys())))
dash.exceptions.DependencyException: Error loading dependency.
"dash_renderer" is not a registered library.
Registered libraries are: []

Is it possible to use components living in nested Python packages, or do we just need to deal with them sitting in the root namespace?