From a68606c564cc747c922ef32710b087c8e697c923 Mon Sep 17 00:00:00 2001 From: tulu-g559 Date: Sun, 9 Mar 2025 00:37:50 +0530 Subject: [PATCH 1/4] Added PDF Wizard --- Generative-AI/PDF Wizard/.env | 1 + Generative-AI/PDF Wizard/app.py | 117 ++++++++++++++++ Generative-AI/PDF Wizard/faiss_index/app.py | 129 ++++++++++++++++++ .../PDF Wizard/faiss_index/index.faiss | Bin 0 -> 3117 bytes .../PDF Wizard/faiss_index/index.pkl | Bin 0 -> 8674 bytes Generative-AI/PDF Wizard/image.png | Bin 0 -> 83822 bytes Generative-AI/PDF Wizard/readme_pdf_wiz.md | 92 +++++++++++++ Generative-AI/PDF Wizard/requirements.txt | 7 + 8 files changed, 346 insertions(+) create mode 100644 Generative-AI/PDF Wizard/.env create mode 100644 Generative-AI/PDF Wizard/app.py create mode 100644 Generative-AI/PDF Wizard/faiss_index/app.py create mode 100644 Generative-AI/PDF Wizard/faiss_index/index.faiss create mode 100644 Generative-AI/PDF Wizard/faiss_index/index.pkl create mode 100644 Generative-AI/PDF Wizard/image.png create mode 100644 Generative-AI/PDF Wizard/readme_pdf_wiz.md create mode 100644 Generative-AI/PDF Wizard/requirements.txt diff --git a/Generative-AI/PDF Wizard/.env b/Generative-AI/PDF Wizard/.env new file mode 100644 index 0000000000..92e9f098e7 --- /dev/null +++ b/Generative-AI/PDF Wizard/.env @@ -0,0 +1 @@ +GOOGLE_API_KEY = "Your_GEMIN_API_KEY"; \ No newline at end of file diff --git a/Generative-AI/PDF Wizard/app.py b/Generative-AI/PDF Wizard/app.py new file mode 100644 index 0000000000..2d3b34952a --- /dev/null +++ b/Generative-AI/PDF Wizard/app.py @@ -0,0 +1,117 @@ +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") +genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) + + +##Function that reads the pdd goes through each and every page +def get_pdf_text(pdf_docs): + text="" + for pdf in pdf_docs: + pdf_reader= PdfReader(pdf) + for page in pdf_reader.pages: + text+= page.extract_text() + return text + + +##Function that breaks text into chunks +def get_text_chunks(text): + # Adjust chunk size and overlap as needed + text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000) + chunks = text_splitter.split_text(text) + return chunks + + +##Function that saves the data we got from conversation to local(here), generally stored in data base +#converting into chunks -> storing data in faiss vector +def get_vector_store(text_chunks): + embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") + vector_store = FAISS.from_texts(text_chunks, embedding=embeddings) + + # Ensure the directory exists + if not os.path.exists("faiss_index"): + os.makedirs("faiss_index") + + # Save the vector store index in the directory + vector_store.save_local("faiss_index") + + +#Function to give the prompt and ask the bot to act accordingly, giving the gemini model +def get_conversational_chain(): + + prompt_template = """ + Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in + provided context 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 + + +##Function for user input, question +#give the question-> do a similarity search on all the faiss vectors-> go with converstional chain-> response from chain +def user_input(user_question): + embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") + + # Check if the faiss_index file exists before loading + if not os.path.exists("faiss_index/index.faiss"): + st.error("FAISS index file not found. Please process the PDF files first.") + return + + new_db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True) + 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"]) + + +##Main Function for streamlit app +def main(): + st.set_page_config("PDF Wizard") + st.header("Chat with multiple PDFs📄") + + 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 your PDF Files and Click on the Submit & Process Button", 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() \ No newline at end of file diff --git a/Generative-AI/PDF Wizard/faiss_index/app.py b/Generative-AI/PDF Wizard/faiss_index/app.py new file mode 100644 index 0000000000..6c10d9a2f4 --- /dev/null +++ b/Generative-AI/PDF Wizard/faiss_index/app.py @@ -0,0 +1,129 @@ +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") +genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) + + + + +##Function that reads the pdd goes through each and every page +def get_pdf_text(pdf_docs): + text="" + for pdf in pdf_docs: + pdf_reader= PdfReader(pdf) + for page in pdf_reader.pages: + text+= page.extract_text() + return text + + + +##Function that breaks text into chunks +def get_text_chunks(text): + # Adjust chunk size and overlap as needed + text_splitter = RecursiveCharacterTextSplitter(chunk_size=10000, chunk_overlap=1000) + chunks = text_splitter.split_text(text) + return chunks + + + + +##Function that saves the data we got from conversation to local(here), generally stored in data base +#converting into chunks -> storing data in faiss vector +def get_vector_store(text_chunks): + embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") + vector_store = FAISS.from_texts(text_chunks, embedding=embeddings) + + # Ensure the directory exists + if not os.path.exists("faiss_index"): + os.makedirs("faiss_index") + + # Save the vector store index in the directory + vector_store.save_local("faiss_index") + + + + +#Function to give the prompt and ask the bot to act accordingly, giving the gemini model +def get_conversational_chain(): + + prompt_template = """ + Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in + provided context 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 + + + + + +##Function for user input, question +#give the question-> do a similarity search on all the faiss vectors-> go with converstional chain-> response from chain +def user_input(user_question): + embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") + + # Check if the faiss_index file exists before loading + if not os.path.exists("faiss_index/index.faiss"): + st.error("FAISS index file not found. Please process the PDF files first.") + return + + new_db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True) + 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"]) + + + + +##Main Function for streamlit app +def main(): + st.set_page_config("PDF Wizard") + st.header("Chat with multiple PDFs📄") + + 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 your PDF Files and Click on the Submit & Process Button", 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() \ No newline at end of file diff --git a/Generative-AI/PDF Wizard/faiss_index/index.faiss b/Generative-AI/PDF Wizard/faiss_index/index.faiss new file mode 100644 index 0000000000000000000000000000000000000000..7c9f680723b997ccbe8f8c31145898c9ec8cdce2 GIT binary patch literal 3117 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 literal 0 HcmV?d00001 diff --git a/Generative-AI/PDF Wizard/readme_pdf_wiz.md b/Generative-AI/PDF Wizard/readme_pdf_wiz.md new file mode 100644 index 0000000000..acb0530c37 --- /dev/null +++ b/Generative-AI/PDF Wizard/readme_pdf_wiz.md @@ -0,0 +1,92 @@ +# PDF Wizard + + +📌 Overview +----------- + +PDF Wizard is an AI-powered Streamlit web application that allows users to chat with multiple PDFs. It processes uploaded PDF files, extracts their text, converts them into embeddings, stores them in a FAISS vector database, and answers user queries based on the stored content using Google's Gemini AI. + +🚀 Features +----------- + +* 📂 Upload multiple PDF files +* 🧠 AI-powered chatbot using Google Gemini API +* 🔍 Search and retrieve context-based answers +* 📚 FAISS vector database for efficient document searching +* ⚡ Streamlit-based interactive UI + + +🛠️ Tech Stack +-------------- + +* Python +* Streamlit +* FAISS +* Google Generative AI (Gemini API) +* PyPDF2 +* LangChain +* dotenv + + +📦 Installation +--------------- +1. Clone the Repo +``` +git clone https://github.com/UTSAVS26/PyVerse.git +cd Generative-AI +cd PDF-Wizard + ``` +2. Activate the environment +``` +python -m venv venv +``` +``` +source venv/bin/activate # For macOS/Linux +venv\Scripts\activate # For Windows +``` +3. Install dependencies +`pip install -r requirements.txt` + +4. **Set Up Environment Variables** + + * Create a .env file in the project root. + * GOOGLE\_API\_KEY= **your\_google\_api\_key** + + +🎯 Usage +-------- + +1. Run the application +`streamlit run app.py` + +2. **Upload PDF files** via the sidebar. + +3. **Ask questions** based on the uploaded PDFs. + +📂 ScreenShots +--------------------- +![alt text](image.png) + +📂 Project Structure +-------------------- +``` +PDF-Wizard +│-- faiss_index/ # Directory to store FAISS vectors +│-- app.py # Main Streamlit app +│-- requirements.txt # Required dependencies +│-- .env # API keys and environment variables +│-- README.md # Project documentation +``` + +🌟 Acknowledgments +------------------ + +* [Streamlit](https://streamlit.io/) +* [FAISS](https://faiss.ai/) +* [Google Generative AI](https://ai.google.dev/) + +👤 Contributor +---------------- +- **Name:** Arnab Ghosh +- **GitHub:** [tulug-559](https://github.com/tulu-g559) +- **Contact:** [email](garnab559@gmai.com) \ No newline at end of file diff --git a/Generative-AI/PDF Wizard/requirements.txt b/Generative-AI/PDF Wizard/requirements.txt new file mode 100644 index 0000000000..d6ecaadf59 --- /dev/null +++ b/Generative-AI/PDF Wizard/requirements.txt @@ -0,0 +1,7 @@ +streamlit +google-generativeai +python-dotenv +langchain +PyPDF2 +faiss-cpu +langchain_google_genai \ No newline at end of file From 8c76b2ed03801668bc6980008f0e324b155d2c24 Mon Sep 17 00:00:00 2001 From: tulu-g559 Date: Sun, 9 Mar 2025 01:10:30 +0530 Subject: [PATCH 2/4] Updated according to CodeRabbit refractor suggesioins --- Generative-AI/PDF Wizard/app.py | 47 ++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/Generative-AI/PDF Wizard/app.py b/Generative-AI/PDF Wizard/app.py index 2d3b34952a..f57ddfad62 100644 --- a/Generative-AI/PDF Wizard/app.py +++ b/Generative-AI/PDF Wizard/app.py @@ -12,17 +12,27 @@ load_dotenv() -os.getenv("GOOGLE_API_KEY") -genai.configure(api_key=os.getenv("GOOGLE_API_KEY")) +api_key = os.getenv("GOOGLE_API_KEY") +if not api_key: + raise ValueError("GOOGLE_API_KEY environment variable is missing. Please add it to your .env file.") +genai.configure(api_key=api_key) ##Function that reads the pdd goes through each and every page def get_pdf_text(pdf_docs): + if not pdf_docs: + return "" text="" for pdf in pdf_docs: pdf_reader= PdfReader(pdf) for page in pdf_reader.pages: text+= page.extract_text() + try: + pdf_reader = PdfReader(pdf) + for page in pdf_reader.pages: + text += page.extract_text() + except Exception as e: + st.error(f"Error reading PDF '{pdf.name}': {str(e)}") return text @@ -36,16 +46,33 @@ def get_text_chunks(text): ##Function that saves the data we got from conversation to local(here), generally stored in data base #converting into chunks -> storing data in faiss vector -def get_vector_store(text_chunks): - embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") - vector_store = FAISS.from_texts(text_chunks, embedding=embeddings) +def get_vector_store(text_chunks, embedding_model="models/embedding-001", store_dir="faiss_index"): + """Create and save vector store from text chunks. - # Ensure the directory exists - if not os.path.exists("faiss_index"): - os.makedirs("faiss_index") + Args: + text_chunks: List of text chunks to embed + embedding_model: Name of the embedding model to use + store_dir: Directory to save the vector store - # Save the vector store index in the directory - vector_store.save_local("faiss_index") + Returns: + None + """ + if not text_chunks: + st.warning("No text to process. Please check the PDF content.") + return + + try: + embeddings = GoogleGenerativeAIEmbeddings(model=embedding_model) + vector_store = FAISS.from_texts(text_chunks, embedding=embeddings) + + # Ensure the directory exists + if not os.path.exists(store_dir): + os.makedirs(store_dir) + + # Save the vector store index in the directory + vector_store.save_local(store_dir) + except Exception as e: + st.error(f"Error creating vector store: {str(e)}") #Function to give the prompt and ask the bot to act accordingly, giving the gemini model From d28b2e221ff59a87d913eb2dde5187fd238d4b89 Mon Sep 17 00:00:00 2001 From: tulu-g559 Date: Sun, 9 Mar 2025 11:21:05 +0530 Subject: [PATCH 3/4] Redundancies resolved --- Generative-AI/PDF Wizard/app.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Generative-AI/PDF Wizard/app.py b/Generative-AI/PDF Wizard/app.py index f57ddfad62..1dc72fecf8 100644 --- a/Generative-AI/PDF Wizard/app.py +++ b/Generative-AI/PDF Wizard/app.py @@ -27,12 +27,13 @@ def get_pdf_text(pdf_docs): pdf_reader= PdfReader(pdf) for page in pdf_reader.pages: text+= page.extract_text() - try: - pdf_reader = PdfReader(pdf) - for page in pdf_reader.pages: - text += page.extract_text() - except Exception as e: - st.error(f"Error reading PDF '{pdf.name}': {str(e)}") + # Optionally wrap the above block in try-except if needed: + # try: + # pdf_reader = PdfReader(pdf) + # for page in pdf_reader.pages: + # text += page.extract_text() + # except Exception as e: + # st.error(f"Error reading PDF '{pdf.name}': {str(e)}") return text @@ -104,7 +105,7 @@ def user_input(user_question): st.error("FAISS index file not found. Please process the PDF files first.") return - new_db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True) + new_db = FAISS.load_local("faiss_index", embeddings) docs = new_db.similarity_search(user_question) chain = get_conversational_chain() From 5e2827a4cb08b5ec0fe0a024350e3344258b51f2 Mon Sep 17 00:00:00 2001 From: tulu-g559 Date: Sun, 9 Mar 2025 11:30:13 +0530 Subject: [PATCH 4/4] Updated the latest version of gemini --- Generative-AI/PDF Wizard/app.py | 2 +- Generative-AI/PDF Wizard/faiss_index/app.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Generative-AI/PDF Wizard/app.py b/Generative-AI/PDF Wizard/app.py index 1dc72fecf8..9b5f4b72a8 100644 --- a/Generative-AI/PDF Wizard/app.py +++ b/Generative-AI/PDF Wizard/app.py @@ -87,7 +87,7 @@ def get_conversational_chain(): Answer: """ - model = ChatGoogleGenerativeAI(model="gemini-pro",temperature=0.3) + model = ChatGoogleGenerativeAI(model="gemini-1.5-flash",temperature=0.3) prompt = PromptTemplate(template = prompt_template, input_variables = ["context", "question"]) chain = load_qa_chain(model, chain_type="stuff", prompt=prompt) diff --git a/Generative-AI/PDF Wizard/faiss_index/app.py b/Generative-AI/PDF Wizard/faiss_index/app.py index 6c10d9a2f4..0b490bf55d 100644 --- a/Generative-AI/PDF Wizard/faiss_index/app.py +++ b/Generative-AI/PDF Wizard/faiss_index/app.py @@ -66,7 +66,7 @@ def get_conversational_chain(): Answer: """ - model = ChatGoogleGenerativeAI(model="gemini-pro",temperature=0.3) + model = ChatGoogleGenerativeAI(model="gemini-1.5-flash",temperature=0.3) prompt = PromptTemplate(template = prompt_template, input_variables = ["context", "question"]) chain = load_qa_chain(model, chain_type="stuff", prompt=prompt)