Nahiyan14 commited on
Commit
ecea8df
·
verified ·
1 Parent(s): f80cc11

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +154 -29
app.py CHANGED
@@ -91,9 +91,57 @@ def get_remaining_queries(user_id):
91
  st.set_page_config(
92
  page_title="USMLE Step 1 AI",
93
  page_icon="🩺",
94
- layout="centered"
 
95
  )
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  # Initialize session state for chat history
98
  if 'messages' not in st.session_state:
99
  st.session_state.messages = []
@@ -101,17 +149,57 @@ if 'messages' not in st.session_state:
101
  # Initialize rate limiting
102
  init_rate_limiting()
103
 
104
- # Display remaining queries
105
- user_id = get_user_id()
106
- remaining_queries = get_remaining_queries(user_id)
107
- st.sidebar.write(f"Remaining queries today: {remaining_queries}/{MAX_REQUESTS_PER_DAY}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  # Check for API keys
110
  PINECONE_API_KEY = os.environ.get('PINECONE_API_KEY')
111
  OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
112
 
113
  if not PINECONE_API_KEY or not OPENAI_API_KEY:
114
- st.error("Missing API keys. Please set PINECONE_API_KEY and OPENAI_API_KEY environment variables.")
115
  st.stop()
116
 
117
  os.environ["PINECONE_API_KEY"] = PINECONE_API_KEY
@@ -121,19 +209,30 @@ os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
121
  @st.cache_resource
122
  def initialize_rag_chain():
123
  try:
124
- st.sidebar.write("Loading embeddings model...")
 
 
 
 
125
  embeddings = download_hugging_face_embeddings()
 
126
 
127
- st.sidebar.write("Connecting to Pinecone...")
 
128
  index_name = "medprep"
129
  docsearch = Pinecone.from_existing_index(
130
  index_name=index_name,
131
  embedding=embeddings
132
  )
 
133
 
 
 
134
  retriever = docsearch.as_retriever(search_type="similarity", search_kwargs={"k": 3})
 
135
 
136
- st.sidebar.write("Initializing OpenAI...")
 
137
  llm = OpenAI(temperature=0.4, max_tokens=500)
138
 
139
  prompt = ChatPromptTemplate.from_messages([
@@ -143,66 +242,92 @@ def initialize_rag_chain():
143
 
144
  question_answer_chain = create_stuff_documents_chain(llm, prompt)
145
  rag_chain = create_retrieval_chain(retriever, question_answer_chain)
 
 
 
 
 
146
 
147
  st.sidebar.success("✅ System initialized successfully!")
148
  return rag_chain
149
  except Exception as e:
150
- st.sidebar.error(f"Error initializing system: {str(e)}")
151
  import traceback
152
  st.sidebar.text(traceback.format_exc())
153
  return None
154
 
155
- # Main app title
156
- st.title("First AID USMLE Step 1")
157
- st.write("Ask me any question from First AID USMLE Step 1 book, and I'll try to help!")
158
 
159
  # Initialize the RAG chain
160
  rag_chain = initialize_rag_chain()
161
 
162
  if rag_chain is None:
163
- st.error("Failed to initialize the system. Please check the sidebar for error details.")
164
  st.stop()
165
 
166
- # Display chat history
167
- for message in st.session_state.messages:
 
168
  with st.chat_message(message["role"]):
169
- st.markdown(message["content"])
170
 
171
  # Get user input
172
- if prompt := st.chat_input("Ask a question..."):
173
  # Add user message to chat history
174
  st.session_state.messages.append({"role": "user", "content": prompt})
175
 
176
  # Display user message
177
  with st.chat_message("user"):
178
- st.markdown(prompt)
179
 
180
  # Check rate limit
181
  user_id = get_user_id()
182
  allowed, count = check_rate_limit(user_id)
183
 
184
  if not allowed:
185
- response = f"⚠️ Daily limit reached. You've used {count} queries today. Please try again tomorrow."
186
  else:
187
  # Process the query with the RAG chain
188
  with st.chat_message("assistant"):
189
- with st.spinner("Thinking..."):
 
 
190
  try:
191
  result = rag_chain.invoke({"input": prompt})
192
  response = result.get("answer", "Sorry, I couldn't find an answer to that.")
 
 
193
  remaining = MAX_REQUESTS_PER_DAY - count
194
- response += f"\n\n\n_You have {remaining} queries remaining today._"
 
 
 
 
 
 
 
195
  except Exception as e:
196
- response = f"Error processing your request: {str(e)}"
197
 
198
- st.markdown(response)
199
 
200
  # Add assistant response to chat history
201
  st.session_state.messages.append({"role": "assistant", "content": response})
202
 
203
- # Footer
204
  st.markdown("---")
205
- # Footer
206
- st.markdown("---")
207
- st.markdown("""*This AI assistant uses retrieval augmented generation to provide information from First Aid USMLE Step 1 content.
208
- It's designed to help with studying, but should not replace professional medical advice.*""")
 
 
 
 
 
 
 
 
 
 
91
  st.set_page_config(
92
  page_title="USMLE Step 1 AI",
93
  page_icon="🩺",
94
+ layout="centered",
95
+ initial_sidebar_state="expanded"
96
  )
97
 
98
+ # Apply custom CSS for better visual appearance
99
+ st.markdown("""
100
+ <style>
101
+ .main-header {
102
+ font-size: 2.5rem !important;
103
+ margin-bottom: 1rem !important;
104
+ color: #2c3e50;
105
+ }
106
+ .sub-header {
107
+ font-size: 1.2rem !important;
108
+ color: #34495e;
109
+ margin-bottom: 2rem !important;
110
+ }
111
+ .stAlert {
112
+ padding: 15px !important;
113
+ border-radius: 8px !important;
114
+ }
115
+ .usage-metric {
116
+ padding: 10px;
117
+ background-color: #f8f9fa;
118
+ border-radius: 8px;
119
+ margin-bottom: 15px;
120
+ border-left: 5px solid #4CAF50;
121
+ }
122
+ .usage-metric-warning {
123
+ border-left: 5px solid #FFC107;
124
+ }
125
+ .usage-metric-danger {
126
+ border-left: 5px solid #F44336;
127
+ }
128
+ .footer-text {
129
+ font-size: 0.85rem !important;
130
+ color: #7f8c8d;
131
+ }
132
+ .stChatMessage div[data-testid="stChatMessageContent"] {
133
+ border-radius: 15px !important;
134
+ padding: 15px !important;
135
+ }
136
+ .user-message {
137
+ background-color: #f1f8ff !important;
138
+ }
139
+ .assistant-message {
140
+ background-color: #f9f9f9 !important;
141
+ }
142
+ </style>
143
+ """, unsafe_allow_html=True)
144
+
145
  # Initialize session state for chat history
146
  if 'messages' not in st.session_state:
147
  st.session_state.messages = []
 
149
  # Initialize rate limiting
150
  init_rate_limiting()
151
 
152
+ # Sidebar content
153
+ with st.sidebar:
154
+ st.image("https://img.icons8.com/color/96/000000/caduceus.png", width=80)
155
+ st.markdown("### USMLE Step 1 Assistant")
156
+ st.markdown("---")
157
+
158
+ # Display remaining queries with visual indicator
159
+ user_id = get_user_id()
160
+ remaining_queries = get_remaining_queries(user_id)
161
+
162
+ # Determine styling based on remaining queries
163
+ usage_class = "usage-metric"
164
+ if remaining_queries <= 2:
165
+ usage_class += " usage-metric-danger"
166
+ elif remaining_queries <= 3:
167
+ usage_class += " usage-metric-warning"
168
+
169
+ st.markdown(f"""
170
+ <div class="{usage_class}">
171
+ <strong>Daily Usage</strong><br>
172
+ {remaining_queries}/{MAX_REQUESTS_PER_DAY} queries remaining
173
+ </div>
174
+ """, unsafe_allow_html=True)
175
+
176
+ # Help section in sidebar
177
+ with st.expander("ℹ️ How to use"):
178
+ st.markdown("""
179
+ 1. Type your USMLE Step 1 question in the chat input
180
+ 2. The AI will search First Aid content and respond
181
+ 3. You have 5 queries per day
182
+
183
+ **Best for:**
184
+ - Fact checking First Aid content
185
+ - Understanding complex topics
186
+ - Quick reference during study
187
+ """)
188
+
189
+ with st.expander("🔍 Example Questions"):
190
+ st.markdown("""
191
+ - "Explain the Krebs cycle"
192
+ - "What are the symptoms of Parkinson's disease?"
193
+ - "Differentiate between type 1 and type 2 diabetes"
194
+ - "What antibiotics are used for MRSA?"
195
+ """)
196
 
197
  # Check for API keys
198
  PINECONE_API_KEY = os.environ.get('PINECONE_API_KEY')
199
  OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
200
 
201
  if not PINECONE_API_KEY or not OPENAI_API_KEY:
202
+ st.error("⚠️ Missing API keys. Please set PINECONE_API_KEY and OPENAI_API_KEY environment variables.")
203
  st.stop()
204
 
205
  os.environ["PINECONE_API_KEY"] = PINECONE_API_KEY
 
209
  @st.cache_resource
210
  def initialize_rag_chain():
211
  try:
212
+ progress_text = st.sidebar.empty()
213
+ progress_bar = st.sidebar.progress(0)
214
+
215
+ # Step 1: Load embeddings
216
+ progress_text.text("Loading embeddings model... (1/4)")
217
  embeddings = download_hugging_face_embeddings()
218
+ progress_bar.progress(25)
219
 
220
+ # Step 2: Connect to Pinecone
221
+ progress_text.text("Connecting to Pinecone database... (2/4)")
222
  index_name = "medprep"
223
  docsearch = Pinecone.from_existing_index(
224
  index_name=index_name,
225
  embedding=embeddings
226
  )
227
+ progress_bar.progress(50)
228
 
229
+ # Step 3: Set up retriever
230
+ progress_text.text("Setting up retrieval system... (3/4)")
231
  retriever = docsearch.as_retriever(search_type="similarity", search_kwargs={"k": 3})
232
+ progress_bar.progress(75)
233
 
234
+ # Step 4: Initialize LLM and chain
235
+ progress_text.text("Initializing language model... (4/4)")
236
  llm = OpenAI(temperature=0.4, max_tokens=500)
237
 
238
  prompt = ChatPromptTemplate.from_messages([
 
242
 
243
  question_answer_chain = create_stuff_documents_chain(llm, prompt)
244
  rag_chain = create_retrieval_chain(retriever, question_answer_chain)
245
+ progress_bar.progress(100)
246
+
247
+ # Clean up progress indicators
248
+ progress_text.empty()
249
+ progress_bar.empty()
250
 
251
  st.sidebar.success("✅ System initialized successfully!")
252
  return rag_chain
253
  except Exception as e:
254
+ st.sidebar.error(f"⚠️ Error initializing system: {str(e)}")
255
  import traceback
256
  st.sidebar.text(traceback.format_exc())
257
  return None
258
 
259
+ # Main app content
260
+ st.markdown('<h1 class="main-header">First Aid USMLE Step 1 Assistant</h1>', unsafe_allow_html=True)
261
+ st.markdown('<p class="sub-header">Ask me any question from First Aid USMLE Step 1 book, and I\'ll try to help!</p>', unsafe_allow_html=True)
262
 
263
  # Initialize the RAG chain
264
  rag_chain = initialize_rag_chain()
265
 
266
  if rag_chain is None:
267
+ st.error("⚠️ Failed to initialize the system. Please check the sidebar for error details.")
268
  st.stop()
269
 
270
+ # Display chat history with improved styling
271
+ for i, message in enumerate(st.session_state.messages):
272
+ message_class = "user-message" if message["role"] == "user" else "assistant-message"
273
  with st.chat_message(message["role"]):
274
+ st.markdown(f'<div class="{message_class}">{message["content"]}</div>', unsafe_allow_html=True)
275
 
276
  # Get user input
277
+ if prompt := st.chat_input("Ask a USMLE Step 1 question..."):
278
  # Add user message to chat history
279
  st.session_state.messages.append({"role": "user", "content": prompt})
280
 
281
  # Display user message
282
  with st.chat_message("user"):
283
+ st.markdown(f'<div class="user-message">{prompt}</div>', unsafe_allow_html=True)
284
 
285
  # Check rate limit
286
  user_id = get_user_id()
287
  allowed, count = check_rate_limit(user_id)
288
 
289
  if not allowed:
290
+ response = f"⚠️ **Daily limit reached**\n\nYou've used {count} queries today. Please try again tomorrow."
291
  else:
292
  # Process the query with the RAG chain
293
  with st.chat_message("assistant"):
294
+ message_placeholder = st.empty()
295
+
296
+ with st.spinner("Searching First Aid content..."):
297
  try:
298
  result = rag_chain.invoke({"input": prompt})
299
  response = result.get("answer", "Sorry, I couldn't find an answer to that.")
300
+
301
+ # Format the remaining queries notification
302
  remaining = MAX_REQUESTS_PER_DAY - count
303
+ if remaining <= 1:
304
+ usage_note = f"⚠️ **{remaining} query remaining today**"
305
+ else:
306
+ usage_note = f"ℹ️ {remaining} queries remaining today"
307
+
308
+ # Add a separator and the usage note
309
+ response += f"\n\n---\n\n{usage_note}"
310
+
311
  except Exception as e:
312
+ response = f"⚠️ **Error processing your request**\n\n{str(e)}"
313
 
314
+ message_placeholder.markdown(f'<div class="assistant-message">{response}</div>', unsafe_allow_html=True)
315
 
316
  # Add assistant response to chat history
317
  st.session_state.messages.append({"role": "assistant", "content": response})
318
 
319
+ # Footer with improved styling
320
  st.markdown("---")
321
+ st.markdown("""
322
+ <div class="footer-text">
323
+ <p><strong>About this assistant</strong></p>
324
+ <p>This AI assistant uses retrieval augmented generation to provide information from First Aid USMLE Step 1 content.
325
+ It's designed to help with studying, but should not replace professional medical advice.</p>
326
+ <p>© 2025 USMLE Step 1 Assistant</p>
327
+ </div>
328
+ """, unsafe_allow_html=True)
329
+
330
+ # Add a reset button at the bottom
331
+ if st.button("Clear Conversation"):
332
+ st.session_state.messages = []
333
+ st.experimental_rerun()