How to update the uploaded file using file_uploader

i want to read file by using file_uploader than i have a function that allow user to update the data in the uploaded file than it save the file on the desktop after that it reopen the saved file and display the updated data.

What i want is to override the uploaded file in order to display the new dataframe once the user click on button replace

In the image above i want to replace the file book2.xlsx by the updated file after the user change cat6 to cat1

code:

import pandas as pd
import streamlit as st 

def main():
    
   
    Activities = ["EDA","Plot","About"]
    choice = st.sidebar.selectbox("Select Activity",Activities)
    
    radio = st.sidebar.radio(label="", options=["Single File", "Multiple Files"])
    
    df = pd.DataFrame()
    pt1=re.compile(".csv$")
    pt2=re.compile(".xlsx$")

    if radio == "Multiple Files":
        data = st.sidebar.file_uploader('Multiple Excel files', type=["csv","xlsx","xls"], accept_multiple_files=True)
    elif radio=="Single File":    
        data = st.sidebar.file_uploader("Upload Dataset",type=["csv","xlsx","xls"])

    if data is not None:
        #EDA Page
        if choice =="EDA":
            st.subheader("Exploratiry Data Analysis")
    
            if radio=="Single File":
                if data.type =="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
                    df=pd.read_excel(data)



#show replace     

            if st.checkbox("replace"):

                mydf = st.dataframe(df)

                columns = st.selectbox("Select  column", df.columns)

                old_values = st.multiselect("Current Values",list(df[columns].unique()),list(df[columns].unique()))

                with st.form(key='my_form'):

                    col1,col2 = st.beta_columns(2)

                    st_input = st.number_input if is_numeric_dtype(df[columns]) else st.text_input

                    with col1:

                        old_val = st_input("old value")

                    with col2:

                        new_val = st_input("new value")

                    if st.form_submit_button("Replace"):

                        df[columns]=df[columns].replace(old_val,new_val)

                        st.success("{} replace with {} successfully ".format(old_val,new_val))


                        excel = df.to_excel(r"F:\book2.xlsx", index = False, header=True,encoding="utf-8")

                        df =pd.read_excel(r"F:\book2.xlsx")       

                        mydf.add_rows(df)

Hi @leb_dev -

In general, this isn’t a good workflow for an app, as the browser cannot directly guarantee access to the underlying file.

When the user uploads a file through file_uploader, the data are copied to the Streamlit backend via the browser, and contained in a BytesIO buffer in Python memory. Assuming the user can change the values as they desire, this is still changing the data in RAM, not in the file.

You could have a step where the user can click a download button, but you cannot ensure that they are going to overwrite their original file, as the browser will always ask the user what name and location they want to save the file to. So while the user could decide to overwrite their own file, the app cannot force this. Additionally, the desire to immediately re-show the results in the Streamlit app could cause a race condition, where the values shown in the app are stale because Streamlit could read the file while the file is being saved.

From your code, I would have the user work in the spreadsheet directly, or consider having a different workflow that can directly access the spreadsheet (i.e. not using file_uploader).

Best,
Randy

my goal is to update the dataframe once the user replace the values and click on the replace button… For that i did thought that if i save the updated file and than read it again in this way i will display the updated dataframe. Is there any best practice for this workflow?

The streamlit-aggrid component has a similar workflow to what you describe, where the user can change the values in a dataframe:

so in the streamlit i can not allow the user to update the dataframe on the web app and in the background this update will override the original dataframe ?

Sorry if i am asking many questions but i really liked streamlit and i am willing to use it as primary web app

1 Like