Streamlit and Python Modules

Streamlit logo on light background

Streamlit

Streamlit is a nice tool to turn data into viewable web apps rapidly.

Streamlit executes a single Python file and performs reloads and reruns of the Python file on change.

Code duplication

Having one script that contains everything or similar leads to an unmaintainable and flat codebase. Having modules points to a structured codebase and less code duplication.

Furthermore, the reuse of existing code or especially local Python modules would be nice, with the eye on reusing code, e.g., in a service application.

Solution

The main problem with streamlit run some.py is that it is not aware of local Python modules. The import of modules located in some package repository is possible because the Python interpreter knows it via the sys.path variable. A local module structure is not.

The simplest solution, therefore, is to add the path to the top local Python module to the  sys.path variable.

import sys

sys.path.append("some_path")

This adds the some_path value to the running Python environment and allows importing local Python modules located in this path.

Optimized Solution

Of course,  this can be optimized to add the path based on the current file. This works only if the Python file that is executed with Streamlit is part of the project structure. It does not have to be in a module but should be located near to it.

import pathlib
import sys

# This adds the path of the …/src folder
# to the PYTHONPATH variable
sys.path.append(str(pathlib.Path().absolute()).split("/src")[0] + "/src")

import streamlit as st
from mymodule.loader import get_name
...

For this case, the project structure could look like that:

mapViewer # project name
- src
| - interactive # streamlit module
| | - __init__.py
| | - base.py # streamlit app
| - mymodule # project module
|   - __init__.py
|   - loader.py # some service
- test
  - mymodule # tests for project module
Reference to some threads with a similar issue