Multipage Apps are great, but it would hopefully be a big improvement, for a small change to make the labelling more flexible. Either a dictionary that could map filenames to a name on screen or simply allowing “x1_page_1.py” or "pg02_page_2.py.
Problem
The problem is acute when one has the normal structure and want to keep each app self contained, but be able to reference functions from the pages in the homepage.
Our rugby app has lots of analytics but includes a function which pulls data from Snowflake and has relevant SQL queries built in and, say, returns the league scores.
Now on our homepage we want a summary of league scores for all the sports, but we can’t import a function because Python obviously restricts imports from files that have names that begin with numbers.
Suggested Solution
Allow an “x”, “pg”, or “page” before the number which would now make the app file importable by doing:
from pages.x2_rugby import league_scores
Or allow a dictionary which means we could change the labels in the sidebar afterwards.
Work Around
There are two work arounds:
Just use the name but then the structure becomes alphanumeric which is fine in the sports app but clearly is unprofessional looking in a corporate settings
On the naming of pages for native multipage apps: you probably want to give a look at st-pages, a package developed by @blackary which exactly enables you to define pages <> scripts using a config file.
On importing util functions from pages: this is certainly doable as is (edit: not really if they are prefixed with digits, you’re right). But if the page triggers st commands, the imports may be janky and also trigger those UI commands… which is certainly not ideal. What we’ve been doing internally is to separate the “functional” utils to “UI” utils.
So that whenever you’re in a page, say, in 2_rugby.py you can still do:
from data_sources.big_query import big_query_connector
from data_sources.sql_queries import GET_RUGBY_DATA_SQL
conn = big_query_connector()
data = conn.get_dataframe_from_sql(GET_RUGBY_DATA_SQL)
...
Thanks @arnaud, I realised the issue you highlighted with triggering other streamlit commands a while later in particular is was the page config bit of the UI.
I settled on a similar solution to what you say you’ve been doing internally, where there is a separate directory with utility functions - but to keep things clean each app has it’s own paired utilities file - that seems to work nicely enough.
Not sure if it could be possible to develop a way for those UI functions to not be triggered on import? This is probably an edge case, but I work in finance on a team with a mix of quants and non-quant people. As we develop more multi-page apps, the individual pages are being treated a bit like modules, and non-quant people want to mix and match. It’s why we find it cleaner to try and keep apps self contained. Like I say, an edge case in data science, but from a Snowflake user point of view could potentially be very helpful in corporate setting.
Thanks… I’ve been converting from Dash and am loving Streamlit.
Not sure if it could be possible to develop a way for those UI functions to not be triggered on import?
I certainly hear you on this, and more than once had to refactor apps which were nicely self-sufficient just in order to benefit from their logics. I did not love doing so! My initial thought is that this might end up confusing to not have those imports actually write anything, since the code running when importing a module is a standard and expected Python behaviour.
We’re always open for suggestions though, so feel free to file a feature request in our repository!
One quick option for “importing but not running” is to change each of your separate apps so that the actual app code is wrapped in a function, like this:
def main():
... # app code codes here
def other_functions():
....
if __name__ == "__main__":
main()
This means that if you run the app as a script (which is what happens when you click on the page) it will run the main function, but if you just import it, it won’t run the code in your functions.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.