RAVENOCC commited on
Commit
6e61695
·
verified ·
1 Parent(s): 503a2ed

Upload 2 files

Browse files
Files changed (2) hide show
  1. src/app.py +179 -0
  2. src/htmlTemplates.py +44 -0
src/app.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from dotenv import load_dotenv
3
+ from PyPDF2 import PdfReader
4
+ from langchain_groq import ChatGroq
5
+ from langchain.text_splitter import CharacterTextSplitter
6
+ from langchain_community.embeddings import HuggingFaceEmbeddings
7
+ #from langchain_huggingface import HuggingFaceEmbeddings
8
+ from langchain_community.vectorstores import FAISS
9
+ from langchain_community.llms import HuggingFaceHub
10
+ from langchain.prompts import ChatPromptTemplate
11
+ from langchain_core.output_parsers import StrOutputParser
12
+ from langchain_core.runnables import RunnablePassthrough
13
+ from htmlTemplates import css, bot_template, user_template
14
+
15
+
16
+ def get_pdf_text(pdf_docs):
17
+ text = ""
18
+ for pdf in pdf_docs:
19
+ pdf_reader = PdfReader(pdf)
20
+ for page in pdf_reader.pages:
21
+ text += page.extract_text()
22
+ return text
23
+
24
+ def get_text_chunks(text):
25
+ text_splitter = CharacterTextSplitter(
26
+ separator="\n",
27
+ chunk_size=1000,
28
+ chunk_overlap=200,
29
+ length_function=len
30
+ )
31
+ chunks = text_splitter.split_text(text)
32
+ return chunks
33
+
34
+ def get_vector_store(text_chunks):
35
+ model_name = "BAAI/bge-small-en"
36
+ model_kwargs = {'device': 'cpu'}
37
+ encode_kwargs = {"normalize_embeddings": True}
38
+
39
+ embeddings = HuggingFaceEmbeddings(
40
+ model_name=model_name,
41
+ model_kwargs=model_kwargs,
42
+ encode_kwargs=encode_kwargs
43
+ )
44
+
45
+ vectorstore = FAISS.from_texts(texts=text_chunks, embedding=embeddings)
46
+ return vectorstore
47
+
48
+ def get_conversation_chain(vectorstore):
49
+ llm= ChatGroq(model="llama3-8b-8192",temperature=0)
50
+ # Create the prompt template
51
+ prompt = ChatPromptTemplate.from_messages([
52
+ ("system", """You are a helpful assistant answering questions based on the provided documents.
53
+ Answer the question using only the context provided.
54
+ If you don't know the answer, just say that you don't know, don't try to make up an answer.
55
+ Keep your answers focused and relevant to the question."""),
56
+ ("human", """Context: {context}
57
+
58
+ Question: {question}
59
+
60
+ Answer: """)
61
+ ])
62
+
63
+ # Create the retrieval chain using syntax
64
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
65
+
66
+ # Define the chain
67
+ chain = (
68
+ {"context": retriever, "question": RunnablePassthrough()}
69
+ | prompt
70
+ | llm
71
+ | StrOutputParser()
72
+ )
73
+
74
+ return chain
75
+
76
+ def handle_user_input(user_question):
77
+ if st.session_state.conversation is None:
78
+ st.warning("Please upload and process documents first.")
79
+ return
80
+
81
+ try:
82
+ # Invoke the chain with the question
83
+ response = st.session_state.conversation.invoke(user_question)
84
+
85
+ # Update chat history
86
+ if 'chat_history' not in st.session_state:
87
+ st.session_state.chat_history = []
88
+
89
+ # Add the new messages to chat history
90
+ st.session_state.chat_history.append(("user", user_question))
91
+ st.session_state.chat_history.append(("bot", response))
92
+
93
+ # Display chat history
94
+ for sender, message in st.session_state.chat_history:
95
+ if sender == "user":
96
+ st.write(user_template.replace("{{MSG}}", message), unsafe_allow_html=True)
97
+ else:
98
+ st.write(bot_template.replace("{{MSG}}", message), unsafe_allow_html=True)
99
+
100
+ except Exception as e:
101
+ st.error(f"An error occurred while processing your question: {str(e)}")
102
+
103
+ def main():
104
+ load_dotenv()
105
+
106
+ # st.write(css, unsafe_allow_html=True)
107
+
108
+ if 'user_template' not in globals():
109
+ global user_template
110
+ user_template = '''
111
+ <div class="chat-message user">
112
+ <div class="avatar">
113
+ <img src="https://i.ibb.co/rdZC7LZ/user.png">
114
+ </div>
115
+ <div class="message">{{MSG}}</div>
116
+ </div>
117
+ '''
118
+
119
+ if 'bot_template' not in globals():
120
+ global bot_template
121
+ bot_template = '''
122
+ <div class="chat-message bot">
123
+ <div class="avatar">
124
+ <img src="https://i.ibb.co/cN0nmSj/robot.png">
125
+ </div>
126
+ <div class="message">{{MSG}}</div>
127
+ </div>
128
+ '''
129
+
130
+ st.set_page_config(page_title='Chat with PDFs', page_icon=":books:")
131
+ st.write(css, unsafe_allow_html=True)
132
+
133
+ if "conversation" not in st.session_state:
134
+ st.session_state.conversation = None
135
+
136
+ if "chat_history" not in st.session_state:
137
+ st.session_state.chat_history = []
138
+
139
+ st.header('PDF ChatBot 📚')
140
+
141
+ # Sidebar for PDF upload
142
+ with st.sidebar:
143
+ st.subheader("Upload Documents")
144
+ pdf_docs = st.file_uploader(
145
+ "Upload your PDFs here and click 'Process'",
146
+ accept_multiple_files=True,
147
+ type=['pdf']
148
+ )
149
+
150
+ if st.button('Process'):
151
+ if not pdf_docs:
152
+ st.warning("Please upload at least one PDF document.")
153
+ return
154
+
155
+ with st.spinner("Processing documents..."):
156
+ try:
157
+ # Get PDF text
158
+ raw_text = get_pdf_text(pdf_docs)
159
+
160
+ # Get text chunks
161
+ text_chunks = get_text_chunks(raw_text)
162
+
163
+ # Create vector store
164
+ vectorstore = get_vector_store(text_chunks)
165
+
166
+ # Create conversation chain
167
+ st.session_state.conversation = get_conversation_chain(vectorstore)
168
+
169
+ st.success("Documents processed successfully!")
170
+ except Exception as e:
171
+ st.error(f"An error occurred: {str(e)}")
172
+
173
+ # Main chat interface
174
+ user_question = st.text_input("Ask a question about your documents:")
175
+ if user_question:
176
+ handle_user_input(user_question)
177
+
178
+ if __name__ == "__main__":
179
+ main()
src/htmlTemplates.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ css = '''
2
+ <style>
3
+ .chat-message {
4
+ padding: 1.5rem; border-radius: 0.5rem; margin-bottom: 1rem; display: flex
5
+ }
6
+ .chat-message.user {
7
+ background-color: #2b313e
8
+ }
9
+ .chat-message.bot {
10
+ background-color: #475063
11
+ }
12
+ .chat-message .avatar {
13
+ width: 20%;
14
+ }
15
+ .chat-message .avatar img {
16
+ max-width: 78px;
17
+ max-height: 78px;
18
+ border-radius: 50%;
19
+ object-fit: cover;
20
+ }
21
+ .chat-message .message {
22
+ width: 80%;
23
+ padding: 0 1.5rem;
24
+ color: #fff;
25
+ }
26
+ '''
27
+
28
+ bot_template = '''
29
+ <div class="chat-message bot">
30
+ <div class="avatar">
31
+ <img src="https://logos-world.net/wp-content/uploads/2020/02/Iron-Man-Logo-500x281.png">
32
+ </div>
33
+ <div class="message">{{MSG}}</div>
34
+ </div>
35
+ '''
36
+
37
+ user_template = '''
38
+ <div class="chat-message user">
39
+ <div class="avatar">
40
+ <img src="https://cdn.freebiesupply.com/logos/large/2x/spider-man-4-logo-png-transparent.png">
41
+ </div>
42
+ <div class="message">{{MSG}}</div>
43
+ </div>
44
+ '''