from flask import Flask, request
from flask_restful import Resource, Api, reqparse, abort
from werkzeug.utils import secure_filename

########################################################################
import tempfile
import os
from langchain.document_loaders import DirectoryLoader, PyMuPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI
from langchain.vectorstores import Pinecone
import pinecone
from templates.qa_prompt import QA_PROMPT
from templates.condense_prompt import CONDENSE_PROMPT

from dotenv import load_dotenv
load_dotenv()
openai_api_key_env = os.environ.get('OPENAI_API_KEY')
pinecone_api_key_env = os.environ.get('PINECONE_API_KEY')
pinecone_environment_env = os.environ.get('PINECONE_ENVIRONMENT')
pinecone_index_env = os.environ.get('PINECONE_INDEX')

pinecone_namespace = 'testing-pdf-2389203901'

app = Flask("L-ChatBot")
UPLOAD_FOLDER = 'documents'
ALLOWED_EXTENSIONS = {'pdf'}


app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
api = Api(app)

parser = reqparse.RequestParser()


def get_answer(message, temperature=0.7, source_amount=4):
    chat_history = []
    embeddings = OpenAIEmbeddings(
        model='text-embedding-ada-002', openai_api_key=openai_api_key_env)

    pinecone.init(api_key=pinecone_api_key_env,
                  environment=pinecone_environment_env)
    vectorstore = Pinecone.from_existing_index(
        index_name=pinecone_index_env, embedding=embeddings, text_key='text', namespace=pinecone_namespace)
    model = ChatOpenAI(model_name='gpt-3.5-turbo', temperature=temperature,
                       openai_api_key=openai_api_key_env, streaming=False)  # max temperature is 2 least is 0
    retriever = vectorstore.as_retriever(search_kwargs={
        "k": source_amount},  qa_template=QA_PROMPT, question_generator_template=CONDENSE_PROMPT)  # 9 is the max sources
    qa = ConversationalRetrievalChain.from_llm(
        llm=model, retriever=retriever, return_source_documents=True)
    result = qa({"question": message, "chat_history": chat_history})
    print("Cevap Geldi")
    answer = result["answer"]
    source_documents = result['source_documents']

    parsed_documents = []
    for doc in source_documents:
        parsed_doc = {
            "page_content": doc.page_content,
            "metadata": {
                "author": doc.metadata.get("author", ""),
                "creationDate": doc.metadata.get("creationDate", ""),
                "creator": doc.metadata.get("creator", ""),
                "file_path": doc.metadata.get("file_path", ""),
                "format": doc.metadata.get("format", ""),
                "keywords": doc.metadata.get("keywords", ""),
                "modDate": doc.metadata.get("modDate", ""),
                "page_number": doc.metadata.get("page_number", 0),
                "producer": doc.metadata.get("producer", ""),
                "source": doc.metadata.get("source", ""),
                "subject": doc.metadata.get("subject", ""),
                "title": doc.metadata.get("title", ""),
                "total_pages": doc.metadata.get("total_pages", 0),
                "trapped": doc.metadata.get("trapped", "")
            }
        }
        parsed_documents.append(parsed_doc)

    # Display the response in the Streamlit app
    return {
        "answer": answer,
        "meta": parsed_documents
    }
########################################################################


class Ask(Resource):

    def get(self):
        question = request.args.get("question")
        temp = request.args.get("temp", default=0.7)
        sources = request.args.get("sources", default=4)
        return get_answer(question, float(temp), int(sources))


class Ingest(Resource):

    def allowed_file(self, filename):
        return '.' in filename and \
            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

    def post(self):
        # Get Text type fields
        if 'file' not in request.files:
            return 'No file part'

        file = request.files.get("file")
        if file and self.allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            loader = DirectoryLoader(
                app.config['UPLOAD_FOLDER'], glob="**/*.pdf", loader_cls=PyMuPDFLoader)
            documents = loader.load()
            text_splitter = RecursiveCharacterTextSplitter(
                chunk_size=1000, chunk_overlap=100)
            documents = text_splitter.split_documents(documents)

            pinecone.init(
                api_key=pinecone_api_key_env,  # find at app.pinecone.io
                environment=pinecone_environment_env  # next to api key in console
            )
            embeddings = OpenAIEmbeddings(
                model='text-embedding-ada-002', openai_api_key=openai_api_key_env)
            Pinecone.from_documents(
                documents, embeddings, index_name=pinecone_index_env, namespace=pinecone_namespace)
            return 'File uploaded and ingested successfully'


