Kiran commited on
Commit
e2dac05
·
verified ·
1 Parent(s): 113e72a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +210 -0
app.py ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from dotenv import load_dotenv
4
+ from groq import Groq
5
+ from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader
6
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
7
+ from langchain_community.vectorstores import FAISS
8
+ from langchain_community.embeddings import HuggingFaceEmbeddings
9
+ import streamlit as st
10
+
11
+
12
+ def load_docs_from_url(input_url):
13
+ web_loader = WebBaseLoader(input_url)
14
+ documents = web_loader.load()
15
+ splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
16
+ split_documents = splitter.split_documents(documents)
17
+ st.write('Documents Loaded from URL')
18
+ return split_documents
19
+
20
+ def load_docs_from_pdf(file):
21
+ start = time.time()
22
+ with open("temp.pdf", "wb") as temp_file:
23
+ temp_file.write(file.getbuffer())
24
+ pdf_loader = PyPDFLoader("temp.pdf")
25
+ pdf_documents = pdf_loader.load()
26
+ splitter = RecursiveCharacterTextSplitter(chunk_size=3000, chunk_overlap=150)
27
+ processed_documents = splitter.split_documents(pdf_documents)
28
+ st.write('Documents Loaded')
29
+ st.write(f"Time taken to load documents: {time.time() - start:.2f} seconds")
30
+ os.remove("temp.pdf")
31
+ return processed_documents
32
+
33
+ def build_vector_db(documents):
34
+ start = time.time()
35
+ embedder = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2", model_kwargs={"trust_remote_code": True})
36
+ db = FAISS.from_documents(documents, embedder)
37
+ st.write('DB is ready')
38
+ st.write(f"Time taken to create DB: {time.time() - start:.2f} seconds")
39
+ return db
40
+
41
+ def call_groq_api(chat_messages):
42
+ load_dotenv()
43
+ api_key = os.getenv("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")
44
+ if not api_key:
45
+ st.error("GROQ API key not found. Please set it in your .env file.")
46
+ return "API key missing."
47
+
48
+ groq_client = Groq(api_key=api_key)
49
+ full_response = ''
50
+ stream_output = groq_client.chat.completions.create(
51
+ model="llama3-70b-8192",
52
+ messages=chat_messages,
53
+ max_tokens=2048,
54
+ temperature=1.0,
55
+ stream=True,
56
+ )
57
+
58
+ for chunk in stream_output:
59
+ part = chunk.choices[0].delta.content
60
+ if part:
61
+ full_response += part
62
+ return full_response
63
+
64
+ def summarize_conversation(history):
65
+ history_text = " ".join([f"{entry['role']}: {entry['content']}" for entry in history])
66
+ summary_prompt = f"Summarize the following chat history:\n\n{history_text}"
67
+ summary_messages = [{'role': 'system', 'content': 'You are very good at summarizing the chat between User and Assistant'}]
68
+ summary_messages.append({'role': 'user', 'content': summary_prompt})
69
+ return call_groq_api(summary_messages)
70
+
71
+ def main():
72
+ st.set_page_config(page_title='Chatbot')
73
+ st.title("Document Chatbot using RAGs - Harsh Tripathi and Shubham Soni")
74
+
75
+ with st.expander("Instructions to upload Text PDF/URL"):
76
+ st.write("1. Open the sidebar by clicking the menu icon in the top-left corner.")
77
+ st.write("2. If you're uploading a PDF, click 'Upload PDF', choose your file, and wait until you see the 'Documents Loaded' message.")
78
+ st.write("3. If you're using a web URL, type it in, click 'Enter Web URL', then hit 'Process URL' and wait for the 'Documents Loaded from URL' confirmation.")
79
+ st.write("4. Once the documents are loaded, click 'Create Vector Store' to begin processing.")
80
+ st.write("5. Type your question into the text box and click Submit.")
81
+ st.write("6. Click 'Generate Chat Summary' to view a summary of the entire chat session.")
82
+
83
+ # Session reset button
84
+ if st.sidebar.button("Reset Session"):
85
+ for key in st.session_state.keys():
86
+ del st.session_state[key]
87
+ st.experimental_rerun()
88
+
89
+ st.sidebar.subheader("Choose document source:")
90
+ input_choice = st.sidebar.radio("Select one:", ("Upload PDF", "Enter Web URL"))
91
+
92
+ # Session state initialization
93
+ if "loaded_docs" not in st.session_state:
94
+ st.session_state.loaded_docs = None
95
+ if "document_db" not in st.session_state:
96
+ st.session_state.document_db = None
97
+ if "conversation" not in st.session_state:
98
+ st.session_state.conversation = []
99
+ if "query_input" not in st.session_state:
100
+ st.session_state.query_input = ""
101
+ if "latest_output" not in st.session_state:
102
+ st.session_state.latest_output = ""
103
+ if "chat_summary" not in st.session_state:
104
+ st.session_state.chat_summary = ""
105
+
106
+ if input_choice == "Upload PDF":
107
+ file_input = st.sidebar.file_uploader("Upload a PDF file", type=["pdf"])
108
+ if file_input is not None:
109
+ if st.session_state.loaded_docs is None:
110
+ with st.spinner("Loading documents..."):
111
+ documents = load_docs_from_pdf(file_input)
112
+ st.session_state.loaded_docs = documents
113
+
114
+ elif input_choice == "Enter Web URL":
115
+ input_url = st.sidebar.text_input("Enter URL", key="url_input")
116
+ if st.session_state.url_input != input_url:
117
+ st.session_state.url_input = input_url
118
+ st.session_state.loaded_docs = None
119
+ if st.sidebar.button('Process URL'):
120
+ if input_url and st.session_state.loaded_docs is None:
121
+ with st.spinner("Fetching and processing documents from URL..."):
122
+ documents = load_docs_from_url(input_url)
123
+ st.session_state.loaded_docs = documents
124
+
125
+ if st.session_state.loaded_docs is not None:
126
+ if st.sidebar.button('Create Vector Store'):
127
+ with st.spinner("Creating vector store..."):
128
+ db = build_vector_db(st.session_state.loaded_docs)
129
+ st.session_state.document_db = db
130
+
131
+ # Chat handling logic
132
+ def submit_with_db():
133
+ user_input = st.session_state.query_input
134
+ if user_input:
135
+ doc_retriever = st.session_state.document_db.as_retriever(search_type="similarity", search_kwargs={"k": 3})
136
+ results = doc_retriever.invoke(user_input)
137
+ constructed_prompt = f'''
138
+ You are a helpful assistant. Answer the user's question based on the context below.
139
+ If the answer is not found in the context, respond with general knowledge.
140
+
141
+ Context: {results}
142
+ Chat History: {st.session_state.conversation}
143
+ Latest Question: {user_input}
144
+ '''
145
+ message_flow = [{'role': 'system', 'content': 'You are a very helpful assistant'}]
146
+ message_flow.append({'role': 'user', 'content': constructed_prompt})
147
+
148
+ try:
149
+ reply = call_groq_api(message_flow)
150
+ except Exception as err:
151
+ st.error(f"Error occurred during chat_groq execution: {str(err)}")
152
+ reply = "An error occurred while fetching response. Please try again."
153
+
154
+ st.session_state.latest_output = reply
155
+ st.session_state.conversation.append({'role': 'user', 'content': user_input})
156
+ st.session_state.conversation.append({'role': 'assistant', 'content': reply})
157
+ st.session_state.query_input = ""
158
+
159
+ def handle_general_chat():
160
+ user_input = st.session_state.query_input
161
+ if user_input:
162
+ prompt_text = f'''
163
+ You are a helpful assistant. Answer the question based on the conversation context.
164
+
165
+ Chat History: {st.session_state.conversation}
166
+ Latest Question: {user_input}
167
+ '''
168
+ message_flow = [{'role': 'system', 'content': 'You are a very helpful assistant'}]
169
+ message_flow.append({'role': 'user', 'content': prompt_text})
170
+
171
+ try:
172
+ reply = call_groq_api(message_flow)
173
+ except Exception as err:
174
+ st.error(f"Error occurred during chat_groq execution: {str(err)}")
175
+ reply = "An error occurred while fetching response. Please try again."
176
+
177
+ st.session_state.latest_output = reply
178
+ st.session_state.conversation.append({'role': 'user', 'content': user_input})
179
+ st.session_state.conversation.append({'role': 'assistant', 'content': reply})
180
+ st.session_state.query_input = ""
181
+
182
+ st.text_area("Enter your question:", key="query_input")
183
+ if st.session_state.document_db is not None:
184
+ st.button('Submit', on_click=submit_with_db)
185
+ else:
186
+ st.button('Submit', on_click=handle_general_chat)
187
+
188
+ if st.session_state.latest_output:
189
+ st.write(st.session_state.latest_output)
190
+
191
+ if st.button('Generate Chat Summary'):
192
+ st.session_state.chat_summary = summarize_conversation(st.session_state.conversation)
193
+
194
+ if st.session_state.chat_summary:
195
+ with st.expander("Chat Summary"):
196
+ st.write(st.session_state.chat_summary)
197
+
198
+ with st.expander("Recent Chat History"):
199
+ latest_entries = st.session_state.conversation[-8:][::-1]
200
+ paired_entries = []
201
+ for i in range(0, len(latest_entries), 2):
202
+ if i+1 < len(latest_entries):
203
+ paired_entries.extend([latest_entries[i+1], latest_entries[i]])
204
+ else:
205
+ paired_entries.append(latest_entries[i])
206
+ for entry in paired_entries:
207
+ st.write(f"{entry['role'].capitalize()}: {entry['content']}")
208
+
209
+ if __name__ == "__main__":
210
+ main()