`jupyter_mode='external'` doesn't work with `use_pages=True`
Nobody has claimed this yet.
- 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 dashbelow
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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