Auto trigger to click on st.form_submit_button once timer elapses

Hey Team ,

I’m working on PKT quiz app using Streamlit , the functionality is like once 10min timer s reached st.form_submit_button should be clicked automatically and user quiz response should be recorded. I had tried with sesssion_state , but it dint work. Can
someone please advice.?

Hi @Rakshitha,

Welcome to our community; we’re thrilled to have you! :hugs:

Do you have a link to the repo?

Thanks,
Charly

Thanks! for the quick response.

But sorry I ll not b able t share repo directly as its internal client use case. Sharing you the code snippet, hope it helps. Kindly revert for any more details! Thanks!

Expectation : Either use should be able t click on form submit button before 10min or once time elapses it should be clicked automatically.

with st.form(‘Take quiz’):

                        pkt.create_faiss_vectordb(option=False)
                        quiz_df, quiz_file_name = 
                        pkt.generate_quiz_for_weakcat(quiz_cat, username)
                        print("--quiz_df-",quiz_df)
                        print("--------quiz_file_name Take Quiz-----",quiz_file_name)
                        #latest_file_path = ut.get_latest_file(quiz_quest_ans_path)
                        st.session_state['quiz_df'] = quiz_file_name
                        # st.write("---quiz_string---",quiz_file_name)
                        # quiz_df = ut.save_quiz_to_csv(quiz_string)

                        for index, row in quiz_df.iterrows():
                            # st.subheader(f"Question {index + 1}: {row['Question']}")
                            question = row['Question']
                            st.write(
                                f"<p style='font-size: 16px; font-weight: bold; margin-bottom: 
                                -40px;'> {question}</p>",
                                unsafe_allow_html=True)

                            options = row['Options']
                            answer = row['Answer']
                            correct = row['Answer']

                            correct_answer.append(correct)
                            selected_option = st.radio(" ", options, index=None, key='Q_' + 
                                                           str(index + 1))

                            chosen_answer.append(selected_option)


                        st.session_state['chosen_list'] = chosen_answer
                        st.session_state['correct_list'] = correct_answer

                        print("-----chosen_answer1-------", (chosen_answer))
                        print("----correct_answer1--------", (correct_answer))

                       st.form_submit_button("Submit",on_click=save_responses)

Hi @Rakshitha :wave:

It sounds like you need an automatic submission of a Streamlit form after a timer expires, is that correct?

If so, Streamlit does not directly support triggering events like form submissions based on a timer. However, you could use an alternative approach with the streamlit Python package and a Python timer. You can use st.session_state to control when to show the form and when to process the submission based on the elapsed time.

I hope that makes sense. Let me know if you need any guidance in building this! :slight_smile:

Best,
Charly

Yeah I did try st.session_state , but its not working as session_state flag is unable to capture user response . Few other approaches which I hav tried and dint work include javascript trigger , Threads and Selenium tool.

Is the code you shared the full code?

Its part of the code , but here s where I wanna implement the logic t auto click on st.form_submit_button(“Submit”,on_click=save_responses) when timer is elapsed.

Could you please share it here, if possible?

It might be more challenging + potentially less accurate to come up with a solution without having access to the full code. :slight_smile:

Thanks,
Charly

Okay sharing you the code here :

def update_progress(progress_bar, message, duration):
start_time = time.time()
while time.time() - start_time < duration:
progress = (time.time() - start_time) / duration
progress_bar.progress(progress)
time.sleep(0.1)

progress_bar.empty()
message.empty()
st.session_state.timer = True

with (tabs[1]):

                if ready_to_take:
                    st.session_state.ready_to_take = True

                    # if st.session_state.ready_to_take:
                    # Create a placeholder for the user's quiz responses
                    correct_answer = []
                    chosen_answer = []

                    msg = "You have a 10-minute window to complete the quiz!"
                    progress_bar = st.progress(0)
                    message = st.empty()
                    message.warning(msg)

                    # Run the quiz section in the main thread
                    with st.form('Take quiz'):

                        pkt.create_faiss_vectordb(option=False)
                        quiz_df, quiz_file_name = pkt.generate_quiz_for_weakcat(quiz_cat, username)
                        print("--quiz_df-",quiz_df)
                        print("--------quiz_file_name Take Quiz-----",quiz_file_name)
                        #latest_file_path = ut.get_latest_file(quiz_quest_ans_path)
                        st.session_state['quiz_df'] = quiz_file_name
                        # st.write("---quiz_string---",quiz_file_name)
                        # quiz_df = ut.save_quiz_to_csv(quiz_string)

                        for index, row in quiz_df.iterrows():
                            # st.subheader(f"Question {index + 1}: {row['Question']}")
                            question = row['Question']
                            st.write(
                                f"<p style='font-size: 16px; font-weight: bold; margin-bottom: -40px;'> {question}</p>",
                                unsafe_allow_html=True)

                            options = row['Options']
                            answer = row['Answer']
                            correct = row['Answer']

                            correct_answer.append(correct)
                            selected_option = st.radio(" ", options, index=None, key='Q_' + str(index + 1))

                            chosen_answer.append(selected_option)


                        st.session_state['chosen_list'] = chosen_answer
                        st.session_state['correct_list'] = correct_answer

                        print("-----chosen_answer1-------", (chosen_answer))
                        print("----correct_answer1--------", (correct_answer))

                        #submit_button = st.form_submit_button("Submit",on_click=save_responses)


                        # Start the progress bar and timer
                        update_progress(progress_bar, timer_message, 10)  

                        if st.session_state.timer:
                            submit_button = True
                            print("-----Auto CLick----")

Thanks for sending, @Rakshitha! :pray:

Based on our code, I’ve tried several app variations trying to create a timer and leveraging session state. I haven’t come to anything satisfying enough yet, but I’ll keep trying and will keep you posted.

Best,
Charly

Thanks for your effort! Please revert if you find any solution!

Good Day!