M365TechHelp commited on
Commit
7b80f12
·
verified ·
1 Parent(s): 63746bd

Upload 2 files

Browse files

new files commint

Files changed (2) hide show
  1. app.py +169 -0
  2. requirements.txt +10 -0
app.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import PyPDF2
3
+ import os
4
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
5
+ from sentence_transformers import SentenceTransformer
6
+ from langchain.vectorstores import Chroma
7
+ from langchain_community.embeddings import SentenceTransformerEmbeddings
8
+ from langchain_groq import ChatGroq
9
+ from langchain.chains import RetrievalQA
10
+ from langchain.prompts import PromptTemplate
11
+
12
+ # Initialize global variables for RAG components
13
+ rag_chain = None
14
+ vector_store = None
15
+ llm = None
16
+ embedding_model = None
17
+ embedding_function = None
18
+
19
+ # Set your Groq API key here - Read from environment variable
20
+ # os.environ["GROQ_API_KEY"] = "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" # Removed hardcoded key
21
+ groq_api_key = os.environ.get("GROQ_API_KEY")
22
+
23
+ def build_rag_from_pdf(pdf_path):
24
+ """Builds the RAG chain from an uploaded PDF."""
25
+ global rag_chain, vector_store, llm, embedding_model, embedding_function
26
+
27
+ if not groq_api_key:
28
+ error_message = "Groq API key not set. Please set the GROQ_API_KEY environment variable."
29
+ print(error_message)
30
+ return False, error_message
31
+
32
+ pdf_text = ""
33
+ try:
34
+ with open(pdf_path, 'rb') as file:
35
+ reader = PyPDF2.PdfReader(file)
36
+ for page in reader.pages:
37
+ pdf_text += page.extract_text()
38
+ print("PDF text extracted successfully.")
39
+ except FileNotFoundError:
40
+ error_message = f"Error: The file '{pdf_path}' was not found."
41
+ print(error_message)
42
+ return False, error_message
43
+ except Exception as e:
44
+ error_message = f"An error occurred during PDF extraction: {e}"
45
+ print(error_message)
46
+ return False, error_message
47
+
48
+ if not pdf_text:
49
+ error_message = "Extracted text is empty."
50
+ print(error_message)
51
+ return False, error_message
52
+
53
+ # Split text into chunks
54
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
55
+ text_chunks = text_splitter.split_text(pdf_text)
56
+ print(f"Split PDF text into {len(text_chunks)} chunks.")
57
+
58
+ if not text_chunks:
59
+ error_message = "No text chunks created."
60
+ print(error_message)
61
+ return False, error_message
62
+
63
+ # Create embeddings
64
+ try:
65
+ embedding_model = SentenceTransformer('all-MiniLM-L6-v2')
66
+ embeddings = embedding_model.encode(text_chunks)
67
+ print(f"Generated embeddings for {len(text_chunks)} text chunks.")
68
+ except Exception as e:
69
+ error_message = f"An error occurred during embedding generation: {e}"
70
+ print(error_message)
71
+ return False, error_message
72
+
73
+ # Set up vector store
74
+ try:
75
+ embedding_function = SentenceTransformerEmbeddings(model_name='all-MiniLM-L6-v2')
76
+ vector_store = Chroma.from_texts(texts=text_chunks, embedding=embedding_function)
77
+ print("Chroma vector store created successfully.")
78
+ except Exception as e:
79
+ error_message = f"An error occurred during vector store creation: {e}"
80
+ print(error_message)
81
+ return False, error_message
82
+
83
+ # Initialize LLM
84
+ try:
85
+ llm = ChatGroq(model_name="openai/gpt-oss-20b", groq_api_key=groq_api_key) # Pass API key
86
+ print("Groq language model set up successfully.")
87
+ except Exception as e:
88
+ error_message = f"An error occurred during LLM setup: {e}"
89
+ print(error_message)
90
+ return False, error_message
91
+
92
+ # Build RAG chain
93
+ try:
94
+ template = """Use the following pieces of context to answer queries about the provided document efficiently. If you don't know the answer, just say that you don't know, don't try to make up an answer.
95
+
96
+ {context}
97
+
98
+ Question: {question}
99
+ Helpful Answer:"""
100
+ QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
101
+
102
+ rag_chain = RetrievalQA.from_chain_type(
103
+ llm=llm,
104
+ chain_type="stuff",
105
+ retriever=vector_store.as_retriever(),
106
+ chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
107
+ )
108
+ print("RAG chain built successfully.")
109
+ return True, "Document processed. You can now ask questions."
110
+ except Exception as e:
111
+ error_message = f"An error occurred while building the RAG chain: {e}"
112
+ print(error_message)
113
+ rag_chain = None
114
+ return False, error_message
115
+
116
+ def chat_with_rag(message, history):
117
+ """Handles chat interactions using the RAG chain."""
118
+ global rag_chain
119
+ print(f"chat_with_rag received history type: {type(history)}, content: {history}") # Debug print
120
+ if rag_chain is not None:
121
+ try:
122
+ response = rag_chain.invoke(message)
123
+ # Append message and response in the 'messages' format
124
+ history.append({"role": "user", "content": message})
125
+ history.append({"role": "assistant", "content": response['result']})
126
+ print(f"chat_with_rag returning history type: {type(history)}, content: {history}") # Debug print
127
+ return history
128
+ except Exception as e:
129
+ error_message = f"An error occurred while querying the RAG chain: {e}"
130
+ history.append({"role": "user", "content": message})
131
+ history.append({"role": "assistant", "content": error_message})
132
+ print(f"chat_with_rag returning history with error type: {type(history)}, content: {history}") # Debug print
133
+ return history
134
+ else:
135
+ error_message = "Please upload a document to start the chat."
136
+ history.append({"role": "user", "content": message})
137
+ history.append({"role": "assistant", "content": error_message})
138
+ print(f"chat_with_rag returning history with no RAG chain type: {type(history)}, content: {history}") # Debug print
139
+ return history
140
+
141
+ def process_file(file):
142
+ """Processes the uploaded file and builds the RAG chain."""
143
+ if file is None:
144
+ print("process_file received None file.") # Debug print
145
+ return "Please upload a file.", None
146
+ print(f"Processing file: {file.name}") # Debug print
147
+ success, message = build_rag_from_pdf(file.name)
148
+ if success:
149
+ print("File processing successful, returning message and None for history.") # Debug print
150
+ # Return None for chatbot history to clear it on successful upload
151
+ return message, None
152
+ else:
153
+ print(f"File processing failed, returning message and empty list for history. Message: {message}") # Debug print
154
+ return message, []
155
+
156
+ # Define the Gradio interface
157
+ with gr.Blocks() as demo:
158
+ gr.Markdown("## RAG Chatbot with Document Upload")
159
+ file_upload = gr.File(label="Upload your document (PDF)")
160
+ output_message = gr.Textbox(label="Status")
161
+ chatbot = gr.Chatbot(type='messages') # Explicitly set type to 'messages'
162
+ msg = gr.Textbox(label="Your Question")
163
+ clear = gr.ClearButton([msg, chatbot])
164
+
165
+ file_upload.upload(process_file, inputs=[file_upload], outputs=[output_message, chatbot])
166
+ msg.submit(chat_with_rag, inputs=[msg, chatbot], outputs=[chatbot])
167
+
168
+ if __name__ == "__main__":
169
+ demo.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ langchain
2
+ pypdf2
3
+ groq
4
+ chromadb
5
+ langchain-groq
6
+ langchain-community
7
+ langchain-text-splitters
8
+ langchain-core
9
+ sentence-transformers
10
+ gradio