While trying to add feedback to an AI chatbot, it is unable to store or display the feedback because it keeps auto-refreshing when clicking on any feedback button

def handle_feedback(question_id, feedback_type):
    """
    Handles feedback submission for a specific question and saves it persistently.
    """
    # Save feedback in session state
    if "feedback" not in st.session_state:
        st.session_state.feedback = {}

    # Update feedback in session state
    st.session_state.feedback[question_id] = feedback_type

    # Save feedback to the database
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    session_id = st.session_state.session_id.replace("'", "''")
    user_name_safe = user_name.replace("'", "''")
    feedback_type_safe = feedback_type.replace("'", "''")
    timestamp_safe = timestamp.replace("'", "''")

    feedback_sql = f"""
        INSERT INTO feedback_table (Session_ID, User_Name, Question_ID, Feedback_Type, Timestamp)
        VALUES ('{session_id}', '{user_name_safe}', {question_id}, '{feedback_type_safe}', '{timestamp_safe}')
    """
    session.sql(feedback_sql).collect()


def render_feedback_with_placeholder(question_id, final_response):
    """
    Displays feedback buttons inline with the assistant's response using a placeholder.
    """
    placeholder = st.empty()  # Dynamic placeholder for feedback buttons

    # Display assistant's response with feedback options
    with placeholder.container():
        st.chat_message("assistant").markdown(final_response)

        # Inline feedback buttons
        col1, col2, col3, col4 = st.columns([3, 3, 0.5, 0.5])
        with col3:
            if st.button(":thumbsup:", key=f"like_{question_id}"):
                handle_feedback(question_id, "Good")
                placeholder.empty()  # Clear feedback options after submission
                st.success("Feedback received: Good 👍")
        with col4:
            if st.button(":thumbsdown:", key=f"dislike_{question_id}"):
                handle_feedback(question_id, "Bad")
                placeholder.empty()  # Clear feedback options after submission
                st.success("Feedback received: Bad 👎")


def show_q_a():
    """
    Displays the questions, answers, and feedback options in the chat interface.
    """
    if st.session_state.questions:
        for i in range(len(st.session_state.questions)):
            write_user_message(st.session_state.questions[i])

            # Use dynamic placeholders for each response
            render_feedback_with_placeholder(
                st.session_state.questions[i]['id'],
                st.session_state.answers[i]['answer']
            )

I hope this helps:
It appears that you are experiencing an issue with your Streamlit chatbot application where the feedback is not being stored or displayed correctly due to auto-refreshing when a feedback button is clicked. This is likely because Streamlit reruns the entire script from top to bottom every time a widget is interacted with, which is the default behavior1. Here’s how you can address this using information from the sources:

Using st.form: One solution to this problem is to bundle your input widgets, such as the feedback buttons, within a st.form container1. This prevents Streamlit from automatically rerunning the script every time a button is clicked within the form1. Instead, the script will only rerun when the user clicks the form’s submit button, allowing you to collect all of the feedback before processing it123.

To use st.form, you would wrap the feedback buttons and any associated input widgets within a with st.form(‘feedback_form’): block2. Then, you would create a submit button within the form using st.form_submit_button(‘Submit’)2. The code inside the if statement, such as if submit_button:, will only execute after the submit button has been pressed2.

Session State: To ensure the feedback is stored and displayed correctly, you can use st.session_state4. Session state allows you to store variables between reruns of the Streamlit application, which is essential for maintaining the state of your chatbot and its feedback456.

Initialize a session state variable to hold the feedback data7. For example: if ‘feedback’ not in st.session_state: st.session_state[‘feedback’] = .

When the form is submitted, append the feedback to the session state variable78. For example: st.session_state[‘feedback’].append(feedback_value).

Display the stored feedback using st.write(st.session_state[‘feedback’])9.

Conditional Flow: You may also need to introduce conditional flow to your Streamlit application, which means certain actions will depend on the prior actions or on the state of the widgets3. For instance, you can write a condition that will not process the feedback if no feedback has been provided, or only display feedback if there is data in the session state variable310.

Preventing Auto-Reruns: You can use a form to prevent the Streamlit script from rerunning until the user submits, as described above, or an alternative would be to use a custom component that does not automatically trigger a Streamlit rerun.

You can create a custom component with ReactJS11. This allows for more complex interactions without immediately causing the entire Streamlit application to rerun1213. You can create a rating component using ReactJS and import it as a custom component into your Streamlit application13141516.

To use this method, you would need to send the feedback data from the custom component to the Streamlit backend, and use the setComponentValue function to communicate with the Streamlit backend1718.

Here is an example of how you can implement these concepts using st.form and st.session_state with a simplified feedback mechanism:

import streamlit as st

# Initialize session state for feedback
if 'feedback' not in st.session_state:
    st.session_state['feedback'] = []

# Feedback form
with st.form('feedback_form'):
    st.header('Feedback Form')
    feedback_value = st.radio('Please rate the bot',('Good', 'Okay', 'Bad'))
    submit_button = st.form_submit_button('Submit')

    # Store feedback in session state
    if submit_button:
        st.session_state['feedback'].append(feedback_value)
        st.success("Thank you for your feedback!")

# Display all feedback
st.header('All Feedback')
if st.session_state['feedback']:
    for item in st.session_state['feedback']:
        st.write(item)
else:
    st.write('No feedback yet.')

In this example, the feedback buttons are placed in a form, the feedback is stored in st.session_state, and the display of the feedback is conditional on there being values in the session state variable.

By using forms and session state, you can effectively manage your feedback mechanism in your Streamlit chatbot and avoid the issue of the app auto-refreshing when clicking on the feedback buttons