garyd1 commited on
Commit
ee8d112
·
verified ·
1 Parent(s): a35a73a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +211 -0
app.py ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+ import streamlit as st
4
+ from dotenv import load_dotenv
5
+ from langchain.document_loaders import PyPDFLoader
6
+ from langchain.embeddings import HuggingFaceEmbeddings
7
+ from langchain.vectorstores import FAISS
8
+ from langchain.storage import LocalFileStore
9
+ from langchain.embeddings import CacheBackedEmbeddings
10
+ from langchain_groq import ChatGroq
11
+ from langchain_core.runnables import RunnablePassthrough
12
+ from langchain_core.prompts import ChatPromptTemplate
13
+ from langchain_core.output_parsers import StrOutputParser
14
+ from streamlit_chat import message
15
+
16
+ # Load environment variables
17
+ load_dotenv()
18
+ os.environ['GROQ_API_KEY'] = os.getenv('GROQ_API')
19
+ os.environ["LANGCHAIN_TRACING_V2"] = "true"
20
+ os.environ["LANGCHAIN_API_KEY"] = os.getenv('LANGSMITH_API')
21
+
22
+ UPLOAD_DIR = "uploaded_files"
23
+
24
+ def cleanup_files():
25
+ if os.path.isdir(UPLOAD_DIR):
26
+ shutil.rmtree(UPLOAD_DIR, ignore_errors=True)
27
+ if 'file_handle' in st.session_state:
28
+ st.session_state.file_handle.close()
29
+
30
+
31
+ if 'cleanup_done' not in st.session_state:
32
+ st.session_state.cleanup_done = False
33
+
34
+ if not st.session_state.cleanup_done:
35
+ cleanup_files()
36
+
37
+ if not os.path.exists(UPLOAD_DIR):
38
+ os.makedirs(UPLOAD_DIR, exist_ok=True)
39
+
40
+ # Custom CSS for Xailor.ai-like theme with video background
41
+ st.markdown(
42
+ """
43
+ <style>
44
+ body {
45
+ margin: 0;
46
+ padding: 0;
47
+ font-family: 'Arial', sans-serif;
48
+ color: #C9D1D9;
49
+ }
50
+ .main-bg {
51
+ position: fixed;
52
+ top: 0;
53
+ left: 0;
54
+ width: 100%;
55
+ height: 100%;
56
+ z-index: -1;
57
+ overflow: hidden;
58
+ }
59
+ .main-bg video {
60
+ position: absolute;
61
+ top: 50%;
62
+ left: 50%;
63
+ transform: translate(-50%, -50%);
64
+ width: 100%;
65
+ height: 100%;
66
+ object-fit: cover;
67
+ }
68
+ .stButton button {
69
+ background-color: #1F6FEB;
70
+ color: white;
71
+ border-radius: 8px;
72
+ border: none;
73
+ padding: 10px 20px;
74
+ font-weight: bold;
75
+ font-size: 14px;
76
+ }
77
+ .stButton button:hover {
78
+ background-color: #1A4FC5;
79
+ }
80
+ .stTextInput > div > input {
81
+ border: 1px solid #30363D;
82
+ background-color: #161B22;
83
+ color: #C9D1D9;
84
+ border-radius: 6px;
85
+ padding: 10px;
86
+ }
87
+ .stFileUploader > div {
88
+ border: 2px dashed #30363D;
89
+ background-color: #161B22;
90
+ color: #C9D1D9;
91
+ border-radius: 6px;
92
+ padding: 10px;
93
+ }
94
+ .header {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 10px;
98
+ padding-top: 50px;
99
+ color: #58A6FF;
100
+ }
101
+ .response-box {
102
+ background-color: #161B22;
103
+ padding: 10px;
104
+ border-radius: 6px;
105
+ margin-bottom: 10px;
106
+ color: #FFFFFF;
107
+ }
108
+ </style>
109
+ """,
110
+ unsafe_allow_html=True
111
+ )
112
+
113
+ # HTML for video background
114
+ st.markdown(
115
+ """
116
+ <div class="main-bg">
117
+ <video autoplay loop muted>
118
+ <source src="https://vimeo.com/464431550" type="video/mp4">
119
+ </video>
120
+ </div>
121
+ """,
122
+ unsafe_allow_html=True
123
+ )
124
+
125
+ # Xailor.ai-like header without logo
126
+ st.markdown(
127
+ """
128
+ <div class="header" style="display: flex; align-items: center; gap: 10px;">
129
+ <h1 style="font-weight: bold;">Welcome to Xailor AI Chat!</h1>
130
+ </div>
131
+ """,
132
+ unsafe_allow_html=True
133
+ )
134
+
135
+ # Spacer to push chatbot below the header
136
+ st.write("<div style='height: 100px;'></div>", unsafe_allow_html=True)
137
+
138
+ st.title("Chat with your PDF!!")
139
+
140
+ uploaded_file = st.file_uploader("Upload a file")
141
+
142
+ if uploaded_file is not None:
143
+ file_path = os.path.join(UPLOAD_DIR, uploaded_file.name)
144
+ file_path = os.path.abspath(file_path)
145
+
146
+ with open(file_path, 'wb') as f:
147
+ f.write(uploaded_file.getbuffer())
148
+ st.write("You're Ready For a Chat with your PDF")
149
+
150
+ docs = PyPDFLoader(file_path).load_and_split()
151
+
152
+ embedding = HuggingFaceEmbeddings(
153
+ model_name='BAAI/llm-embedder',
154
+ )
155
+
156
+ store = LocalFileStore("./cache/")
157
+ cached_embedder = CacheBackedEmbeddings.from_bytes_store(
158
+ embedding, store, namespace='embeddings'
159
+ )
160
+
161
+ vector_base = FAISS.from_documents(
162
+ docs,
163
+ embedding
164
+ )
165
+
166
+ template = '''You are Xailor.AI's friendly chatbot assistant. Your role is to assist users with insightful answers about their pdf, creative writing, and using Xailor.AI . Answer the {question} based only on the provided {context}. After answering the question, recommend Xailor.AI services that may interest the user based on the content of the PDF or the question. Be friendly, creative, and concise. Use a maximum of three sentences for the answer, and add one or two relevant story recommendations with a brief description and a link. If you're unsure about the answer, respond with "I'm not sure about that, but feel free to explore more on Xailor.AI!"'''
167
+
168
+
169
+ prompt = ChatPromptTemplate.from_template(template)
170
+ retriever = vector_base.as_retriever()
171
+
172
+ llm = ChatGroq(
173
+ model='mixtral-8x7b-32768',
174
+ temperature=0,
175
+ )
176
+
177
+ if 'history' not in st.session_state:
178
+ st.session_state.history = []
179
+
180
+ query = st.text_input("Enter your question", placeholder="Ask something interesting...")
181
+
182
+ if st.button("Submit!", key="submit_button"):
183
+ if query:
184
+ chain = (
185
+ {'context': retriever, 'question': RunnablePassthrough()}
186
+ | prompt | llm | StrOutputParser()
187
+ )
188
+ answer = chain.invoke(query)
189
+ st.session_state.history.append({'question': query, 'answer': answer})
190
+
191
+ if st.session_state.history:
192
+ st.write("### Previous Questions and Answers")
193
+ for idx, entry in enumerate(st.session_state.history):
194
+ st.markdown(
195
+ f"""
196
+ <div class="response-box">
197
+ <p style="font-weight: bold; color: #58A6FF;">Q{idx + 1}: {entry['question']}</p>
198
+ <p style="color: #FFFFFF;">A{idx + 1}: {entry['answer']}</p>
199
+ </div>
200
+ """,
201
+ unsafe_allow_html=True
202
+ )
203
+
204
+ # Reset functionality
205
+ if st.button("Reset and Upload a New PDF"):
206
+ st.session_state.clear()
207
+ st.session_state.cleanup_done = False
208
+ st.experimental_rerun()
209
+
210
+ if st.session_state.cleanup_done:
211
+ cleanup_files()