Multipage app, directory structure, and imports

Hello

Below is how I imagined to organise the code of a mutlipage app.
In each pages, I will need to “import” from various code in the utils folder.
Relative importing in this way doesn’t seem to work.
I guess this is because the way StreamLit works for multipages.

Would you see how to import for example “birdsDictionary” in the data page?
Woudl you organize the files in another way?

Thanks

Michel

birdsAudio/

├── app.py

├── pages/
│ ├── data.py
│ ├── statistics.py
│ └── listen.py

├── utils/
│ ├── birdsDictionary.py
│ ├── birdsSpectrogram.py
│ └── birdsXenoCanto.py

Hi Michel,

Make sure to include an __ init __.py file in both the pages and utils folders to make them Python packages.

birdsAudio/

├── app.py

├── pages/
│ ├── data.py
│ ├── statistics.py
│ └── listen.py
│ └── init.py
├── utils/
│ ├── birdsDictionary.py
│ ├── birdsSpectrogram.py
│ └── birdsXenoCanto.py
└── init.py

from …utils.birdsDictionary import your_function_or_class

I use absolute.

./utils/birdsDictionary.py

def multiply(a, b):
    return a * b

./pages/data.py

import utils.birdsDictionary as bd

bd.multiply(3, 4)

or

from utils.birdsDictionary import multiply

multiply(3, 4)

I actually have similar structure with what you posted.

You have ./pages/data.py

I prefer to have ./modules/data.py
where:
The former is for frontend with widgets etc and the later is for backend, doing some calculation to be used for the frontend.

Thanks Oscar1

I included the init.py files.
I still get this message:

ImportError: attempted relative import with no known parent package

I think this is so because the way StreamLit work.
If I go to the ‘listen’ page, the listen.py code is executed just like an new app.
With the help of StreamLit, this new app just receives the st.session_state.
I guess StreamLit does that I bit like passing argument, I don’t know exactly how.

But the end result is that this “app” listen.py apparrently does not have have access to code to the “parent package” as -my guess- there is not such parent in this context.

Any idea?
Thanks for you suggestions.

Michel

PS:
Everytime I come back to StreamLit, I fall on such difficulties…
Maybe “simple” is difficult for me !
Like for example adjusting the structure of code to fit the “pages” trick of st.

Hello @maajdl,

Based on your structure, you should be able to use absolute imports if your project’s root directory is correctly recognized as such. If birdsAudio is your project root, and you run your Streamlit app from there, you can import modules like so:

# In your pages/data.py
from utils.birdsDictionary import multiply

# Now you can use the function multiply() as needed
result = multiply(3, 4)

When running your Streamlit app, ensure the current working directory is the root of your project (birdsAudio ).

import os
print("Current Working Directory:", os.getcwd())
# If not correct, change it
os.chdir('/path/to/birdsAudio')

Hope this helps!

Kind Regards,
Sahir Maharaj
Data Scientist | AI Engineer

P.S. Lets connect on LinkedIn!

➤ Want me to build your solution? Lets chat about how I can assist!
➤ Join my Medium community of 30k readers! Sharing my knowledge about data science and AI
➤ Website: https://sahirmaharaj.com
➤ Email: sahir@sahirmaharaj.com
➤ 100+ FREE Power BI Themes: Download Now

3 Likes