Watching custom folders

Say I have a folder structure like this

custom_py_package1
- __init.py__
- ...
custom_py_package2
- __init.py__
- ...
app
- streamlit_app1.py
- ...

I want to run apps from my app folder which uses custom_py_package1 and custom_py_package2. Now that all works fine but I’d like my apps to detect changes in my custom packages without restarting the app. How do I achieve this?

1 Like

Hi @mr-bjerre, thanks for your question. By default Streamlit only watches modules within the directory of the main script file. In your case, that would be app.

Nevertheless, Streamlit also watches modules in the PYTHONPATH. So setting the PYTHONPATH to include the modules you want to track should help you.

See this PR: https://github.com/streamlit/streamlit/pull/845

Best,
Matteo

@monchier is this currently working? I’m modifying a function foo inside $ROOT/mypackage/func.py
and my streamlit app file is in $ROOT/utils/streamlit_main.py
When doing

export PYTHONPATH = $ROOT/mypackage/func.py
streamlit run $ROOT/utils/streamlit_main.py

If I modify function foo inside func.py, streamlit doesn’t detect the changes in the main app.

I have a similar problem. I have two folders , lets call them β€œmy_folder1” and β€œmy_folder2”

My Dockerfile has

ENV PYTHONPATH=./
ENTRYPOINT ["streamlit", "run"]
CMD ["./my_folder2/main.py"]

but the app does not watch for changes in ./my_folder1/ :confused:

It seems that the issue was not importing directly the function, but rather importing the module.
What I’m currently doing is the following:

import inspect                                                                                                                                                                                                     
import os 
import streamlit as st                                                                                                                                                                                             
from streamlit import session_state as st_session                                                                                                                                                                  
from mypackage.module import foo, bar                                                                                                                                                                                
                                                                                                                                                                                                                 
def monitor_func(*args):                                                                                                                                                                                          
    if 'monitor' not in st_session:                                                                                                                                                                                
        st_session['monitor'] = set()                                                                                                                                                                              
    for func in args:                                                                                                                                                                                              
        path = inspect.getsourcefile(func)                                                                                                                                                                         
        st_session['monitor'].add(os.path.dirname(path))                                                                                                                                                           
    os.environ['PYTHONPATH'] = ':'.join(list(st_session['monitor']))                                                                                                                                               

monitor_func(foo, bar)                                                                                                                                                                                             
foo()                                                                                                                                                                                                              
bar()

Then changes in foo and bar are detected in the main app.

But if I do:

import inspect                                                                                                                                                                                                     
import os 
import streamlit as st                                                                                                                                                                                             
from streamlit import session_state as st_session                                                                                                                                                                  
from mypackage import module                                                                                                                                                                                
                                                                                                                                                                                                                 
def monitor_func(*args):                                                                                                                                                                                          
    if 'monitor' not in st_session:                                                                                                                                                                                
        st_session['monitor'] = set()                                                                                                                                                                              
    for func in args:                                                                                                                                                                                              
        path = inspect.getsourcefile(func)                                                                                                                                                                         
        st_session['monitor'].add(os.path.dirname(path))                                                                                                                                                           
    os.environ['PYTHONPATH'] = ':'.join(list(st_session['monitor']))                                                                                                                                               

monitor_func(module.foo, module.bar)                                                                                                                                                                                             
module.foo()                                                                                                                                                                                                              
module.bar()

Then changes are not detected

1 Like