plotly / plotly/dash

`jupyter_mode='external'` doesn't work with `use_pages=True`

Open
#3,132 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P2
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

Describe your context
Please provide us your environment, so we can easily reproduce the issue.

  • replace the result of pip list | grep dash below
dash                                     2.18.1
dash_ag_grid                             31.2.0
dash-bootstrap-components                1.6.0
dash-colorscales                         0.0.4
dash-core-components                     2.0.0
dash_cytoscape                           1.0.2
dash_daq                                 0.5.0
dash_html_components                     2.0.0
dash_renderer                            1.9.1
dash-table                               5.0.0
pydash                                   6.0.2

Describe the bug

Using both jupyter_mode='external' and 'use_pages=Truefails on themain` module lookup when ran inside JupyterLab.

File /opt/conda/lib/python3.12/site-packages/dash/dash.py:659, in Dash.init_app(self, app, **kwargs)
    656 self._setup_routes()
    658 _get_app.APP = self
--> 659 self.enable_pages()
    661 self._setup_plotlyjs()

File /opt/conda/lib/python3.12/site-packages/dash/dash.py:2189, in Dash.enable_pages(self)
   2187     return
   2188 if self.pages_folder:
-> 2189     _import_layouts_from_pages(self.config.pages_folder)
   2191 @self.server.before_request
   2192 def router():
   2193     if self._got_first_request["pages"]:

File /opt/conda/lib/python3.12/site-packages/dash/_pages.py:441, in _import_layouts_from_pages(pages_folder)
    438     if "register_page" not in content:
    439         continue
--> 441 module_name = _infer_module_name(page_path)
    442 spec = importlib.util.spec_from_file_location(module_name, page_path)
    443 page_module = importlib.util.module_from_spec(spec)

File /opt/conda/lib/python3.12/site-packages/dash/_pages.py:109, in _infer_module_name(page_path)
    106 parent_module = _path_to_module_name(parent_path)
    108 module_name = f"{parent_module}.{module}"
--> 109 if _module_name_is_package(CONFIG.name):
    110     # Only prefix with CONFIG.name when it's an imported package name
    111     module_name = f"{CONFIG.name}.{module_name}"
    112 return module_name

File /opt/conda/lib/python3.12/site-packages/dash/_pages.py:90, in _module_name_is_package(module_name)
     87 def _module_name_is_package(module_name):
     88     return (
     89         module_name in sys.modules
---> 90         and Path(sys.modules[module_name].__file__).name == "__init__.py"
     91     )

AttributeError: module '__main__' has no attribute '__file__'

Expected behavior

It works similar to how use_pages=True works outside of Jupyter. Not sure how correct the fix is, but I am using this monkey-patch to work around it:

from  dash import _pages
def _hacked_module_name_is_package(module_name):
    return (
            module_name in sys.modules
            and hasattr(sys.modules[module_name], "__file__")
            and Path(sys.modules[module_name].__file__).name == "__init__.py"
    )
_pages._module_name_is_package = _hacked_module_name_is_package

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The failure occurs in dash/_pages.py within _module_name_is_package; start there and reproduce it with jupyter_mode='external' and use_pages=True in JupyterLab. Confirm the module lookup handles main when it has no file, while preserving the existing behavior outside Jupyter.

Written by the indexing model from the issue text.

Assessment

Tech stack
jupyter, python
Domain
web-dev
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.