JirasakJo commited on
Commit
65d5ffc
·
verified ·
1 Parent(s): d0861f4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +235 -69
app.py CHANGED
@@ -14,56 +14,61 @@ def load_custom_css():
14
  <style>
15
  /* General body styling */
16
  body {
17
- font-family: "Arial", sans-serif !important;
18
- color: #000000 !important;
19
  background-color: white !important;
20
- line-height: 1.7 !important;
21
  }
22
 
23
  /* Main container styling */
24
  .main {
25
  padding: 2rem;
26
- background-color: #F9FAFB;
 
27
  }
28
 
29
  /* Headers styling */
30
  h1 {
31
- color: #1E40AF;
32
- font-size: 2.5rem !important;
33
  font-weight: 700 !important;
 
34
  text-align: center;
35
- border-bottom: 2px solid #1E40AF;
36
- padding-bottom: 0.5rem;
37
  }
38
 
39
  h3, h4 {
40
- color: #1F2937;
41
  font-weight: 600 !important;
42
- font-size: 1.5rem !important;
 
43
  }
44
 
45
  /* Paragraphs and text */
46
  p, span, li {
47
- font-size: 1.1rem !important;
48
- color: #374151 !important;
49
  }
50
 
51
  /* Chat message styling */
52
  .chat-message {
53
- padding: 1rem;
54
- border-radius: 8px;
55
  margin: 1rem 0;
 
56
  font-size: 1.1rem !important;
57
- line-height: 1.6 !important;
58
- color: #374151 !important;
 
59
  }
60
 
61
  .user-message {
62
- background-color: #E5E7EB;
63
  }
64
 
65
  .assistant-message {
66
- background-color: #E0F2FE;
67
  }
68
 
69
  /* Input field styling */
@@ -72,26 +77,26 @@ def load_custom_css():
72
  border: 2px solid #E5E7EB;
73
  padding: 0.75rem;
74
  font-size: 1.1rem;
75
- color: #111827;
 
76
  }
77
 
78
  .stTextInput input:focus {
79
- border-color: #1E40AF;
80
- box-shadow: 0 0 0 2px rgba(30, 64, 175, 0.3);
81
  }
82
 
83
  /* Button styling */
84
  .stButton button {
85
  border-radius: 8px;
86
  font-weight: 600;
87
- font-size: 1.2rem !important;
88
- color: #ffffff;
89
- background-color: #1E40AF;
90
  transition: all 0.2s ease;
91
  }
92
 
93
  .stButton button:hover {
94
- transform: translateY(-2px);
95
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
96
  }
97
 
