Importing modules in pages

I’ve created a multi-page app. Obviously different pages will be mostly different, but I do want to apply same page formatting (company logo, copyright message, etc.).

I created a separate module with these formatting, and tried to import in the page scripts under pages directory, and the main script. It failed for scripts under pages, main one works.

  1. When I place it outside pages, I can not import it as it complains about relative import without parent package.
  • As soon as I make pages as a package with a __init__ script, that gets treated as a lage which is not what I want.
  1. When I place it inside pages, it gets treated as a page automatically. So once again, this doesn’t help me.

So, I want to know how to import custom codes (modules or packages, but not packages that are installed) in the scripts under pages. Also, it’d be good to know if there’s a way to tell streamlit to ignore a script under pages as an app page.

I also came up against this when turning a single script into a multipage app. The solution for me was to modify the PYTHONPATH to include the top-level directory before doing the imports within the *.py files within pages. Doesn’t look particularly nice, but it is what it is given the limitations of relative imports.

For a structure like this:

.
├── mymodule
│   └── __init__.py
├── pages
│   ├── 01_foo.py
│   └── 02_bar.py
└── streamlit_app.py

Say I want to import the __prog__ definition from mymodule/__init__.py from within pages/01_foo.py:

from pathlib import Path
import sys

import streamlit as st

sys.path.append(str(Path(__file__).resolve().parent.parent))
from mymodule import __prog__
1 Like

Very interesting approach. As you said, it does look bad, but it’s solves the problem. I changed it to insert at 0th position instead of appending it at end, but that’s just my own preference I guess, it works exactly as you shared as well.

But I hope there’ll be a native streamlit solution soon. :crossed_fingers:

Can also just set the PYTHONPATH in the environment, in preference to messing around with sys.path:

PYTHONPATH=. streamlit run path/to/my/app.py

… and put this into a simple start script etc.