Code that is equivalent to pressing 'R' for refresh/rerun?

I have an app that uses a paginator to display a series of audios, 5 per page. I listen and label audio, then press the save button and that causes the data to be saved and the audio to be added to a list of completed audios using SessionState.

The problem is that after pressing save, the completed audio is still displayed. This is because main calls the paginator so the whole app needs to be rerun every time, to do this I press β€˜r’. If I manually call the paginator from inside the save button, I get duplicate key errors. Is there a way I can tell the app to start over and run main after the save button is pressed (this is fine performance wise since I’m using caching)?

How can I do the equivalent of pressing the β€˜r’ key from inside streamlit code? Thank you.

1 Like

Hi @MadeUpMasters -

Not sure I understand the issue here, could you post a code snippet or a link to your repo?

Best,
Randy

Sure, here is a simplified version of the code.

def main():
    # loads all the details of the audio like filepath, speaker...etc and caches it
    items = load_items()
    state = SessionState.get(
        completed_speakers=completed_speakers, rerun=False, prepro_steps=0
    )
    # reduce to only items from speakers who haven't been graded yet
    non_completed_items = [i for i in items if i[0] not in state.completed_speakers]
    audio_paginator(
        non_completed_items,
        state,
        items_per_page=6,
    )

def audio_paginator(items, state, items_per_page):
   # standard paginator adopted from fruit example in above gist
    for i, item in paginator("Select an audio page", items, items_per_page=items_per_page):
        speaker, path, label = item
        display_native_audio_form(i, items, speaker, path, state, start_label=label)

def display_native_audio_form(i, items, speaker, path, state, start_label):
    st.text(f"Speaker: {speaker}")
    st.audio(str(path), format="audio/wav", start_time=0)
    st.text(f"Audio Label: {start_label}")
    quality = st.radio("Speaker Quality", options=OPTIONS_QUALITY, index=0, key=i)
    if st.button("Save Speaker", key=i):
        state.completed_speakers.append(speaker)
        add_speaker_to_json(speaker, quality)

The issue is that, since I am using this audio paginator (paginator code here) to iterate over my items and make a form for each of them, I need to rerun main each time I save a result (so that the speaker that has been graded no longer appears in the data). I can press r to do this each time, but it would be easier if I could put code to rerun the app from scratch at the end of the buttons action event. Right now I press β€œsave speaker”, wait for rerender to finish, press β€˜r’ and wait for reload to finish. Not a huge deal and I may be able to refactor out the paginator so I don’t have this issue (only show one speaker at a time), but I am curious how to solve this problem in general. Thank you.

Good question, having a similar issue.
Something like. st.rerun() would be great.

I admit I haven’t read all of the thread :upside_down_face: but if you are looking for a programmatic rerun, it was added as experimental in version 0.69 as st.experimental_rerun.

This should help you control the app flow without having to rely on pressing R

Cheers,
Fanilo

1 Like