@@ -99,9 +104,28 @@ def load_custom_css():
99
  ul {
100
  font-size: 1.2rem !important;
101
  margin-left: 1rem;
102
- color: #374151;
103
  list-style-type: disc;
104
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  </style>
106
  """, unsafe_allow_html=True)
107
 
@@ -110,6 +134,7 @@ st.set_page_config(
110
  page_title="Academic Calendar Assistant",
111
  page_icon="📅",
112
  layout="wide",
 
113
  )
114
 
115
  # Load custom CSS
@@ -118,10 +143,10 @@ load_custom_css()
118
  # Initialize session state
119
  if 'pipeline' not in st.session_state:
120
  st.session_state.pipeline = None
121
-
122
  if 'chat_history' not in st.session_state:
123
  st.session_state.chat_history = []
124
-
125
  if 'feedback_data' not in st.session_state:
126
  st.session_state.feedback_data = []
127
 
@@ -145,70 +170,211 @@ def initialize_pipeline():
145
  st.error(f"Error initializing pipeline: {str(e)}")
146
  return None
147
 
148
- def add_to_history(role: str, message: str):
149
- """Add message to chat history"""
150
- st.session_state.chat_history.append((role, message))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
  def display_chat_history():
153
  """Display chat history with enhanced styling"""
154
- for role, message in st.session_state.chat_history:
155
- style_class = "user-message" if role == "user" else "assistant-message"
156
- st.markdown(f"""
157
- <div class="chat-message {style_class}">
158
- <strong>{'🧑 คำถาม:' if role == 'user' else '🤖 คำตอบ:'}</strong><br>
159
- {message}
160
- </div>
161
- """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  def main():
164
- # Header
165
  st.markdown("""
166
- <div style="text-align: center;">
167
- <h1>🎓 Academic Calendar Assistant</h1>
168
  </div>
169
  """, unsafe_allow_html=True)
170
 
171
  # Initialize pipeline if needed
172
  if st.session_state.pipeline is None:
173
- with st.spinner("Initializing system..."):
174
  st.session_state.pipeline = initialize_pipeline()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
- # Two-column layout
177
- chat_col, info_col = st.columns([2, 1])
 
 
 
 
 
 
178
 
179
- with chat_col:
180
- # Chat interface
181
- display_chat_history()
182
- query = st.text_input("Enter your question about the academic calendar:", placeholder="e.g., What is the last day of exams for Term 1, 2023?")
183
-
184
- if st.button("Send"):
185
- if not query:
186
- st.warning("Please enter a question.")
187
- else:
188
  add_to_history("user", query)
 
189
  try:
190
- with st.spinner("Searching for answers..."):
191
  result = st.session_state.pipeline.process_query(query)
192
  add_to_history("assistant", result["answer"])
193
- st.experimental_rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  except Exception as e:
195
- st.error(f"Error: {str(e)}")
196
-
 
 
 
197
  with info_col:
198
- # System info
199
  st.markdown("""
200
- <div style="background-color: #E5E7EB; padding: 1rem; border-radius: 8px;">
201
- <h3>About the System</h3>
202
- <p>This system uses <strong>Retrieval-Augmented Generation (RAG)</strong> to answer questions about academic calendars.</p>
203
- <ul>
204
- <li>📅 Event schedules</li>
205
- <li>🎯 Important dates</li>
206
- <li>📝 Registration deadlines</li>
207
- <li>📚 Exam schedules</li>
208
- <li>🏖️ Holidays</li>
 
 
 
 
209
  </ul>
210
  </div>
211
  """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
 
213
  if __name__ == "__main__":
214
- main()
 
14
  <style>
15
  /* General body styling */
16
  body {
17
+ font-family: "Arial", sans-serif !important; /* Clean and readable font */
18
+ color: #000000 !important; /* Black text */
19
  background-color: white !important;
20
+ line-height: 1.7 !important; /* Increase line spacing */
21
  }
22
 
23
  /* Main container styling */
24
  .main {
25
  padding: 2rem;
26
+ color: #000000; /* Ensure all text is black */
27
+ background-color: white;
28
  }
29
 
30
  /* Headers styling */
31
  h1 {
32
+ color: #000000; /* Black headers */
33
+ font-size: 2.8rem !important; /* Larger font for headers */
34
  font-weight: 700 !important;
35
+ margin-bottom: 1.5rem !important;
36
  text-align: center;
37
+ padding: 1rem 0;
38
+ border-bottom: 3px solid #1E3A8A; /* Keep a blue line for a clean design */
39
  }
40
 
41
  h3, h4 {
42
+ color: #000000; /* Black sub-headers */
43
  font-weight: 600 !important;
44
+ font-size: 1.6rem !important; /* Increase font size for sub-headers */
45
+ margin-top: 1.5rem !important;
46
  }
47
 
48
  /* Paragraphs and text */
49
  p, span, li {
50
+ font-size: 1.2rem !important; /* Larger font size for regular text */
51
+ color: #000000 !important; /* Black text */
52
  }
53
 
54
  /* Chat message styling */
55
  .chat-message {
56
+ padding: 1.5rem;
57
+ border-radius: 10px;
58
  margin: 1rem 0;
59
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
60
  font-size: 1.1rem !important;
61
+ line-height: 1.6 !important; /* Better readability */
62
+ font-family: "Arial", sans-serif !important;
63
+ color: #000000 !important; /* Black text in chat */
64
  }
65
 
66
  .user-message {
67
+ background-color: #F3F4F6 !important;
68
  }
69
 
70
  .assistant-message {
71
+ background-color: #EFF6FF !important;
72
  }
73
 
74
  /* Input field styling */
 
77
  border: 2px solid #E5E7EB;
78
  padding: 0.75rem;
79
  font-size: 1.1rem;
80
+ font-family: "Arial", sans-serif !important;
81
+ color: #000000; /* Black input text */
82
  }
83
 
84
  .stTextInput input:focus {
85
+ border-color: #1E3A8A;
86
+ box-shadow: 0 0 0 2px rgba(30, 58, 138, 0.1);
87
  }
88
 
89
  /* Button styling */
90
  .stButton button {
91
  border-radius: 8px;
92
  font-weight: 600;
93
+ font-size: 1.2rem !important; /* Bigger buttons for better interaction */
94
+ color: #000000; /* Black text on buttons */
 
95
  transition: all 0.2s ease;
96
  }
97
 
98
  .stButton button:hover {
99
+ transform: translateY(-1px);
100
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
101
  }
102
 
 
104
  ul {
105
  font-size: 1.2rem !important;
106
  margin-left: 1rem;
107
+ color: #000000; /* Black text in lists */
108
  list-style-type: disc;
109
  }
110
+
111
+ /* Status indicator styling */
112
+ .status-indicator {
113
+ padding: 0.5rem 1rem;
114
+ border-radius: 6px;
115
+ font-weight: 500;
116
+ font-size: 1.2rem; /* Larger for better clarity */
117
+ color: #000000; /* Black text for status */
118
+ }
119
+
120
+ .status-online {
121
+ background-color: #DEF7EC;
122
+ color: #03543F;
123
+ }
124
+
125
+ .status-offline {
126
+ background-color: #FDE8E8;
127
+ color: #9B1C1C;
128
+ }
129
  </style>
130
  """, unsafe_allow_html=True)
