from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores.faiss import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI
from PyPDF2 import PdfReader
import langchain
import requests
import io
import docx
import json

langchain.verbose = False
def get_text_from_files(file_list):
    text = ""
    for file in file_list:
        ext_name = file.split(".")[-1].lower()
        response = requests.get(file)
        if ext_name == "pdf":   
            ##load pdf from url          
            pdf_reader = PdfReader(io.BytesIO(response.content))  
            # pdf_reader = PdfReader(file)
            for page in pdf_reader.pages:
                text += page.extract_text()
        elif ext_name == "txt":
            #load txt from url
            text = response.content.decode("utf-8")
        elif ext_name == "docx":
            #load docx from url
            docx_file = io.BytesIO(response.content)
            doc = docx.Document(docx_file)
            for para in doc.paragraphs:
                text += para.text
    return text

def get_text_chunks(text):
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=800,
        chunk_overlap=200,
        length_function=len,
    )
    chunks = text_splitter.split_text(text)
    return chunks

##get keys from .env file
import os
# from dotenv import load_dotenv
# load_dotenv()
openai_api_key = os.getenv("OPENAI_API_KEY")

def get_vectorstore(text_chunks):
    embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
    vector_store = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
    return vector_store

def get_conversation_chain(vectorstore):
    llm = ChatOpenAI(openai_api_key=openai_api_key,
                     temperature=0.25)
    memory = ConversationBufferMemory(memory_key='chat_history', return_messages=True)
    conversation_chain = ConversationalRetrievalChain.from_llm(
        llm=llm,
        retriever=vectorstore.as_retriever(),
        memory=memory,
    )
    return conversation_chain

def process(text_info,files_or_urls,questions):
    conversation=None

    if text_info:   
        raw_text = str(text_info)
    else:
        raw_text = ""

    ## allow if only text is input
    if files_or_urls:
        raw_text = raw_text+ "\n" + str(get_text_from_files(files_or_urls))
    text_chunks = get_text_chunks(raw_text)
    vectorstore = get_vectorstore(text_chunks)
    conversation = get_conversation_chain(vectorstore)
    for user_question in questions:
        response = conversation({'question': user_question})
    chat_history = response['chat_history']
    data={}
    for i, message in enumerate(chat_history):
        if i % 2 == 0:
            key=message.content
        else:
            data[key]=message.content
    return data

    
  


def lambda_handler(event, context):
    # TODO implement
    result=process(text_info=event['text_info'],files_or_urls=event['files_or_urls'],questions=event['questions'])
    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }


langchain.text_splitter.CharacterTextSplitter langchain.memory.ConversationBufferMemory langchain.chat_models.ChatOpenAI langchain.vectorstores.faiss.FAISS.from_texts langchain.embeddings.OpenAIEmbeddings
[((1580, 1607), 'os.getenv', 'os.getenv', (['"""OPENAI_API_KEY"""'], {}), "('OPENAI_API_KEY')\n", (1589, 1607), False, 'import os\n'), ((1282, 1379), 'langchain.text_splitter.CharacterTextSplitter', 'CharacterTextSplitter', ([], {'separator': '"""\n"""', 'chunk_size': '(800)', 'chunk_overlap': '(200)', 'length_function': 'len'}), "(separator='\\n', chunk_size=800, chunk_overlap=200,\n    length_function=len)\n", (1303, 1379), False, 'from langchain.text_splitter import CharacterTextSplitter\n'), ((1660, 1707), 'langchain.embeddings.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {'openai_api_key': 'openai_api_key'}), '(openai_api_key=openai_api_key)\n', (1676, 1707), False, 'from langchain.embeddings import OpenAIEmbeddings\n'), ((1727, 1784), 'langchain.vectorstores.faiss.FAISS.from_texts', 'FAISS.from_texts', ([], {'texts': 'text_chunks', 'embedding': 'embeddings'}), '(texts=text_chunks, embedding=embeddings)\n', (1743, 1784), False, 'from langchain.vectorstores.faiss import FAISS\n'), ((1861, 1920), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'openai_api_key': 'openai_api_key', 'temperature': '(0.25)'}), '(openai_api_key=openai_api_key, temperature=0.25)\n', (1871, 1920), False, 'from langchain.chat_models import ChatOpenAI\n'), ((1955, 2028), 'langchain.memory.ConversationBufferMemory', 'ConversationBufferMemory', ([], {'memory_key': '"""chat_history"""', 'return_messages': '(True)'}), "(memory_key='chat_history', return_messages=True)\n", (1979, 2028), False, 'from langchain.memory import ConversationBufferMemory\n'), ((578, 596), 'requests.get', 'requests.get', (['file'], {}), '(file)\n', (590, 596), False, 'import requests\n'), ((3216, 3234), 'json.dumps', 'json.dumps', (['result'], {}), '(result)\n', (3226, 3234), False, 'import json\n'), ((707, 735), 'io.BytesIO', 'io.BytesIO', (['response.content'], {}), '(response.content)\n', (717, 735), False, 'import io\n'), ((1072, 1100), 'io.BytesIO', 'io.BytesIO', (['response.content'], {}), '(response.content)\n', (1082, 1100), False, 'import io\n'), ((1119, 1143), 'docx.Document', 'docx.Document', (['docx_file'], {}), '(docx_file)\n', (1132, 1143), False, 'import docx\n')]