Save the results of a button click to a csv in S3

Summary

I want the user to be able to click a button, and save the selection to a csv in S3.

Steps to reproduce

Code snippet:

# option 1 (two individual buttons)
if st.sidebar.button("Yep."):
    feedback = '1'
if st.sidebar.button("Nope."):
    feedback = '0'

df = pd.DataFrame({'feedback': feedback}, index=[0])
with s3.open(f"{path}.csv", 'wb') as f:
    df.to_csv(f)

# option 2 (radio buttons)
feedback = st.sidebar.radio(
    "Am I right?",
    ('Yes', 'No'),
    horizontal=True
)
# Save feedback to s3
if st.sidebar.button("Submit feedback."):
    # TODO figure out a slicker way to do this
    df = pd.DataFrame({'feedback': feedback}, index=[0])
    with s3.open(f"{path}.csv", 'wb') as f:
        df.to_csv(f)

Expected behavior:

I would expect a csv to be saved to s3.

Actual behavior:
No csv is saved. I’m also saving an image at the same time, and that is saving properly.

Debug info

  • Streamlit version: 1.14.1
  • Python version: 3.9
  • Using Conda? PipEnv? PyEnv? Pex? Pip

Requirements file

Links

It must be something s3-specific. Your option 2 works for me if I save the file to a local filesystem.

It’s a bug in the file path to s3. :smile: Oops. Thanks for pointing me in the right direction!

Just kidding. There was a problem with the link, but the problem persists in the app. I’m able to save the csv successfully locally (just running the save step in a script), but not in the app.

I tried adding a st.sidebar.write() after the save step, and it doesn’t print, so I think there’s something not firing properly?

Not sure what you mean by “not in the app”. When I say your option 2 works I mean it works as a Streamlit app. By “local filesystem” I actually mean the current working directory as seen by the app, just using built-in open instead of s3.open. It works that way both in my computer and deployed to Streamlit Cloud.

st.sidebar.write() not printing anything is expected behavoir, totally unrelated to saving files in S3.

Sorry, I should have been more clear. I included st.sidebar.write(f"Feedback ({feedback}) saved to {path}.csv"), which I would expect would print the input from the selected button and the filepath, but does not.

What I was saying is that I am able to execute the exact same code to save the dataframe as a csv in S3 (including the same path and credentials) in a python script, but when I check the deployed app, the image is saved but not the csv.

Not to mention, if I use the radio button option (#2), and I select “No”, the button disappears before I can even select submit. So, I’m pretty confident I’ve still got this set up incorrectly.

It does for me and I can’t see how that can possibly happen with your code unless an exception is raised before that line of code is execcuted. Maybe there is an error message that you can’t see unless you scroll down to the bottom of the page? Or the code is wrapped in a try clause that is eating exceptions? What is there in the logs?

What if you write something right after creating the dataframe? Or right before it?

Again, I can’t replicate that and I can’t see how the code you posted as option 2 can possibly do it. Are you sure you are running the same code?

My code is here (linked to the relevant part).

The deployed app where you can see the strange button behavior is here. I understand you will of course not be able to see whether the file saves properly, but at least it might help with the button issue.

There are no try clauses, and no errors showing on the page (I scrolled down), and nothing in the logs besides the prediction being run.

The trick was to use st.session_state, like described in this thread.

At least, that solved the file saving issue. I just went with the two-buttons option to get around the radio button problem.

Thanks for your help!

1 Like