131
 
 
134
  page_title="Academic Calendar Assistant",
135
  page_icon="📅",
136
  layout="wide",
137
+ initial_sidebar_state="collapsed"
138
  )
139
 
140
  # Load custom CSS
 
143
  # Initialize session state
144
  if 'pipeline' not in st.session_state:
145
  st.session_state.pipeline = None
146
+
147
  if 'chat_history' not in st.session_state:
148
  st.session_state.chat_history = []
149
+
150
  if 'feedback_data' not in st.session_state:
151
  st.session_state.feedback_data = []
152
 
 
170
  st.error(f"Error initializing pipeline: {str(e)}")
171
  return None
172
 
173
+ def save_feedback_to_json():
174
+ """Save feedback data to a JSON file"""
175
+ try:
176
+ # Get current directory
177
+ current_dir = os.path.dirname(os.path.abspath(__file__))
178
+ file_path = os.path.join(current_dir, 'feedback_data.json')
179
+
180
+ # Log the attempt
181
+ st.write(f"Attempting to save feedback to: {file_path}")
182
+
183
+ # Create directory if it doesn't exist
184
+ os.makedirs(current_dir, exist_ok=True)
185
+
186
+ # Save the file
187
+ with open(file_path, "w", encoding="utf-8") as f:
188
+ json.dump(
189
+ st.session_state.feedback_data,
190
+ f,
191
+ ensure_ascii=False,
192
+ indent=2
193
+ )
194
+
195
+ # Verify file was created
196
+ if os.path.exists(file_path):
197
+ st.write(f"✅ Feedback saved successfully to {file_path}")
198
+ st.write(f"Current feedback data: {st.session_state.feedback_data}")
199
+ return True
200
+ else:
201
+ st.error("File was not created despite no errors")
202
+ return False
203
+
204
+ except Exception as e:
205
+ st.error(f"Error saving feedback: {str(e)}")
206
+ st.write(f"Current directory: {current_dir}")
207
+ st.write(f"Current feedback data: {st.session_state.feedback_data}")
208
+ return False
209
+
210
+ def add_feedback(query: str, answer: str, is_correct: bool):
211
+ """Add feedback entry to session state and save to JSON"""
212
+ feedback_entry = {
213
+ "timestamp": datetime.now().isoformat(),
214
+ "query": query,
215
+ "answer": answer,
216
+ "is_correct": is_correct
217
+ }
218
+ st.session_state.feedback_data.append(feedback_entry)
219
+ save_feedback_to_json()
220
+
221
+ def evaluate_answer(query: str, answer: str):
222
+ """Display evaluation buttons for the answer"""
223
+ col1, col2, col3 = st.columns([1, 1, 4])
224
+
225
+ with col1:
226
+ if st.button("✅ ถูกต้อง", type="primary", key=f"correct_{len(st.session_state.chat_history)}"):
227
+ add_feedback(query, answer, True)
228
+ st.success("บันทึกผลการประเมินแล้ว")
229
+ return True
230
+
231
+ with col2:
232
+ if st.button("❌ ไม่ถูกต้อง", type="secondary", key=f"incorrect_{len(st.session_state.chat_history)}"):
233
+ add_feedback(query, answer, False)
234
+ st.error("บันทึกผลการประเมินแล้ว")
235
+ return True
236
+
237
+ return False
238
 
