Search code examples
pythonbuttonstreamlit

creating a selectbox/file_uploader with a button in streamlit app


The page must start with a single button:

enter image description here

And when I click "Upload File", a file_uploader must appear. enter image description here

It works until here. However, If I click "Browse files" and upload a 2kb CSV file, file_uplader disappears from the page, and "You selected the file:" is not printed.

Here is my code:

import streamlit as st

if st.button('Upload File'):
    uploaded_file = st.file_uploader("Choose a file")
    print(uploaded_file)
    if uploaded_file is not None:
        # print(uploaded_file)
        st.write("You selected the file:", uploaded_file.name)

First print returns "None" in the terminal. If I try the same code for a selectbox, the same thing is happening. It shows options in the menu, but if I select one, the dropdown menu disappears.

How can I create a file_uploader with a button, and use the file_uploader without any problem in the streamlit app?


Solution

  • Buttons do not retain state. They return True on the page load resulting from their click and then go back to False for subsequent page loads. If you nest something inside of a button, as soon as you interact with any other widget, then everything nested inside that button goes away.

    Here's a blog post with some explanations and options: https://blog.streamlit.io/10-most-common-explanations-on-the-streamlit-forum/#1-buttons-aren%E2%80%99t-stateful

    I'm not sure what you are wanting to accomplish with the button click to show the uploader, but one way you can do this is:

    import streamlit as st
    
    if 'clicked' not in st.session_state:
        st.session_state.clicked = False
    
    def set_clicked():
        st.session_state.clicked = True
    
    st.button('Upload File', on_click=set_clicked)
    if st.session_state.clicked:
        uploaded_file = st.file_uploader("Choose a file")
        print(uploaded_file)
        if uploaded_file is not None:
            # print(uploaded_file)
            st.write("You selected the file:", uploaded_file.name)
    

    In this example, you use some data stored in session state to retain the info that the button was clicked. You can change the function so that it toggles instead, if you wanted the Upload button to work more like an on/off switch.

    def set_clicked():
        st.session_state.clicked = not(st.session_state.clicked)