Prevent GUI Elements From Reloading Page

I am facing a challenge where the output of the last work is being cleared when I change a GUI element. If I change the slider or the dropdown list, the work previously done is cleared. I understand the reason. It is because the program is being rerun.

There is only one button “Transcribe Audio” that I want action to take place, otherwise I want to store the state for later use.

I’ve been reading about st.cache_data and st.cache_resources but I haven’t been able to determine how to overcome this issue.

Unrelated…There is one strange thing. When I click on “Transcribe Audio” it turns red upon activation but does not change again until I click somewhere else on the page. Essentially, its stuck looking as though its still clicked. How would I resolve this?

Below is a mock-up of the code I am using, where I’ve substituted “def simulateWorking()” for the actual working code.

import  streamlit as st
import  multiprocessing, random, string, time
from    streamlit import session_state
from    timeit import default_timer as timer

model = None

# Initialize session state
if "selected_model" not in session_state:
    session_state.selected_model = None

if "selected_threadcount" not in session_state:
    session_state.selected_threadcount = 1


def select_model():
    # Create a dropdown for selecting models
    whisperModelList = ["tiny.en", "base.en", "small.en", "medium.en"] # The models downloaded
    intialModel      = whisperModelList.index("base.en")
    selected_model   = st.sidebar.selectbox("Select a Whisper Model", whisperModelList, index=intialModel)
    # Store the selected model in the session state
    session_state.selected_model = selected_model


st.title("Whisper App")
# upload audio file with streamlit
audio_file = st.file_uploader("Upload Media File", type=["wav", "mp3", "m4a", "mp4"])


def numCPUS():
   return multiprocessing.cpu_count()


def setNumThreadsUsed():
    threadCountList = list(range(1, numCPUS())) # create a list in range - 1
    threads = st.sidebar.select_slider(
    'Select the number of threads to utilize',
    options=threadCountList)
    numThreadsToUse = int(threads)
    session_state.selected_threadcount = numThreadsToUse
    debuggingHelp()
    

def generate_random_word(length):
    characters = string.ascii_lowercase  # You can customize the character pool
    return ''.join(random.choice(characters) for _ in range(length))


def simulateWorking():
    simulatedWork  = "**Simulating a new stream of data using fake words for the text processed.**\n\n"
    simulatedWork += ":blue[This process, in reality could take 30 seconds to 30 minutes or longer "
    simulatedWork += "depending on the size of the file, model chosen and number of threads used.]\n\n"
    simulatedWork += ":green[I want to prevent this work being cleared whenever a GUI element is changed]\n\n\n"
    simulatedWork += ":red[**Simulated Output:**]\n\n"

    for i in range(1, 1001):
        random_fake_word = generate_random_word(random.randint(5, 20))
        simulatedWork += (random_fake_word + "  ")

    # In reality, this process could take take a substantial time depending on factors 
    # We'll add some time for realism
    random_sleep_time = random.uniform(5.0, 10.3)
    time.sleep(random_sleep_time)
    return simulatedWork

def transcribeAudio():
    transcrStatus = st.sidebar.empty()              # Single phrase status information
    transcrStatus.markdown( ":gray[Awaiting Media To Transcribe]")
    if st.sidebar.button("Transcribe Audio"):
        if audio_file is not None:
            transcrStatus.markdown( ":blue[Transcribing Audio]")
            start = timer()
            transcription = simulateWorking()
            end = timer()
            elapsed = (end - start)
            st.write(f"Process completed in {elapsed} seconds")
            st.write(transcription.strip())
            transcrStatus.markdown( ":green[Transcription Complete]")
        else:
            st.sidebar.error("Please upload a media file")

    st.sidebar.header("Play Original Audio File")
    st.sidebar.audio(audio_file)


def debuggingHelp():
    # Display the selected model
    st.write(f"You selected the model: {session_state.selected_model}")
    st.write(f"You selected thread count: {session_state.selected_threadcount}")

def main():
    select_model()
    setNumThreadsUsed()
    transcribeAudio()


if __name__ == "__main__":
    main()

I don’t know if this is the correct way but thought I would bump this question up, hoping someone has ideas on how to resolve the issue I’m experiencing.

I was able to get to a solution, which required the using or adding “session_state.transcription” to hold the last work. When the page is reloaded, if the session_state variable exists, it will redisplay that data. Only when I click on “Transcribe Audio” will the work (simulated or real) take place.

I have much to understand about how session_state works but that solved my issue.

Below is the modified function

.

def transcribeAudio():
    transcrStatus = st.sidebar.empty()              # Holds single phrase status information
    transcrStatus.markdown(":gray[Awaiting Media To Transcribe]")

    if audio_file is not None:
        # Check if the "Transcribe Audio" button is pressed.
        if st.sidebar.button("Transcribe Audio"):
            transcrStatus.markdown(":blue[Transcribing Audio]")
            start = timer()
            transcription = simulateWorking()
            end = timer()
            elapsed = round((end - start),3)            # Round to 3 decimal places for consistency
            transcrStatus.markdown(":green[Transcription Complete]")

            finalOutput = f"Process completed in {elapsed} seconds\n\n" + transcription.strip()
            session_state.transcription = finalOutput   # Cache the result in session_state
            st.write(session_state.transcription)       # Display the cached result

        elif "transcription" in session_state:          
            # If there's already a cached transcription, display it.
            st.write(session_state.transcription)

        # Play the uploaded audio file
        st.sidebar.header("Play Original Audio File")
        st.sidebar.audio(audio_file)
    else:
        st.sidebar.error("Please upload a media file")

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.