Streamlit automatically reload imported modules

Hi,

python version: 3.11.5
streamlit version: 1.31.1

I run local streamlit app and have some folder structure like below (simplified):

  • main_page.py
  • utils.py

In main_page.py file I do:

import utils

and in utils.py file I define some functions and do something like:

print("I am here!")

My questions is, whenever I change main_page.py file and save, streamlit tells me source file changed, and I click rerun button, but it seems it reloads utils.py file as I can see it prints “I am here!” again. I understand when I click rerun button Streamlit will rerun main_page.py file but isn’t it not supposed to reload utils.py as it is already loaded? Or does it clear everything and rerun everything?

What is most weird to me is, I have an old app which is working as I expected (update main_page.py, click rerun button, but does not reload utils.py as I do not see printed message) even though I upgrade python and Streamlit to the same version as above. The old app and the new app above are in the same machine but in different project folders and have different virtual environments.

Could anyone please help me on this? Thank you!

2 Likes

Hi @xzhu43,

Thanks for sharing this question!

So Streamlit reruns the entire page upon any interaction on the page or reload. This means that all the modules including utils.py gets re-imported that’s why you’re seeing the I am here! printed on the console each time you reload the page especially if the print statement in the utils file is at the top level. To prevent the printing, you can consider wrapping the print statement in a function and only call it when necessary or use the if __name__ == "__main__": to ensure it only runs when the utils.py is executed as the main program not when it is imported as a module.

1 Like

I’ve weirdly found the opposite to be true @tonykip.

Running streamlit 1.32.2 in python 3.10.13

I have 2 files, trial_app.py and a trial_test.py.
I ran streamlit run trial_app.py.

trial_app.py:

import streamlit as st
from datetime import datetime

print(f'Before Test    {datetime.now()}')
import trial_test as testy
print(f'After Test     {datetime.now()}')
st.write(testy.count)

trial_test.py:

from datetime import datetime
print(f"Test     {datetime.now()}")
count = 0

terminal output:
1 initial run and 2 browser refreshes.

Before Test    2024-03-23 05:05:29.272836
Test           2024-03-23 05:05:29.275250
After Test     2024-03-23 05:05:29.275362
Before Test    2024-03-23 05:05:29.789673
After Test     2024-03-23 05:05:29.789854
Before Test    2024-03-23 05:05:34.898263
After Test     2024-03-23 05:05:34.898341
1 Like

Update: I tested by updating count = 1 and now a browser refresh executes trial_test.py once more.
From this I can conclude that a re-import only happens when a change is recognised in said module. How can I force execute it everytime?

1 Like

You can’t. The proper mechanism to force execution of code in another module is a function call, not importing.

2 Likes

Hi,

Thanks for sharing your test! This is what I expected to see as I only want to update the UI defined in trial_app.py to make it looks better without reloading trial_test.py which does some calculation. And I managed to do this in my old app, but it failed to do this in the new app. So I have always believed that there is some simple trick or some streamlit config to switch between 2 behavior but I just do not know.

1 Like

So weird why we have the exactly opposite situation. My case in my new app is the change is in trial_app.py file but it reloads trial_test.py again.

1 Like

Thanks for you suggestion. The function in utils.py needs to run to make the app work. My issue is not I do not want it to run. It is actually working well when the app launches in production. The issue is when I am doing the development on the UI main_page.py, I do not want utils.py to run again and again as it takes time to wait for it to finish.

1 Like

Then call the function once and store the result somewhere, then use the stored result.

Hi @ruthran-c, did you find a solution to your issue? I’m running into the same thing where an imported library doesn’t reload if I make changes in that file. Only the main file triggers a reload.

I’m 100% sure this is not how it was working previously. My modules would always trigger a reload.

1 Like

@N3Cr0,
My imported custom module always reloads, 'if ’ a code change is introduced to said module’s .py file. I use Streamlit, version 1.32.2.

Note: I desired a module reload with each app refresh even if the module’s code didn’t change, but I couldn’t achieve it. So, I modified my source code to align with Streamlit’s current operation.
Hope this was helpful!

Aah ok. I misunderstood that.

I’ve just posted in another thread what I found about my own problem though. The module you want to watch for changes can’t be in a parent or sibling directory from what I can see. It only works if it is at or below the main app file directory.

Hopefully this saves someone the 2 hours I just spent on this problem…