import streamlit as st from PyPDF2 import PdfReader from langchain.text_splitter import RecursiveCharacterTextSplitter import os from langchain_google_genai import GoogleGenerativeAIEmbeddings import google.generativeai as genai from langchain.vectorstores import FAISS from langchain_google_genai import ChatGoogleGenerativeAI from langchain.chains.question_answering import load_qa_chain from langchain.prompts import PromptTemplate from dotenv import load_dotenv load_dotenv() os.getenv("GOOGLE_API_KEY") #configure api key genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) ## extract text from pdf files and put it on one variable def get_pdf_text(pdf_docs): text="" for pdf in pdf_docs: pdf_reader= PdfReader(pdf) #take text from page for page in pdf_reader.pages: text+= page.extract_text() return text #break text to smaller chunks (list of chunks) def get_text_chunks(text): text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000) chunks = text_splitter.split_text(text) return chunks #create vectore store def get_vector_store(text_chunks): embeddings = GoogleGenerativeAIEmbeddings(model = "models/embedding-001") vector_store = FAISS.from_texts(text_chunks, embedding=embeddings) vector_store.save_local("faiss_index") def get_conversational_chain(): prompt_template = """ Answer the question using all the details you have. If the information isn't there just say, "answer is not available in the context", don't provide the wrong answer\n\n Context:\n {context}?\n Question: \n{question}\n Answer: """ model = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.3) prompt = PromptTemplate(template = prompt_template, input_variables = ["context", "question"]) chain = load_qa_chain(model, chain_type="stuff", prompt=prompt) return chain def user_input(user_question): embeddings = GoogleGenerativeAIEmbeddings(model = "models/embedding-001") new_db = FAISS.load_local("faiss_index", embeddings) docs = new_db.similarity_search(user_question) chain = get_conversational_chain() response = chain( {"input_documents":docs, "question": user_question} , return_only_outputs=True) print(response) st.write("Reply: ", response["output_text"]) ##example of response #{'output_text': "Qui utilise des codes mnémotechniques. Pour les codes opérations, on préfère des code s plus suggestif. On crée une table de cor respondance entre code \nopération de l'ordinateur, et des symboles lisibles. L'écriture d'un programme en langage assembleur exige une connaissance par faite du fonctionnement \ninterne de l'ordinateur (quelles sont les mémoires disponibles , etc.). Le langage assembleur permet à l'utilisateur de maîtrise r complètement le \nfonctionnement de son programme dans une machine déterminée. Mais : le programme est difficile à lire , et à corri ger. Le résultat est s pécifique à une pg pg , g pq\nmachine déterminée et donc non utilisable sur une machine différente."} def main(): st.set_page_config("Chat PDF") st.header("Chat with PDF") user_question = st.text_input("Ask a Question from the PDF Files") if user_question: user_input(user_question) with st.sidebar: st.title("Menu:") pdf_docs = st.file_uploader("Upload PDF Files", accept_multiple_files=True) if st.button("Submit & Process"): with st.spinner("Processing..."): raw_text = get_pdf_text(pdf_docs) text_chunks = get_text_chunks(raw_text) get_vector_store(text_chunks) st.success("Done") if __name__ == "__main__": main()