239
  def display_chat_history():
240
  """Display chat history with enhanced styling"""
241
+ for i, (role, message) in enumerate(st.session_state.chat_history):
242
+ if role == "user":
243
+ st.markdown(f"""
244
+ <div class="chat-message user-message">
245
+ <strong>🧑 คำถาม:</strong><br>
246
+ {message}
247
+ </div>
248
+ """, unsafe_allow_html=True)
249
+ else:
250
+ st.markdown(f"""
251
+ <div class="chat-message assistant-message">
252
+ <strong>🤖 คำตอบ:</strong><br>
253
+ {message}
254
+ </div>
255
+ """, unsafe_allow_html=True)
256
+
257
+ # Add evaluation buttons after each assistant response
258
+ if i == len(st.session_state.chat_history) - 1: # Only for the latest answer
259
+ user_query = st.session_state.chat_history[i-1][1] # Get the corresponding user query
260
+ evaluate_answer(user_query, message)
261
+
262
+ def add_to_history(role: str, message: str):
263
+ """Add message to chat history"""
264
+ st.session_state.chat_history.append((role, message))
265
 
266
  def main():
267
+ # Header with animation
268
  st.markdown("""
269
+ <div style="text-align: center; padding: 2rem 0;">
270
+ <h1>🎓 ระบบค้นหาข้อมูลปฏิทินการศึกษา</h1>
271
  </div>
272
  """, unsafe_allow_html=True)
273
 
274
  # Initialize pipeline if needed
275
  if st.session_state.pipeline is None:
276
+ with st.spinner("กำลังเริ่มต้นระบบ..."):
277
  st.session_state.pipeline = initialize_pipeline()
278
+
279
+ # Create two columns with better proportions
280
+ chat_col, info_col = st.columns([7, 3])
281
+
282
+ with chat_col:
283
+ # Add a subtle container for the chat interface
284
+ with st.container():
285
+ # Display chat history
286
+ display_chat_history()
287
+
288
+ # Main query interface with enhanced styling
289
+ st.markdown("<br>", unsafe_allow_html=True)
290
+ query = st.text_input(
291
+ "โปรดระบุคำถามเกี่ยวกับปฏิทินการศึกษา:",
292
+ placeholder="เช่น: วันสุดท้ายของการสอบปากเปล่าในภาคเรียนที่ 1/2567 คือวันที่เท่าไร?",
293
+ key="query_input"
294
+ )
295
 
296
+ # Button layout with enhanced styling
297
+ col1, col2, col3 = st.columns([1, 1, 4])
298
+ with col1:
299
+ send_query = st.button("📤 ส่งคำถาม", type="primary", use_container_width=True)
300
+ with col2:
301
+ if st.button("🗑️ ล้างประวัติ", type="secondary", use_container_width=True):
302
+ st.session_state.chat_history = []
303
+ st.rerun()
304
 
