Tuesday, 20 June 2023

Streamlit input to chat via button does not persist

I have a streamlit app that takes a file and builds a chat bot on top of it.

There are two ways to upload files. From folder ("Use Data from folder" button) and from the "drag and drop" box.  The option with the "drag and drop" box works fine, but for the option with the "Use Data from folder" button, chat appears once, but when I put a question in chat and click "send", chat disappears for some reason.

Here code for buttons from main app:

use_example_file = st.sidebar.button("Use Data from folder")
uploaded_file = utils.handle_upload(["pdf", "txt", "csv"], use_example_file)

if uploaded_file:
    [do something]

Where handle_upload is the following function:

@staticmethod
def handle_upload(file_types, use_example_file):
    """
    Handles and display uploaded_file
    :param file_types: List of accepted file types, e.g., ["csv", "pdf", "txt"]
    """
    
    if use_example_file is False:
        uploaded_file = st.sidebar.file_uploader("upload", type=file_types, label_visibility="collapsed")
    else: 
        # uploaded_file = use_example_file
        # use_example_file = st.sidebar.button(use_example_file)
        uploaded_file = open("example.csv", "rb")

    if uploaded_file is not None:

        def show_csv_file(uploaded_file):
            file_container = st.expander("Your CSV file :")
            uploaded_file.seek(0)
            shows = pd.read_csv(uploaded_file)
            file_container.write(shows)

        def show_pdf_file(uploaded_file):
            file_container = st.expander("Your PDF file :")
            with pdfplumber.open(uploaded_file) as pdf:
                pdf_text = ""
                for page in pdf.pages:
                    pdf_text += page.extract_text() + "\n\n"
            file_container.write(pdf_text)
        
        def show_txt_file(uploaded_file):
            file_container = st.expander("Your TXT file:")
            uploaded_file.seek(0)
            content = uploaded_file.read().decode("utf-8")
            file_container.write(content)
        
        def get_file_extension(uploaded_file):
            return os.path.splitext(uploaded_file)[1].lower()
        
        file_extension = get_file_extension(uploaded_file.name)

        # Show the contents of the file based on its extension
        #if file_extension == ".csv" :
        #    show_csv_file(uploaded_file)
        if file_extension== ".pdf" : 
            show_pdf_file(uploaded_file)
        elif file_extension== ".txt" : 
            show_txt_file(uploaded_file)

    else:
        st.session_state["reset_chat"] = True

    #print(uploaded_file)
    return uploaded_file

Full code for app is:

import os
import streamlit as st
from io import StringIO
import re
import sys
from modules.history import ChatHistory
from modules.layout import Layout
from modules.utils import Utilities
from modules.sidebar import Sidebar

import traceback

# load .env
from dotenv import load_dotenv
load_dotenv()

#To be able to update the changes made to modules in localhost (press r)
def reload_module(module_name):
    import importlib
    import sys
    if module_name in sys.modules:
        importlib.reload(sys.modules[module_name])
    return sys.modules[module_name]

history_module = reload_module('modules.history')
layout_module = reload_module('modules.layout')
utils_module = reload_module('modules.utils')
sidebar_module = reload_module('modules.sidebar')

ChatHistory = history_module.ChatHistory
Layout = layout_module.Layout
Utilities = utils_module.Utilities
Sidebar = sidebar_module.Sidebar

st.set_page_config(layout="wide", page_icon=".", page_title="AI Assistant")

# Instantiate the main components
layout, sidebar, utils = Layout(), Sidebar(), Utilities()

layout.show_header("PDF, TXT, CSV")

user_api_key = utils.load_api_key()
# user_api_key = '.'

if not user_api_key:
    layout.show_api_key_missing()
else:
    os.environ["OPENAI_API_KEY"] = user_api_key
    os.environ["OPENAI_API_TYPE"] = "azure"
    os.environ["OPENAI_API_BASE"] = 'https://testingchat.openai.azure.com/'
    os.environ["OPENAI_API_VERSION"] = "2023-05-15"
    # os.environ["OPENAI_API_DEPLOYMENT_NAME"] = 'Petes-Test'

    # uploaded_file = utils.handle_upload(["pdf", "txt", "csv"])
    use_example_file = st.sidebar.button("Use Data from folder")
    # st.write(f"use_example_file: {use_example_file}")
    uploaded_file = utils.handle_upload(["pdf", "txt", "csv"], use_example_file)
    # if use_example_file:
    #         uploaded_file = open("example.csv", "rb")

    # st.write(uploaded_file)

    if uploaded_file:

        # Configure the sidebar
        sidebar.show_options()
        sidebar.about()

        # Initialize chat history
        history = ChatHistory()

        chatbot = utils.setup_chatbot(
            uploaded_file, st.session_state["model"], st.session_state["temperature"]
        )
        st.session_state["chatbot"] = chatbot

        if st.session_state["ready"]:
            # Create containers for chat responses and user prompts
            response_container, prompt_container = st.container(), st.container()

            with prompt_container:
                # Display the prompt form
                is_ready, user_input = layout.prompt_form()

                # Initialize the chat history
                history.initialize(uploaded_file)

                # Reset the chat history if button clicked
                if st.session_state["reset_chat"]:
                    history.reset(uploaded_file)

                if is_ready:
                    # Update the chat history and display the chat messages
                    history.append("user", user_input)

                    old_stdout = sys.stdout
                    sys.stdout = captured_output = StringIO()

                    output = st.session_state["chatbot"].conversational_chat(user_input)

                    sys.stdout = old_stdout

                    history.append("assistant", output)

                    # Clean up the agent's thoughts to remove unwanted characters
                    thoughts = captured_output.getvalue()
                    cleaned_thoughts = re.sub(r'\x1b\[[0-9;]*[a-zA-Z]', '', thoughts)
                    cleaned_thoughts = re.sub(r'\[1m>', '', cleaned_thoughts)

                    # Display the agent's thoughts
                    with st.expander("Display the agent's thoughts"):
                        st.write(cleaned_thoughts)

            history.generate_messages(response_container)


from Streamlit input to chat via button does not persist

No comments:

Post a Comment