api.add_resource(Ask, "/ask")
api.add_resource(Ingest, "/ingest")

if __name__ == "__main__":
    app.run()

langchain.document_loaders.DirectoryLoader langchain.text_splitter.RecursiveCharacterTextSplitter langchain.chains.ConversationalRetrievalChain.from_llm langchain.vectorstores.Pinecone.from_documents langchain.chat_models.ChatOpenAI langchain.vectorstores.Pinecone.from_existing_index langchain.embeddings.openai.OpenAIEmbeddings
[((718, 731), 'dotenv.load_dotenv', 'load_dotenv', ([], {}), '()\n', (729, 731), False, 'from dotenv import load_dotenv\n'), ((753, 785), 'os.environ.get', 'os.environ.get', (['"""OPENAI_API_KEY"""'], {}), "('OPENAI_API_KEY')\n", (767, 785), False, 'import os\n'), ((809, 843), 'os.environ.get', 'os.environ.get', (['"""PINECONE_API_KEY"""'], {}), "('PINECONE_API_KEY')\n", (823, 843), False, 'import os\n'), ((871, 909), 'os.environ.get', 'os.environ.get', (['"""PINECONE_ENVIRONMENT"""'], {}), "('PINECONE_ENVIRONMENT')\n", (885, 909), False, 'import os\n'), ((931, 963), 'os.environ.get', 'os.environ.get', (['"""PINECONE_INDEX"""'], {}), "('PINECONE_INDEX')\n", (945, 963), False, 'import os\n'), ((1018, 1036), 'flask.Flask', 'Flask', (['"""L-ChatBot"""'], {}), "('L-ChatBot')\n", (1023, 1036), False, 'from flask import Flask, request\n'), ((1146, 1154), 'flask_restful.Api', 'Api', (['app'], {}), '(app)\n', (1149, 1154), False, 'from flask_restful import Resource, Api, reqparse, abort\n'), ((1165, 1189), 'flask_restful.reqparse.RequestParser', 'reqparse.RequestParser', ([], {}), '()\n', (1187, 1189), False, 'from flask_restful import Resource, Api, reqparse, abort\n'), ((1290, 1378), 'langchain.embeddings.openai.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {'model': '"""text-embedding-ada-002"""', 'openai_api_key': 'openai_api_key_env'}), "(model='text-embedding-ada-002', openai_api_key=\n    openai_api_key_env)\n", (1306, 1378), False, 'from langchain.embeddings.openai import OpenAIEmbeddings\n'), ((1388, 1474), 'pinecone.init', 'pinecone.init', ([], {'api_key': 'pinecone_api_key_env', 'environment': 'pinecone_environment_env'}), '(api_key=pinecone_api_key_env, environment=\n    pinecone_environment_env)\n', (1401, 1474), False, 'import pinecone\n'), ((1506, 1639), 'langchain.vectorstores.Pinecone.from_existing_index', 'Pinecone.from_existing_index', ([], {'index_name': 'pinecone_index_env', 'embedding': 'embeddings', 'text_key': '"""text"""', 'namespace': 'pinecone_namespace'}), "(index_name=pinecone_index_env, embedding=\n    embeddings, text_key='text', namespace=pinecone_namespace)\n", (1534, 1639), False, 'from langchain.vectorstores import Pinecone\n'), ((1656, 1775), 'langchain.chat_models.ChatOpenAI', 'ChatOpenAI', ([], {'model_name': '"""gpt-3.5-turbo"""', 'temperature': 'temperature', 'openai_api_key': 'openai_api_key_env', 'streaming': '(False)'}), "(model_name='gpt-3.5-turbo', temperature=temperature,\n    openai_api_key=openai_api_key_env, streaming=False)\n", (1666, 1775), False, 'from langchain.chat_models import ChatOpenAI\n'), ((2018, 2121), 'langchain.chains.ConversationalRetrievalChain.from_llm', 'ConversationalRetrievalChain.from_llm', ([], {'llm': 'model', 'retriever': 'retriever', 'return_source_documents': '(True)'}), '(llm=model, retriever=retriever,\n    return_source_documents=True)\n', (2055, 2121), False, 'from langchain.chains import ConversationalRetrievalChain\n'), ((3647, 3675), 'flask.request.args.get', 'request.args.get', (['"""question"""'], {}), "('question')\n", (3663, 3675), False, 'from flask import Flask, request\n'), ((3691, 3728), 'flask.request.args.get', 'request.args.get', (['"""temp"""'], {'default': '(0.7)'}), "('temp', default=0.7)\n", (3707, 3728), False, 'from flask import Flask, request\n'), ((3747, 3785), 'flask.request.args.get', 'request.args.get', (['"""sources"""'], {'default': '(4)'}), "('sources', default=4)\n", (3763, 3785), False, 'from flask import Flask, request\n'), ((4162, 4187), 'flask.request.files.get', 'request.files.get', (['"""file"""'], {}), "('file')\n", (4179, 4187), False, 'from flask import Flask, request\n'), ((4265, 4295), 'werkzeug.utils.secure_filename', 'secure_filename', (['file.filename'], {}), '(file.filename)\n', (4280, 4295), False, 'from werkzeug.utils import secure_filename\n'), ((4392, 4484), 'langchain.document_loaders.DirectoryLoader', 'DirectoryLoader', (["app.config['UPLOAD_FOLDER']"], {'glob': '"""**/*.pdf"""', 'loader_cls': 'PyMuPDFLoader'}), "(app.config['UPLOAD_FOLDER'], glob='**/*.pdf', loader_cls=\n    PyMuPDFLoader)\n", (4407, 4484), False, 'from langchain.document_loaders import DirectoryLoader, PyMuPDFLoader\n'), ((4563, 4629), 'langchain.text_splitter.RecursiveCharacterTextSplitter', 'RecursiveCharacterTextSplitter', ([], {'chunk_size': '(1000)', 'chunk_overlap': '(100)'}), '(chunk_size=1000, chunk_overlap=100)\n', (4593, 4629), False, 'from langchain.text_splitter import RecursiveCharacterTextSplitter\n'), ((4725, 4811), 'pinecone.init', 'pinecone.init', ([], {'api_key': 'pinecone_api_key_env', 'environment': 'pinecone_environment_env'}), '(api_key=pinecone_api_key_env, environment=\n    pinecone_environment_env)\n', (4738, 4811), False, 'import pinecone\n'), ((4935, 5023), 'langchain.embeddings.openai.OpenAIEmbeddings', 'OpenAIEmbeddings', ([], {'model': '"""text-embedding-ada-002"""', 'openai_api_key': 'openai_api_key_env'}), "(model='text-embedding-ada-002', openai_api_key=\n    openai_api_key_env)\n", (4951, 5023), False, 'from langchain.embeddings.openai import OpenAIEmbeddings\n'), ((5048, 5160), 'langchain.vectorstores.Pinecone.from_documents', 'Pinecone.from_documents', (['documents', 'embeddings'], {'index_name': 'pinecone_index_env', 'namespace': 'pinecone_namespace'}), '(documents, embeddings, index_name=\n    pinecone_index_env, namespace=pinecone_namespace)\n', (5071, 5160), False, 'from langchain.vectorstores import Pinecone\n'), ((4318, 4369), 'os.path.join', 'os.path.join', (["app.config['UPLOAD_FOLDER']", 'filename'], {}), "(app.config['UPLOAD_FOLDER'], filename)\n", (4330, 4369), False, 'import os\n')]