Handle feedback change in fragment

Hello, I’m building an AI chatbot with multiple pages. The user can add feedback to each answer and I’m using st.fragment to avoid page rerun (when user click on the thumb). It stores messages and feedback on a sqlite database.
I have an issue: when I click on another page and then go back to chatbot page, streamlit rerun the page but the last feedback are not up-to-date.
While, refreshing the page it works fine!

Here the code:

# fragment allows to reder only the messages without reloading the whole page
@st.fragment
def render_message(message):
    with st.chat_message(message["role"], avatar=logo_path if message["role"] == "assistant" else None):
        st.markdown(escape_markdown(message["content"]))
        
        # Feedback only for assistant messages
        if message["role"] == "assistant":
            message_id = message.get("id")

            if message_id is not None:
                fb_key = f"feedback_{message_id}"

            if fb_key not in st.session_state:
                st.session_state[fb_key] = message.get("feedback", None)

            feedback_val = st.feedback(
                "thumbs",
                key=fb_key,
                disabled=st.session_state.get(fb_key) is not None, # Disable if feedback already given
                on_change=on_feedback_change,
                args=(message_id, fb_key)
            )

# -------------------------------
# Display chat messages
# -------------------------------
for message in user_chat:
    render_message(message)

def get_messages(username):
    with sqlite3.connect(DB_FILE) as conn:
        cursor = conn.execute(
            'SELECT id, role, content, feedback FROM messages WHERE username = ? ORDER BY timestamp ASC',
            (username,)
        )
        return [{"id": row[0], "role": row[1], "content": row[2], "feedback": row[3]} for row in cursor.fetchall()] 

def update_feedback(message_id, feedback):
    print(f"Updating feedback for message ID {message_id} to {feedback}")
    with sqlite3.connect(DB_FILE) as conn:
        conn.execute(
            'UPDATE messages SET feedback = ? WHERE id = ?',
            (feedback, message_id)
        )
        conn.commit()

def on_feedback_change(message_id, fb_key):
    feedback = st.session_state[fb_key]
    update_feedback(message_id, feedback)

def get_feedback(message_id):
    with sqlite3.connect(DB_FILE) as conn:
        cursor = conn.execute(
            'SELECT feedback FROM messages WHERE id = ?',
            (message_id,)
        )
        row = cursor.fetchone()
        return row[0] if row else None

thanks a lot,
Gianluca

Hi @Gianluca1,

Can you please edit your post so that all your code is in a code block? You can put a line above and below it with ```

That will allow others to actually read and run your code properly.

Hello @blackary, done thanks!