import streamlit as st
import langchain
# from dotenv import load_dotenv
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings, HuggingFaceInstructEmbeddings
from langchain.vectorstores import FAISS
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from htmlTemplates import css, bot_template, user_template
import openai
import os
from PyPDF2 import PdfReader
from docx import Document
import pinecone
import time
from langchain.vectorstores import Pinecone
import toml

def main():
    # load_dotenv()
    st.set_page_config(page_title="Chat with multiple files", page_icon=":books:")
    st.write(css, unsafe_allow_html=True)
    openai.api_key = st.secrets["OPENAI_API_KEY"]
    pinecone_api_key = st.secrets["PINECONE_API_KEY"]
    pinecone_env = st.secrets["PINECONE_ENV"]
    index_name = st.secrets["PINECONE_INDEX_NAME"]

    if "conversation" not in st.session_state:
        st.session_state.conversation = None
    if "chat_history" not in st.session_state:
        st.session_state.chat_history = None

    st.header("Chat with multiple files :books:")

    if "messages" not in st.session_state:
        st.session_state.messages = []

    for message in st.session_state.messages:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

    user_question = st.chat_input("What is up?")
    if user_question:
        if st.session_state.conversation is None:
            st.error("Please provide data and click 'Process' before asking questions.")
        else:
            response = st.session_state.conversation({'question': user_question})
            st.session_state.chat_history = response['chat_history']

            for i, message in enumerate(st.session_state.chat_history):
                if i % 2 == 0:
                    st.write(user_template.replace("{{MSG}}", message.content), unsafe_allow_html=True)
                else:
                    st.write(bot_template.replace("{{MSG}}", message.content), unsafe_allow_html=True)

    selected_tab = st.sidebar.radio("Navigation", options=["Files", "Text"], horizontal=True, label_visibility="collapsed")

    if selected_tab == "Files":
        st.sidebar.subheader("Upload and Process Files")
        uploaded_files = st.sidebar.file_uploader("Upload your files here and click on 'Process'", accept_multiple_files=True)

        if uploaded_files:
            if st.sidebar.button("Process"):
                with st.spinner("Processing"):

                    # initialize pinecone
                    pinecone.init(api_key=pinecone_api_key, environment=pinecone_env)

                    if index_name in pinecone.list_indexes():
                        pinecone.delete_index(index_name)

                    # we create a new index
                    pinecone.create_index(name=index_name, metric='cosine',
                                          dimension=1536)  # 1536 dim of text-embedding-ada-002

                    # wait for index to be initialized
                    while not pinecone.describe_index(index_name).status['ready']:
                        time.sleep(1)

                    st.session_state.conversation = None
                    st.session_state.chat_history = None

                    text = ""
                    for file in uploaded_files:
                        file_extension = os.path.splitext(file.name)[1].lower()

                        if file_extension == '.pdf':
                            pdf_reader = PdfReader(file)
                            for page in pdf_reader.pages:
                                text += page.extract_text()
                        elif file_extension == '.txt':
                            text += file.read().decode("utf-8")
                        elif file_extension == '.docx':
                            doc = Document(file)
                            for paragraph in doc.paragraphs:
                                text += paragraph.text + "\n"
                        else:
                            st.warning('We only support PDF, TXT and DOCX files')
                            st.stop()

                    text_splitter = CharacterTextSplitter(separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len)
                    text_chunks = text_splitter.split_text(text)

                    embeddings = OpenAIEmbeddings()
                    # vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
                    vectorstore = Pinecone.from_texts(text_chunks, embeddings, index_name=index_name)
                    llm = ChatOpenAI(model_name = 'gpt-4')
                    memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
                    conversation_chain = ConversationalRetrievalChain.from_llm(llm=llm, retriever=vectorstore.as_retriever(), memory=memory)
                    st.session_state.conversation = conversation_chain

    elif selected_tab == "Text":
        st.sidebar.subheader("Enter Text")
        user_text = st.sidebar.text_area("Enter your text here", "")

        if st.sidebar.button("Process Text"):
            if not user_text.strip():
                st.warning("Please enter some text before processing.")
            else:
                # Process the user's entered text
                if user_text:
                    # total_character_count = len(user_text)
                    # if total_character_count > 400000:
                    #     st.warning("Total input data should not exceed 400,000 characters.")
                    #     st.stop()

                    st.session_state.conversation = None
                    st.session_state.chat_history = None

                    # initialize pinecone
                    pinecone.init(api_key=pinecone_api_key, environment=pinecone_env)

                    if index_name in pinecone.list_indexes():
                        pinecone.delete_index(index_name)

                    # we create a new index
                    pinecone.create_index(name=index_name, metric='cosine',
                                          dimension=1536)  # 1536 dim of text-embedding-ada-002

                    # wait for index to be initialized
                    while not pinecone.describe_index(index_name).status['ready']:
                        time.sleep(1)

                    st.session_state.conversation = None
                    st.session_state.chat_history = None

                    text_splitter = CharacterTextSplitter(separator="\n", chunk_size=1000, chunk_overlap=200, length_function=len)
                    text_chunks = text_splitter.split_text(user_text)

                    embeddings = OpenAIEmbeddings()
                    vectorstore = Pinecone.from_texts(text_chunks, embeddings, index_name=index_name)

                    llm = ChatOpenAI(model_name = 'gpt-4')
                    memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
                    conversation_chain = ConversationalRetrievalChain.from_llm(llm=llm, retriever=vectorstore.as_retriever(), memory=memory)
                    st.session_state.conversation = conversation_chain

