When trying out the new Dash Pages, I found that I cannot access modules outside of the pages folder from inside the pages folder via relative imports. Let’s say that I have the following folder structure:
UI/
common_data/
styles.py
pages/
other_page/
other_page.py
home.py
app.py
run_my_app.py
Where common_data/styles.py
contains some style definitions,
# run_my_app.py
from UI.app import app
app.run(debug=True)
and the other files contain a multi-page app similar to the Dash example.
The problem
From pages/home.py
or pages/other_page/other_page.py
it is not possible to import common_data/styles.py
via relative imports.
For example:
# pages/home.py
from ..common_data import styles
results in the error
ImportError: attempted relative import beyond top-level package
A print statement above the relative import reveals why this is the case:
# pages/home.py
print(f'home: {__name__ = }')
from ..common_data import styles
will print
>>> home: __name__ = 'pages.home'
Clearly showing that the scope of the modules/scripts within the pages
folder is restricted to the pages folder.
Note: the same thing happens for
pages/other_page/other_page.py
whereprint(other_page: {__name__ = }')
prints
>>> other_page: __name__ = 'pages.other_page.other_page'
How can I pass the scope of app.py
to the individual pages so that I can access content outside of the pages folder via relative imports? I think this happens due to how the Dash page registry searches and loads the contents of the pages
folder.
Absolute imports
I know that it is possible to access external content using absolute imports, i.e. replacing the relative import with
from UI.common_data import styles
makes the dashboard work. However due to portability considerations of my dashboard code between different computers, it is much more convenient to use relative imports.