ask-my-docs / app.py
ahmadimran's picture
Update app.py
6cb2ef7 verified
Raw
History Blame Contribute Delete
4.65 kB
# Modules for environment variables
import os
from dotenv import load_dotenv
# Module for Interface (UI)
import gradio as gr
# Modules for Sourcing Data, transforming, embedding, and storing
from langchain_community.document_loaders import (
PyPDFDirectoryLoader,
PyPDFLoader,
Docx2txtLoader,
TextLoader,
CSVLoader,
UnstructuredPowerPointLoader,
)
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
# Modules for Document chain, retriever, and retrieval chain
from langchain_classic.chains.combine_documents import create_stuff_documents_chain
from langchain_groq import ChatGroq
from langchain_core.prompts import ChatPromptTemplate
from langchain_classic.chains import create_retrieval_chain
# Get the env variables
load_dotenv()
os.environ['GROQ_API_KEY'] = os.getenv('GROQ_API_KEY')
# Load embeddings model
embeddings = HuggingFaceEmbeddings(
model_name = 'sentence-transformers/all-MiniLM-L6-v2',
model_kwargs = {"device": "cpu"},
encode_kwargs = {"batch_size": 8}
)
# Load the source data and chunk it
KNOWLEDGE_DIR = os.path.join(os.path.dirname(__file__), "knowledge")
loader = PyPDFDirectoryLoader(KNOWLEDGE_DIR)
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=200)
documents = text_splitter.split_documents(docs)
# Embed the data and store it in the database if it is not already stored, if it is stored, then just load it from local index file
if os.path.exists("faiss_index"):
db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)
else:
db = FAISS.from_documents(documents, embeddings)
db.save_local("faiss_index")
# Initialize the LLM model and generate a rag prompt
llm = ChatGroq(
model_name="llama-3.3-70b-versatile"
)
rag_prompt = ChatPromptTemplate.from_template(
"""
Answer the questions based only on the provided context. Don't hallucinate. Don't reply to anything else that is not in the context. Make sure you provide the most accurate answer and I will give you praise when you will provide the best accurate answer which the user finds helpful.
<context> {context} </context>
Question: {input}
"""
)
# Create retriever, document chain, and retrieval chain for retrieving the embeddings from the vector store
retriever = db.as_retriever()
document_chain = create_stuff_documents_chain(llm, rag_prompt)
retrieval_chain = create_retrieval_chain(retriever, document_chain)
# For multiple file types uploaded by the user
def load_file_by_extension(file_path):
ext = os.path.splitext(file_path)[-1].lower()
try:
if ext == ".pdf":
return PyPDFLoader(file_path).load()
elif ext == ".docx":
return Docx2txtLoader(file_path).load()
elif ext == ".txt":
return TextLoader(file_path).load()
elif ext == ".csv":
return CSVLoader(file_path).load()
elif ext == ".pptx":
return UnstructuredPowerPointLoader(file_path).load()
else:
print(f"Unsupported file type: {ext}")
return []
except Exception as e:
print(f"Error loading {file_path}: {e}")
return []
# Function for gradio chat interface
def response(message, history):
user_text = message["text"]
user_files = message["files"]
if user_files:
new_docs = []
for file in user_files:
file_path = file["path"] if isinstance(file, dict) else file
loaded = load_file_by_extension(file_path)
new_docs.extend(loaded)
split_new_docs = text_splitter.split_documents(new_docs)
db.add_documents(split_new_docs)
response = retrieval_chain.invoke({"input": user_text})
answer = response["answer"]
return answer
# Gradio Initialization
with gr.Blocks(title='RAG Knowledge Based Chatbot') as demo:
gr.Markdown('RAG Chatbot')
gr.Markdown('Ask anything about your uploaded documents and about mr chips questions and answers')
chatbot = gr.ChatInterface(
fn=response,
multimodal=True,
chatbot=gr.Chatbot(height=420, show_label=False),
textbox=gr.MultimodalTextbox(
placeholder='Ask anything about your uploaded files',
file_types=[".pdf", ".txt", ".docx", ".csv", ".xlsx", "image"],
container=False,
scale=8
),
examples=[
"What is Logistics Regression?",
"What services did Brookfield render during the war?",
"When and how did Katherine die?"
]
)
demo.launch()