if __name__ == '__main__':
    main()

langchain.text_splitter.CharacterTextSplitter langchain.vectorstores.Pinecone.from_texts langchain.memory.ConversationBufferMemory langchain.chat_models.ChatOpenAI langchain.embeddings.OpenAIEmbeddings
[((669, 747), 'streamlit.set_page_config', 'st.set_page_config', ([], {'page_title': '"""Chat with multiple files"""', 'page_icon': '""":books:"""'}), "(page_title='Chat with multiple files', page_icon=':books:')\n", (687, 747), True, 'import streamlit as st\n'), ((752, 789), 'streamlit.write', 'st.write', (['css'], {'unsafe_allow_html': '(True)'}), '(css, unsafe_allow_html=True)\n', (760, 789), True, 'import streamlit as st\n'), ((1181, 1226), 'streamlit.header', 'st.header', (['"""Chat with multiple files :books:"""'], {}), "('Chat with multiple files :books:')\n", (1190, 1226), True, 'import streamlit as st\n'), ((1469, 1497), 'streamlit.chat_input', 'st.chat_input', (['"""What is up?"""'], {}), "('What is up?')\n", (1482, 1497), True, 'import streamlit as st\n'), ((2177, 2285), 'streamlit.sidebar.radio', 'st.sidebar.radio', (['"""Navigation"""'], {'options': "['Files', 'Text']", 'horizontal': '(True)', 'label_visibility': '"""collapsed"""'}), "('Navigation', options=['Files', 'Text'], horizontal=True,\n    label_visibility='collapsed')\n", (2193, 2285), True, 'import streamlit as st\n'), ((2323, 2371), 'streamlit.sidebar.subheader', 'st.sidebar.subheader', (['"""Upload and Process Files"""'], {}), "('Upload and Process Files')\n", (2343, 2371), True, 'import streamlit as st\n'), ((2397, 2502), 'streamlit.sidebar.file_uploader', 'st.sidebar.file_uploader', (['"""Upload your files here and click on \'Process\'"""'], {'accept_multiple_files': '(True)'}), '("Upload your files here and click on \'Process\'",\n    accept_multiple_files=True)\n', (2421, 2502), True, 'import streamlit as st\n'), ((1370, 1402), 'streamlit.chat_message', 'st.chat_message', (["message['role']"], {}), "(message['role'])\n", (1385, 1402), True, 'import streamlit as st\n'), ((1416, 1447), 'streamlit.markdown', 'st.markdown', (["message['content']"], {}), "(message['content'])\n", (1427, 1447), True, 'import streamlit as st\n'), ((1582, 1658), 'streamlit.error', 'st.error', (['"""Please provide data and click \'Process\' before asking questions."""'], {}), '("Please provide data and click \'Process\' before asking questions.")\n', (1590, 1658), True, 'import streamlit as st\n'), ((1696, 1754), 'streamlit.session_state.conversation', 'st.session_state.conversation', (["{'question': user_question}"], {}), "({'question': user_question})\n", (1725, 1754), True, 'import streamlit as st\n'), ((2542, 2570), 'streamlit.sidebar.button', 'st.sidebar.button', (['"""Process"""'], {}), "('Process')\n", (2559, 2570), True, 'import streamlit as st\n'), ((5125, 5159), 'streamlit.sidebar.subheader', 'st.sidebar.subheader', (['"""Enter Text"""'], {}), "('Enter Text')\n", (5145, 5159), True, 'import streamlit as st\n'), ((5180, 5228), 'streamlit.sidebar.text_area', 'st.sidebar.text_area', (['"""Enter your text here"""', '""""""'], {}), "('Enter your text here', '')\n", (5200, 5228), True, 'import streamlit as st\n'), ((5241, 5274), 'streamlit.sidebar.button', 'st.sidebar.button', (['"""Process Text"""'], {}), "('Process Text')\n", (5258, 5274), True, 'import streamlit as st\n'), ((2593, 2617), 'streamlit.spinner', 'st.spinner', (['"""Processing"""'], {}), "('Processing')\n", (2603, 2617), True, 'import streamlit as st\n'), ((2682, 2747), 'pinecone.init', 'pinecone.init', ([], {'api_key': 'pinecone_api_key', 'environment': 'pinecone_env'}), '(api_key=pinecone_api_key, environment=pinecone_env)\n', (2695, 2747), False, 'import pinecone\n'), ((2934, 3005), 'pinecone.create_index', 'pinecone.create_index', ([], {'name': 'index_name', 'metric': '"""cosine"""', 'dimension': '(1536)'}), "(name=index_name, metric='cosine', dimension=1536)\n", (2955, 3005), False, 'import pinecone\n'), ((4300, 4398), 'langchain.text_splitter.CharacterTextSplitter', 'CharacterTextSplitter', ([], {'separator': '"""\n"""', 'chunk_size': '(1000)', 'chunk_overlap': '(200)', 'length_function': 'len'}), "(separator='\\n', chunk_size=1000, chunk_overlap=200,\n    length_function=len)\n", (4321, 4398), False, 'from langchain.text_splitter import CharacterTextSplitter\n'), ((4494, 4512), 'langchain.embeddings.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {}), '()\n', (4510, 4512), False, 'from langchain.embeddings import OpenAIEmbeddings, HuggingFaceInstructEmbeddings\n'), ((4641, 4708), 'langchain.vectorstores.Pinecone.from_texts', 'Pinecone.from_texts', (['text_chunks', 'embeddings'], {'index_name': 'index_name'}), '(text_chunks, embeddings, index_name=index_name)\n', (4660, 4708), False, 'from langchain.vectorstores import Pinecone\n'), ((4735, 4765), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model_name': '"""gpt-4"""'}), "(model_name='gpt-4')\n", (4745, 4765), False, 'from langchain.chat_models import ChatOpenAI\n'), ((4797, 4870), 'langchain.memory.ConversationBufferMemory', 'ConversationBufferMemory', ([], {'memory_key': '"""chat_history"""', 'return_messages': '(True)'}), "(memory_key='chat_history', return_messages=True)\n", (4821, 4870), False, 'from langchain.memory import ConversationBufferMemory\n'), ((5330, 5385), 'streamlit.warning', 'st.warning', (['"""Please enter some text before processing."""'], {}), "('Please enter some text before processing.')\n", (5340, 5385), True, 'import streamlit as st\n'), ((1957, 2006), 'htmlTemplates.user_template.replace', 'user_template.replace', (['"""{{MSG}}"""', 'message.content'], {}), "('{{MSG}}', message.content)\n", (1978, 2006), False, 'from htmlTemplates import css, bot_template, user_template\n'), ((2083, 2131), 'htmlTemplates.bot_template.replace', 'bot_template.replace', (['"""{{MSG}}"""', 'message.content'], {}), "('{{MSG}}', message.content)\n", (2103, 2131), False, 'from htmlTemplates import css, bot_template, user_template\n'), ((2786, 2809), 'pinecone.list_indexes', 'pinecone.list_indexes', ([], {}), '()\n', (2807, 2809), False, 'import pinecone\n'), ((2835, 2868), 'pinecone.delete_index', 'pinecone.delete_index', (['index_name'], {}), '(index_name)\n', (2856, 2868), False, 'import pinecone\n'), ((3249, 3262), 'time.sleep', 'time.sleep', (['(1)'], {}), '(1)\n', (3259, 3262), False, 'import time\n'), ((5911, 5976), 'pinecone.init', 'pinecone.init', ([], {'api_key': 'pinecone_api_key', 'environment': 'pinecone_env'}), '(api_key=pinecone_api_key, environment=pinecone_env)\n', (5924, 5976), False, 'import pinecone\n'), ((6163, 6234), 'pinecone.create_index', 'pinecone.create_index', ([], {'name': 'index_name', 'metric': '"""cosine"""', 'dimension': '(1536)'}), "(name=index_name, metric='cosine', dimension=1536)\n", (6184, 6234), False, 'import pinecone\n'), ((6644, 6742), 'langchain.text_splitter.CharacterTextSplitter', 'CharacterTextSplitter', ([], {'separator': '"""\n"""', 'chunk_size': '(1000)', 'chunk_overlap': '(200)', 'length_function': 'len'}), "(separator='\\n', chunk_size=1000, chunk_overlap=200,\n    length_function=len)\n", (6665, 6742), False, 'from langchain.text_splitter import CharacterTextSplitter\n'), ((6843, 6861), 'langchain.embeddings.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {}), '()\n', (6859, 6861), False, 'from langchain.embeddings import OpenAIEmbeddings, HuggingFaceInstructEmbeddings\n'), ((6896, 6963), 'langchain.vectorstores.Pinecone.from_texts', 'Pinecone.from_texts', (['text_chunks', 'embeddings'], {'index_name': 'index_name'}), '(text_chunks, embeddings, index_name=index_name)\n', (6915, 6963), False, 'from langchain.vectorstores import Pinecone\n'), ((6991, 7021), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model_name': '"""gpt-4"""'}), "(model_name='gpt-4')\n", (7001, 7021), False, 'from langchain.chat_models import ChatOpenAI\n'), ((7053, 7126), 'langchain.memory.ConversationBufferMemory', 'ConversationBufferMemory', ([], {'memory_key': '"""chat_history"""', 'return_messages': '(True)'}), "(memory_key='chat_history', return_messages=True)\n", (7077, 7126), False, 'from langchain.memory import ConversationBufferMemory\n'), ((3632, 3647), 'PyPDF2.PdfReader', 'PdfReader', (['file'], {}), '(file)\n', (3641, 3647), False, 'from PyPDF2 import PdfReader\n'), ((6015, 6038), 'pinecone.list_indexes', 'pinecone.list_indexes', ([], {}), '()\n', (6036, 6038), False, 'import pinecone\n'), ((6064, 6097), 'pinecone.delete_index', 'pinecone.delete_index', (['index_name'], {}), '(index_name)\n', (6085, 6097), False, 'import pinecone\n'), ((6478, 6491), 'time.sleep', 'time.sleep', (['(1)'], {}), '(1)\n', (6488, 6491), False, 'import time\n'), ((3172, 3207), 'pinecone.describe_index', 'pinecone.describe_index', (['index_name'], {}), '(index_name)\n', (3195, 3207), False, 'import pinecone\n'), ((3498, 3525), 'os.path.splitext', 'os.path.splitext', (['file.name'], {}), '(file.name)\n', (3514, 3525), False, 'import os\n'), ((3975, 3989), 'docx.Document', 'Document', (['file'], {}), '(file)\n', (3983, 3989), False, 'from docx import Document\n'), ((4171, 4224), 'streamlit.warning', 'st.warning', (['"""We only support PDF, TXT and DOCX files"""'], {}), "('We only support PDF, TXT and DOCX files')\n", (4181, 4224), True, 'import streamlit as st\n'), ((4253, 4262), 'streamlit.stop', 'st.stop', ([], {}), '()\n', (4260, 4262), True, 'import streamlit as st\n'), ((6401, 6436), 'pinecone.describe_index', 'pinecone.describe_index', (['index_name'], {}), '(index_name)\n', (6424, 6436), False, 'import pinecone\n')]