absiitr commited on
Commit
921958d
Β·
verified Β·
1 Parent(s): 73eaaac

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -108
app.py CHANGED
@@ -16,12 +16,7 @@ logging.basicConfig(level=logging.INFO)
16
  GROQ_API_KEY = st.secrets.get("GROQ_API_KEY", os.environ.get("GROQ_API_KEY"))
17
  GROQ_MODEL = "llama-3.1-8b-instant"
18
 
19
- client = None
20
- if GROQ_API_KEY:
21
- try:
22
- client = Groq(api_key=GROQ_API_KEY)
23
- except Exception as e:
24
- st.error(e)
25
 
26
  # ---------------- PAGE CONFIG ----------------
27
  st.set_page_config(
@@ -30,124 +25,120 @@ st.set_page_config(
30
  layout="wide"
31
  )
32
 
33
- # ---------------- FORCE DARK UI (THEME INDEPENDENT) ----------------
34
  st.markdown("""
35
  <style>
 
36
  :root {
37
- --primary-color: #1e3a8a;
38
- --background-color: #0e1117;
39
- --secondary-background-color: #161b22;
40
- --text-color: #f0f2f6;
 
 
41
  }
42
 
43
  html, body, [data-testid="stAppViewContainer"], .main {
44
- background-color: #0e1117 !important;
45
- color: #f0f2f6 !important;
46
  }
47
 
48
- /* Hide Streamlit default UI */
49
- header[data-testid="stHeader"], footer {
50
- display: none;
51
- }
52
 
53
  /* Sidebar */
54
  [data-testid="stSidebar"] {
55
- background-color: #161b22 !important;
56
  width: 20rem;
57
- position: fixed;
58
- height: 100vh;
59
- overflow-y: auto;
60
  }
61
 
62
- /* Fixed header */
 
 
 
 
 
 
 
 
 
63
  .fixed-header {
64
  position: fixed;
65
  top: 0;
66
  left: 0;
67
- width: 100%;
68
  height: 6rem;
69
- background: #0e1117;
70
- z-index: 9999;
 
71
  display: flex;
72
  flex-direction: column;
73
  align-items: center;
74
  justify-content: center;
75
- border-bottom: 1px solid rgba(255,255,255,0.1);
76
- }
77
-
78
- .title-text {
79
- font-size: 2.5rem;
80
- font-weight: 800;
81
- }
82
-
83
- .creator-text {
84
- font-size: 1rem;
85
- color: #9ca3af;
86
  }
87
 
88
- .creator-text a {
89
- color: #4da6ff;
90
- text-decoration: none;
91
- }
92
 
93
- /* Main content spacing */
94
  .main .block-container {
95
  margin-top: 6rem;
96
- padding-bottom: 5rem;
97
  }
98
 
99
- /* Inputs */
100
  input, textarea {
101
- background-color: #1f2933 !important;
102
- color: #f0f2f6 !important;
103
- border: 1px solid #374151 !important;
 
 
 
 
 
 
 
 
104
  }
105
 
106
- /* Buttons */
107
  button {
108
- background-color: #1e3a8a !important;
 
109
  color: white !important;
110
- border-radius: 8px !important;
111
- font-weight: 600;
112
  }
113
 
114
- button:hover {
115
- background-color: #2563eb !important;
116
- }
117
 
118
  /* Chat bubbles */
119
  .chat-user {
120
  background: #2d3748;
121
- padding: 12px;
122
- border-radius: 10px 10px 2px 10px;
123
  margin: 6px 0 6px auto;
124
  max-width: 85%;
125
  text-align: right;
126
  }
127
 
128
  .chat-bot {
129
- background: #1e3a8a;
130
- padding: 12px;
131
- border-radius: 10px 10px 10px 2px;
132
  margin: 6px auto 6px 0;
133
  max-width: 85%;
134
  }
135
 
136
- /* Hide file list */
137
- [data-testid="stFileUploaderFile"],
138
- section[data-testid="stFileUploader"] ul,
139
- section[data-testid="stFileUploader"] small {
140
- display: none;
141
- }
142
-
143
- /* Scrollbar */
144
- *::-webkit-scrollbar {
145
- width: 8px;
146
- }
147
  *::-webkit-scrollbar-thumb {
148
  background: #2d3748;
149
  border-radius: 4px;
150
  }
 
 
 
151
  </style>
152
  """, unsafe_allow_html=True)
153
 
@@ -156,7 +147,7 @@ st.markdown("""
156
  <div class="fixed-header">
157
  <div class="title-text">πŸ“˜ PDF Assistant</div>
158
  <div class="creator-text">
159
- by <a href="https://www.linkedin.com/in/abhishek-iitr/" target="_blank">
160
  Abhishek Saxena</a>
161
  </div>
162
  </div>
@@ -192,53 +183,38 @@ def process_pdf(uploaded):
192
  tmp.write(uploaded.getvalue())
193
  path = tmp.name
194
 
195
- loader = PyPDFLoader(path)
196
- docs = loader.load()
197
-
198
- splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=60)
199
- chunks = splitter.split_documents(docs)
200
 
201
  embeddings = HuggingFaceEmbeddings(
202
  model_name="sentence-transformers/all-MiniLM-L6-v2",
203
- model_kwargs={"device": "cpu"},
204
  encode_kwargs={"normalize_embeddings": True}
205
  )
206
 
207
- vectorstore = Chroma.from_documents(chunks, embeddings)
208
- st.session_state.retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
209
  os.unlink(path)
210
 
211
- def ask(question):
212
- docs = st.session_state.retriever.invoke(question)
213
  context = "\n\n".join(d.page_content for d in docs)
214
 
215
- prompt = f"""
216
- You are a strict RAG assistant.
217
- Use ONLY the PDF content.
218
- If the answer is not found, say:
219
- "I cannot find this in the PDF."
220
-
221
- CONTEXT:
222
- {context}
223
-
224
- QUESTION:
225
- {question}
226
- """
227
-
228
  res = client.chat.completions.create(
229
  model=GROQ_MODEL,
230
- messages=[{"role": "user", "content": prompt}],
 
 
 
231
  temperature=0.1
232
  )
233
  return res.choices[0].message.content.strip()
234
 
235
  # ---------------- SIDEBAR ----------------
236
  with st.sidebar:
237
- if st.button("πŸ—‘οΈ Clear Chat History", use_container_width=True):
238
- clear_chat()
239
- if st.button("πŸ”₯ Clear PDF Memory", use_container_width=True):
240
- clear_memory()
241
- st.success("Memory cleared")
242
 
243
  st.markdown("---")
244
 
@@ -262,8 +238,8 @@ with st.sidebar:
262
  # ---------------- INPUT ----------------
263
  disabled = not st.session_state.uploaded_file_name or not client
264
 
265
- with st.form(key="chat_form", clear_on_submit=True):
266
- col1, col2 = st.columns([0.85, 0.15])
267
  with col1:
268
  question = st.text_input(
269
  "",
@@ -276,13 +252,10 @@ with st.form(key="chat_form", clear_on_submit=True):
276
  if send and question:
277
  st.session_state.messages.append(("user", question))
278
  with st.spinner("Thinking..."):
279
- answer = ask(question)
280
- st.session_state.messages.append(("bot", answer))
281
  st.rerun()
282
 
283
- # ---------------- CHAT HISTORY ----------------
284
  for role, msg in reversed(st.session_state.messages):
285
- if role == "user":
286
- st.markdown(f"<div class='chat-user'>{msg}</div>", unsafe_allow_html=True)
287
- else:
288
- st.markdown(f"<div class='chat-bot'>{msg}</div>", unsafe_allow_html=True)
 
16
  GROQ_API_KEY = st.secrets.get("GROQ_API_KEY", os.environ.get("GROQ_API_KEY"))
17
  GROQ_MODEL = "llama-3.1-8b-instant"
18
 
19
+ client = Groq(api_key=GROQ_API_KEY) if GROQ_API_KEY else None
 
 
 
 
 
20
 
21
  # ---------------- PAGE CONFIG ----------------
22
  st.set_page_config(
 
25
  layout="wide"
26
  )
27
 
28
+ # ---------------- FORCE DARK UI ----------------
29
  st.markdown("""
30
  <style>
31
+ /* ================= FORCE DARK THEME ================= */
32
  :root {
33
+ --bg: #0e1117;
34
+ --sidebar: #161b22;
35
+ --input: #1f2933;
36
+ --border: #374151;
37
+ --text: #f0f2f6;
38
+ --primary: #1e3a8a;
39
  }
40
 
41
  html, body, [data-testid="stAppViewContainer"], .main {
42
+ background-color: var(--bg) !important;
43
+ color: var(--text) !important;
44
  }
45
 
46
+ /* Hide Streamlit chrome */
47
+ header[data-testid="stHeader"], footer { display: none; }
 
 
48
 
49
  /* Sidebar */
50
  [data-testid="stSidebar"] {
51
+ background-color: var(--sidebar) !important;
52
  width: 20rem;
 
 
 
53
  }
54
 
55
+ /* FIX: File uploader white background */
56
+ section[data-testid="stFileUploader"],
57
+ section[data-testid="stFileUploader"] > div,
58
+ section[data-testid="stFileUploader"] label {
59
+ background-color: var(--sidebar) !important;
60
+ color: var(--text) !important;
61
+ border-radius: 12px;
62
+ }
63
+
64
+ /* Fixed Header */
65
  .fixed-header {
66
  position: fixed;
67
  top: 0;
68
  left: 0;
 
69
  height: 6rem;
70
+ width: 100%;
71
+ background: var(--bg);
72
+ border-bottom: 1px solid rgba(255,255,255,0.08);
73
  display: flex;
74
  flex-direction: column;
75
  align-items: center;
76
  justify-content: center;
77
+ z-index: 9999;
 
 
 
 
 
 
 
 
 
 
78
  }
79
 
80
+ .title-text { font-size: 2.5rem; font-weight: 800; }
81
+ .creator-text { color: #9ca3af; }
 
 
82
 
83
+ /* Main spacing */
84
  .main .block-container {
85
  margin-top: 6rem;
86
+ padding-bottom: 6rem;
87
  }
88
 
89
+ /* ================= INPUT + BUTTON ALIGNMENT ================= */
90
  input, textarea {
91
+ background-color: var(--input) !important;
92
+ color: var(--text) !important;
93
+ border: 1px solid var(--border) !important;
94
+ height: 3.2rem !important;
95
+ border-radius: 10px !important;
96
+ }
97
+
98
+ /* Placeholder FIX (same in light & dark) */
99
+ input::placeholder {
100
+ color: #9ca3af !important;
101
+ opacity: 1 !important;
102
  }
103
 
104
+ /* Button (Arrow) */
105
  button {
106
+ height: 3.2rem !important;
107
+ background-color: var(--primary) !important;
108
  color: white !important;
109
+ border-radius: 10px !important;
110
+ font-weight: 700 !important;
111
  }
112
 
113
+ button:hover { background-color: #2563eb !important; }
 
 
114
 
115
  /* Chat bubbles */
116
  .chat-user {
117
  background: #2d3748;
118
+ padding: 14px;
119
+ border-radius: 12px 12px 2px 12px;
120
  margin: 6px 0 6px auto;
121
  max-width: 85%;
122
  text-align: right;
123
  }
124
 
125
  .chat-bot {
126
+ background: var(--primary);
127
+ padding: 14px;
128
+ border-radius: 12px 12px 12px 2px;
129
  margin: 6px auto 6px 0;
130
  max-width: 85%;
131
  }
132
 
133
+ /* Scrollbars */
134
+ *::-webkit-scrollbar { width: 8px; }
 
 
 
 
 
 
 
 
 
135
  *::-webkit-scrollbar-thumb {
136
  background: #2d3748;
137
  border-radius: 4px;
138
  }
139
+
140
+ /* Hide uploaded filename */
141
+ [data-testid="stFileUploaderFile"] { display: none; }
142
  </style>
143
  """, unsafe_allow_html=True)
144
 
 
147
  <div class="fixed-header">
148
  <div class="title-text">πŸ“˜ PDF Assistant</div>
149
  <div class="creator-text">
150
+ by <a href="https://www.linkedin.com/in/abhishek-iitr/" target="_blank" style="color:#4da6ff">
151
  Abhishek Saxena</a>
152
  </div>
153
  </div>
 
183
  tmp.write(uploaded.getvalue())
184
  path = tmp.name
185
 
186
+ docs = PyPDFLoader(path).load()
187
+ chunks = RecursiveCharacterTextSplitter(
188
+ chunk_size=800, chunk_overlap=60
189
+ ).split_documents(docs)
 
190
 
191
  embeddings = HuggingFaceEmbeddings(
192
  model_name="sentence-transformers/all-MiniLM-L6-v2",
 
193
  encode_kwargs={"normalize_embeddings": True}
194
  )
195
 
196
+ vs = Chroma.from_documents(chunks, embeddings)
197
+ st.session_state.retriever = vs.as_retriever(search_kwargs={"k": 5})
198
  os.unlink(path)
199
 
200
+ def ask(q):
201
+ docs = st.session_state.retriever.invoke(q)
202
  context = "\n\n".join(d.page_content for d in docs)
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  res = client.chat.completions.create(
205
  model=GROQ_MODEL,
206
+ messages=[{
207
+ "role": "user",
208
+ "content": f"Use ONLY the PDF content.\n\n{context}\n\nQuestion: {q}"
209
+ }],
210
  temperature=0.1
211
  )
212
  return res.choices[0].message.content.strip()
213
 
214
  # ---------------- SIDEBAR ----------------
215
  with st.sidebar:
216
+ st.button("πŸ—‘οΈ Clear Chat History", on_click=clear_chat, use_container_width=True)
217
+ st.button("πŸ”₯ Clear PDF Memory", on_click=clear_memory, use_container_width=True)
 
 
 
218
 
219
  st.markdown("---")
220
 
 
238
  # ---------------- INPUT ----------------
239
  disabled = not st.session_state.uploaded_file_name or not client
240
 
241
+ with st.form("chat_form", clear_on_submit=True):
242
+ col1, col2 = st.columns([0.9, 0.1])
243
  with col1:
244
  question = st.text_input(
245
  "",
 
252
  if send and question:
253
  st.session_state.messages.append(("user", question))
254
  with st.spinner("Thinking..."):
255
+ st.session_state.messages.append(("bot", ask(question)))
 
256
  st.rerun()
257
 
258
+ # ---------------- CHAT ----------------
259
  for role, msg in reversed(st.session_state.messages):
260
+ css = "chat-user" if role == "user" else "chat-bot"
261
+ st.markdown(f"<div class='{css}'>{msg}</div>", unsafe_allow_html=True)