305
+ # Process query
306
+ if send_query and query:
307
+ if st.session_state.pipeline is None:
308
+ st.error(" ไม่สามารถเชื่อมต่อกับระบบได้ กรุณาลองใหม่อีกครั้ง")
309
+ return
310
+
 
 
 
311
  add_to_history("user", query)
312
+
313
  try:
314
+ with st.spinner("🔍 กำลังค้นหาคำตอบ..."):
315
  result = st.session_state.pipeline.process_query(query)
316
  add_to_history("assistant", result["answer"])
317
+
318
+ # Enhanced expandable sections
319
+ with st.expander("📚 แสดงข้อมูลอ้างอิง", expanded=False):
320
+ for i, doc in enumerate(result["documents"], 1):
321
+ st.markdown(f"""
322
+ <div style="padding: 1rem; background-color: #F9FAFB; border-radius: 8px; margin: 0.5rem 0;">
323
+ <strong>เอกสารที่ {i}:</strong><br>
324
+ {doc.content}
325
+ </div>
326
+ """, unsafe_allow_html=True)
327
+
328
+ with st.expander("🔍 รายละเอียดการวิเคราะห์คำถาม", expanded=False):
329
+ st.json(result["query_info"])
330
+
331
+ st.rerun()
332
+
333
  except Exception as e:
334
+ st.error(f" เกิดข้อผิดพลาด: {str(e)}")
335
+
336
+ elif send_query and not query:
337
+ st.warning("⚠️ กรุณาระบุคำถาม")
338
+
339
  with info_col:
340
+ # Enhanced system information section
341
  st.markdown("""
342
+ <div style="background-color: #F9FAFB; padding: 1.5rem; border-radius: 12px; margin-bottom: 2rem;">
343
+ <h3>ℹ️ เกี่ยวกับระบบ</h3>
344
+ <p style="color: #4B5563;">
345
+ ระบบนี้ใช้เทคโนโลยี <strong>RAG (Retrieval-Augmented Generation)</strong>
346
+ ในการค้นหาและตอบคำถามเกี่ยวกับปฏิทินการศึกษา
347
+ </p>
348
+ <h4 style="color: #1E3A8A; margin-top: 1rem;">สามารถสอบถามข้อมูลเกี่ยวกับ:</h4>
349
+ <ul style="list-style-type: none; padding-left: 0;">
350
+ <li>📅 กำหนดการต่างๆ ในปฏิทินการศึกษา</li>
351
+ <li>🎯 วันสำคัญและกิจกรรม</li>
352
+ <li>📝 การลงทะเบียนเรียน</li>
353
+ <li>📚 กำหนดการสอบ</li>
354
+ <li>🏖️ วันหยุดการศึกษา</li>
355
  </ul>
356
  </div>
357
  """, unsafe_allow_html=True)
358
+
359
+ # Enhanced system status section
360
+ st.markdown("""
361
+ <div style="background-color: #F9FAFB; padding: 1.5rem; border-radius: 12px;">
362
+ <h3>🔄 สถานะระบบ</h3>
363
+ <div style="margin-top: 1rem;">
364
+ <p><strong>⏰ เวลาปัจจุบัน:</strong><br>
365
+ {}</p>
366
+ <p><strong>📡 สถานะระบบ:</strong><br>
367
+ <span class="status-indicator {}">
368
+ {} {}
369
+ </span></p>
370
+ </div>
371
+ </div>
372
+ """.format(
373
+ datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
374
+ "status-online" if st.session_state.pipeline else "status-offline",
375
+ "🟢" if st.session_state.pipeline else "🔴",
376
+ "พร้อมใช้งาน" if st.session_state.pipeline else "ไม่พร้อมใช้งาน"
377
+ ), unsafe_allow_html=True)
378
 
379
  if __name__ == "__main__":
380
+ main()