JirasakJo commited on
Commit
efdbc70
·
verified ·
1 Parent(s): c80e8b9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -201
app.py CHANGED
@@ -2,34 +2,21 @@ import streamlit as st
2
  import json
3
  import os
4
  from datetime import datetime, timedelta
5
- import subprocess
6
- from huggingface_hub import HfApi
7
  from pathlib import Path
8
  from calendar_rag import (
9
  create_default_config,
10
- AcademicCalendarRAG,
11
- PipelineConfig
12
  )
13
- # Custom CSS for enhanced styling
14
  def load_custom_css():
15
  st.markdown("""
16
  <style>
17
- /* General body styling */
18
  body {
19
  font-family: "Arial", sans-serif !important;
20
  color: #000000 !important;
21
  background-color: white !important;
22
  line-height: 1.7 !important;
23
  }
24
-
25
- /* Main container styling */
26
- .main {
27
- padding: 2rem;
28
- color: #000000;
29
- background-color: white;
30
- }
31
-
32
- /* Headers styling */
33
  h1 {
34
  color: #000000;
35
  font-size: 2.8rem !important;
@@ -39,15 +26,6 @@ def load_custom_css():
39
  padding: 1rem 0;
40
  border-bottom: 3px solid #1E3A8A;
41
  }
42
-
43
- h3, h4 {
44
- color: #000000;
45
- font-weight: 600 !important;
46
- font-size: 1.6rem !important;
47
- margin-top: 1.5rem !important;
48
- }
49
-
50
- /* Chat message styling */
51
  .chat-message {
52
  padding: 1.5rem;
53
  border-radius: 10px;
@@ -55,45 +33,18 @@ def load_custom_css():
55
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
56
  font-size: 1.1rem !important;
57
  line-height: 1.6 !important;
58
- font-family: "Arial", sans-serif !important;
59
  color: #000000 !important;
60
  }
61
-
62
  .user-message {
63
  background-color: #F3F4F6 !important;
64
  }
65
-
66
  .assistant-message {
67
  background-color: #EFF6FF !important;
68
  }
69
-
70
- /* Status indicators */
71
- .status-indicator {
72
- padding: 0.5rem 1rem;
73
- border-radius: 6px;
74
- font-weight: 500;
75
- font-size: 1.2rem;
76
- color: #000000;
77
- }
78
-
79
- .status-online {
80
- background-color: #DEF7EC;
81
- color: #03543F;
82
- }
83
-
84
- .status-offline {
85
- background-color: #FDE8E8;
86
- color: rgb(255, 255, 255);
87
- }
88
  </style>
89
  """, unsafe_allow_html=True)
90
 
91
- # Define a callback to reset query_input
92
- def reset_query_input():
93
- st.session_state.query_input = ""
94
-
95
  def initialize_pipeline():
96
- """Initialize RAG pipeline with configurations"""
97
  try:
98
  openai_api_key = os.getenv('OPENAI_API_KEY') or st.secrets['OPENAI_API_KEY']
99
  config = create_default_config(openai_api_key)
@@ -101,19 +52,17 @@ def initialize_pipeline():
101
  config.retriever.top_k = 5
102
  config.model.temperature = 0.3
103
  pipeline = AcademicCalendarRAG(config)
104
-
105
  with open("calendar.json", "r", encoding="utf-8") as f:
106
  calendar_data = json.load(f)
107
  pipeline.load_data(calendar_data)
108
-
109
  return pipeline
110
-
111
  except Exception as e:
112
  st.error(f"Error initializing pipeline: {str(e)}")
113
  return None
114
 
115
  def load_qa_history():
116
- """Load QA history from local JSON file"""
117
  try:
118
  history_file = Path("qa_history.json")
119
  if history_file.exists():
@@ -125,91 +74,37 @@ def load_qa_history():
125
  return []
126
 
127
  def save_qa_history(history_entry):
128
- """Save QA history entry to local JSON file and push to GitHub"""
129
  try:
130
  history_file = Path("qa_history.json")
131
-
132
- # Initialize or load existing history
133
  if history_file.exists():
134
  with open(history_file, "r", encoding="utf-8") as f:
135
- try:
136
- history_data = json.load(f)
137
- except json.JSONDecodeError:
138
- st.error("Error parsing existing JSON file")
139
- history_data = []
140
  else:
141
  history_data = []
142
-
143
- # Append new entry
144
  history_data.append(history_entry)
145
-
146
- # Save updated history locally
147
  with open("qa_history.json", "w", encoding="utf-8") as f:
148
  json.dump(history_data, f, ensure_ascii=False, indent=2)
149
-
150
- # st.info("Saved locally, attempting GitHub upload...")
151
-
152
- # Push to GitHub
153
- github_token = os.getenv('GITHUB_TOKEN') or st.secrets['GITHUB_TOKEN']
154
- if not github_token:
155
- st.error("GitHub token not found!")
156
- return
157
-
158
- from github import Github
159
- g = Github(github_token)
160
-
161
- # Replace with your repository name
162
- repo = g.get_repo("jirasaksaimekJijo/swu-chat-bot-project")
163
-
164
- try:
165
- # Try to get the file first
166
- contents = repo.get_contents("qa_history.json")
167
- response = repo.update_file(
168
- path="qa_history.json",
169
- message="Update QA history",
170
- content=json.dumps(history_data, ensure_ascii=False, indent=2),
171
- sha=contents.sha
172
- )
173
- # st.success(f"Successfully updated file on GitHub: {response.commit.html_url}")
174
- except Exception as e:
175
- # st.info(f"File doesn't exist yet, creating new one... Error was: {str(e)}")
176
- # File doesn't exist, create it
177
- response = repo.create_file(
178
- path="qa_history.json",
179
- message="Create QA history",
180
- content=json.dumps(history_data, ensure_ascii=False, indent=2)
181
- )
182
- # st.success(f"Successfully created file on GitHub: {response['commit'].html_url}")
183
-
184
  except Exception as e:
185
- # st.error(f"Error saving QA history: {str(e)}")
186
- import traceback
187
- # st.error(f"Full error: {traceback.format_exc()}")
188
 
189
  def add_to_qa_history(query: str, answer: str):
190
- """Add new QA pair to history"""
191
  history_entry = {
192
  "timestamp": (datetime.now() + timedelta(hours=7)).isoformat(),
193
  "query": query,
194
  "answer": answer
195
  }
196
-
197
  save_qa_history(history_entry)
198
  return history_entry
199
-
200
  def add_to_history(role: str, message: str):
201
- """Add message to chat history and save if it's a complete QA pair"""
202
  st.session_state.chat_history.append((role, message))
203
-
204
- # If this is an assistant response, save the QA pair
205
  if role == "assistant" and len(st.session_state.chat_history) >= 2:
206
- # Get the corresponding user query (previous message)
207
  user_query = st.session_state.chat_history[-2][1]
208
  add_to_qa_history(user_query, message)
209
-
210
  def display_chat_history():
211
- """Display chat history with enhanced styling"""
212
- for i, (role, message) in enumerate(st.session_state.chat_history):
213
  if role == "user":
214
  st.markdown(f"""
215
  <div class="chat-message user-message">
@@ -225,51 +120,44 @@ def display_chat_history():
225
  </div>
226
  """, unsafe_allow_html=True)
227
 
 
 
 
228
  def main():
229
- # Page config
230
  st.set_page_config(
231
  page_title="Academic Calendar Assistant",
232
  page_icon="📅",
233
- layout="wide",
234
- initial_sidebar_state="collapsed"
235
  )
236
 
237
- # Load custom CSS
238
  load_custom_css()
239
 
240
- # Initialize session state
241
  if 'pipeline' not in st.session_state:
242
  st.session_state.pipeline = None
243
-
244
  if 'chat_history' not in st.session_state:
245
  st.session_state.chat_history = []
246
 
247
- # Load QA history at startup
248
  if 'qa_history_loaded' not in st.session_state:
249
  st.session_state.qa_history_loaded = True
250
  load_qa_history()
251
 
252
- # Header
253
  st.markdown("""
254
  <div style="text-align: center; padding: 2rem 0;">
255
  <h1>🎓 ระบบค้นหาข้อมูลปฏิทินการศึกษา</h1>
256
- <p style="font-size: 1.2rem; color: #666;">บัณฑิตวิทยาลัย มหาวิทยาลัยศรีนครินทรวิโรฒ</p>
257
  </div>
258
  """, unsafe_allow_html=True)
259
 
260
- # Initialize pipeline
261
  if st.session_state.pipeline is None:
262
  with st.spinner("กำลังเริ่มต้นระบบ..."):
263
  st.session_state.pipeline = initialize_pipeline()
264
 
265
  chat_col, info_col = st.columns([7, 3])
266
-
267
  with chat_col:
268
  with st.container():
269
- # Display chat history
270
  display_chat_history()
271
-
272
- # Query input section
273
  st.markdown("""
274
  <label for="query_input" style="font-size: 1.2rem; font-weight: 600; margin-bottom: 1rem; display: block;">
275
  <span style="color: #ffffff; border-left: 4px solid #ffffff; padding-left: 0.8rem;">
@@ -277,36 +165,33 @@ def main():
277
  </span>
278
  </label>
279
  """, unsafe_allow_html=True)
280
-
281
- # Inside the main function
282
  if "query_input" not in st.session_state:
283
  st.session_state.query_input = ""
284
-
285
  query = st.text_input(
286
  "",
287
  placeholder="เช่น: วันสุดท้ายของการสอบปากเปล่าในภาคเรียนที่ 1/2567 คือวันที่เท่าไร?",
288
  key="query_input",
 
289
  )
290
-
291
  col1, col2, col3 = st.columns([1, 1, 4])
292
-
293
  with col1:
294
  send_query = st.button(
295
  "📤 ส่งคำถาม",
296
  type="primary",
297
- use_container_width=True,
298
- key="send_query_button"
299
  )
300
-
301
  with col2:
302
  clear_history = st.button(
303
  "🗑️ ล้างประวัติ",
304
  type="secondary",
305
- use_container_width=True,
306
- key="clear_history_button"
307
  )
308
-
309
- # Process query
310
  if send_query and query:
311
  if st.session_state.pipeline is None:
312
  st.error("❌ ไม่สามารถเชื่อมต่อกับระบบได้ กรุณาลองใหม่อีกครั้ง")
@@ -316,72 +201,15 @@ def main():
316
  with st.spinner("🔍 กำลังค้นหาคำตอบ..."):
317
  result = st.session_state.pipeline.process_query(query)
318
  add_to_history("assistant", result["answer"])
319
-
320
- # Reset the query input
321
- reset_query_input()
322
-
323
- with st.expander("📚 แสดงข้อมูลอ้างอิง", expanded=False):
324
- for i, doc in enumerate(result["documents"], 1):
325
- st.markdown(f"""
326
- <div style="padding: 1rem; background-color: #F9FAFB; border-radius: 8px; margin: 0.5rem 0;">
327
- <strong>เอกสารที่ {i}:</strong><br>
328
- {doc.content}
329
- </div>
330
- """, unsafe_allow_html=True)
331
-
332
- with st.expander("🔍 รายละเอียดการวิเคราะห์คำถาม", expanded=False):
333
- st.json(result["query_info"])
334
-
335
  st.rerun()
336
  except Exception as e:
337
  st.error(f"❌ เกิดข้อผิดพลาด: {str(e)}")
338
  elif send_query and not query:
339
  st.warning("⚠️ กรุณาระบุคำถาม")
340
 
341
- # Handle clear history action
342
- if clear_history:
343
- st.session_state.chat_history = []
344
- st.rerun()
345
-
346
- with info_col:
347
- # System information
348
- st.markdown("""
349
- <div style="background-color: #F9FAFB; padding: 1.5rem; border-radius: 12px; margin-bottom: 2rem;">
350
- <h3 style="color: #1E3A8A;">ℹ️ เกี่ยวกับระบบ</h3>
351
- <p style="color: #000000;">
352
- ระบบนี้ใช้เทคโนโลยี <strong>RAG (Retrieval-Augmented Generation)</strong>
353
- ในการค้นหาและตอบคำถามเกี่ยวกับปฏิทินการศึกษา
354
- </p>
355
- <h4 style="color: #1E3A8A; margin-top: 1rem;">สามารถสอบถามข้อมูลเกี่ยวกับ:</h4>
356
- <ul style="list-style-type: none; padding-left: 0;">
357
- <li style="color: #000000; margin-bottom: 0.5rem;">📅 กำหนดการต่างๆ ในปฏิทินการศึกษา</li>
358
- <li style="color: #000000; margin-bottom: 0.5rem;">🎯 วันสำคัญและกิจกรรม</li>
359
- <li style="color: #000000; margin-bottom: 0.5rem;">📝 การลงทะเบียนเรียน</li>
360
- <li style="color: #000000; margin-bottom: 0.5rem;">📚 กำหนดการสอบ</li>
361
- <li style="color: #000000; margin-bottom: 0.5rem;">🏖️ วันหยุดการศึกษา</li>
362
- </ul>
363
- </div>
364
- """, unsafe_allow_html=True)
365
-
366
- # System status
367
- st.markdown("""
368
- <div style="background-color: #f9fafb; padding: 1.5rem; border-radius: 12px;">
369
- <h3 style="color: #1E3A8A;">🔄 สถานะระบบ</h3>
370
- <div style="margin-top: 1rem;">
371
- <p><strong style="color: #000000;">⏰ เวลาปัจจุบัน:</strong><br>
372
- <span style="color: #000000;">{}</span></p>
373
- <p><strong style="color: #000000;">📡 สถานะระบบ:</strong><br>
374
- <span class="status-indicator {}">
375
- {} {}
376
- </span></p>
377
- </div>
378
- </div>
379
- """.format(
380
- (datetime.now() + timedelta(hours=6)).strftime('%Y-%m-%d %H:%M:%S'),
381
- "status-online" if st.session_state.pipeline else "status-offline",
382
- "🟢" if st.session_state.pipeline else "🔴",
383
- "พร้อมใช้งาน" if st.session_state.pipeline else "ไม่พร้อมใช้งาน"
384
- ), unsafe_allow_html=True)
385
 
386
  if __name__ == "__main__":
387
  main()
 
2
  import json
3
  import os
4
  from datetime import datetime, timedelta
 
 
5
  from pathlib import Path
6
  from calendar_rag import (
7
  create_default_config,
8
+ AcademicCalendarRAG
 
9
  )
10
+
11
  def load_custom_css():
12
  st.markdown("""
13
  <style>
 
14
  body {
15
  font-family: "Arial", sans-serif !important;
16
  color: #000000 !important;
17
  background-color: white !important;
18
  line-height: 1.7 !important;
19
  }
 
 
 
 
 
 
 
 
 
20
  h1 {
21
  color: #000000;
22
  font-size: 2.8rem !important;
 
26
  padding: 1rem 0;
27
  border-bottom: 3px solid #1E3A8A;
28
  }
 
 
 
 
 
 
 
 
 
29
  .chat-message {
30
  padding: 1.5rem;
31
  border-radius: 10px;
 
33
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
34
  font-size: 1.1rem !important;
35
  line-height: 1.6 !important;
 
36
  color: #000000 !important;
37
  }
 
38
  .user-message {
39
  background-color: #F3F4F6 !important;
40
  }
 
41
  .assistant-message {
42
  background-color: #EFF6FF !important;
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  </style>
45
  """, unsafe_allow_html=True)
46
 
 
 
 
 
47
  def initialize_pipeline():
 
48
  try:
49
  openai_api_key = os.getenv('OPENAI_API_KEY') or st.secrets['OPENAI_API_KEY']
50
  config = create_default_config(openai_api_key)
 
52
  config.retriever.top_k = 5
53
  config.model.temperature = 0.3
54
  pipeline = AcademicCalendarRAG(config)
55
+
56
  with open("calendar.json", "r", encoding="utf-8") as f:
57
  calendar_data = json.load(f)
58
  pipeline.load_data(calendar_data)
59
+
60
  return pipeline
 
61
  except Exception as e:
62
  st.error(f"Error initializing pipeline: {str(e)}")
63
  return None
64
 
65
  def load_qa_history():
 
66
  try:
67
  history_file = Path("qa_history.json")
68
  if history_file.exists():
 
74
  return []
75
 
76
  def save_qa_history(history_entry):
 
77
  try:
78
  history_file = Path("qa_history.json")
 
 
79
  if history_file.exists():
80
  with open(history_file, "r", encoding="utf-8") as f:
81
+ history_data = json.load(f)
 
 
 
 
82
  else:
83
  history_data = []
 
 
84
  history_data.append(history_entry)
85
+
 
86
  with open("qa_history.json", "w", encoding="utf-8") as f:
87
  json.dump(history_data, f, ensure_ascii=False, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  except Exception as e:
89
+ st.error(f"Error saving QA history: {str(e)}")
 
 
90
 
91
  def add_to_qa_history(query: str, answer: str):
 
92
  history_entry = {
93
  "timestamp": (datetime.now() + timedelta(hours=7)).isoformat(),
94
  "query": query,
95
  "answer": answer
96
  }
 
97
  save_qa_history(history_entry)
98
  return history_entry
99
+
100
  def add_to_history(role: str, message: str):
 
101
  st.session_state.chat_history.append((role, message))
 
 
102
  if role == "assistant" and len(st.session_state.chat_history) >= 2:
 
103
  user_query = st.session_state.chat_history[-2][1]
104
  add_to_qa_history(user_query, message)
105
+
106
  def display_chat_history():
107
+ for role, message in st.session_state.chat_history:
 
108
  if role == "user":
109
  st.markdown(f"""
110
  <div class="chat-message user-message">
 
120
  </div>
121
  """, unsafe_allow_html=True)
122
 
123
+ def reset_query_input():
124
+ st.session_state.query_input = ""
125
+
126
  def main():
 
127
  st.set_page_config(
128
  page_title="Academic Calendar Assistant",
129
  page_icon="📅",
130
+ layout="wide"
 
131
  )
132
 
 
133
  load_custom_css()
134
 
 
135
  if 'pipeline' not in st.session_state:
136
  st.session_state.pipeline = None
137
+
138
  if 'chat_history' not in st.session_state:
139
  st.session_state.chat_history = []
140
 
 
141
  if 'qa_history_loaded' not in st.session_state:
142
  st.session_state.qa_history_loaded = True
143
  load_qa_history()
144
 
 
145
  st.markdown("""
146
  <div style="text-align: center; padding: 2rem 0;">
147
  <h1>🎓 ระบบค้นหาข้อมูลปฏิทินการศึกษา</h1>
 
148
  </div>
149
  """, unsafe_allow_html=True)
150
 
 
151
  if st.session_state.pipeline is None:
152
  with st.spinner("กำลังเริ่มต้นระบบ..."):
153
  st.session_state.pipeline = initialize_pipeline()
154
 
155
  chat_col, info_col = st.columns([7, 3])
156
+
157
  with chat_col:
158
  with st.container():
 
159
  display_chat_history()
160
+
 
161
  st.markdown("""
162
  <label for="query_input" style="font-size: 1.2rem; font-weight: 600; margin-bottom: 1rem; display: block;">
163
  <span style="color: #ffffff; border-left: 4px solid #ffffff; padding-left: 0.8rem;">
 
165
  </span>
166
  </label>
167
  """, unsafe_allow_html=True)
168
+
 
169
  if "query_input" not in st.session_state:
170
  st.session_state.query_input = ""
171
+
172
  query = st.text_input(
173
  "",
174
  placeholder="เช่น: วันสุดท้ายของการสอบปากเปล่าในภาคเรียนที่ 1/2567 คือวันที่เท่าไร?",
175
  key="query_input",
176
+ on_change=reset_query_input
177
  )
178
+
179
  col1, col2, col3 = st.columns([1, 1, 4])
180
+
181
  with col1:
182
  send_query = st.button(
183
  "📤 ส่งคำถาม",
184
  type="primary",
185
+ use_container_width=True
 
186
  )
187
+
188
  with col2:
189
  clear_history = st.button(
190
  "🗑️ ล้างประวัติ",
191
  type="secondary",
192
+ use_container_width=True
 
193
  )
194
+
 
195
  if send_query and query:
196
  if st.session_state.pipeline is None:
197
  st.error("❌ ไม่สามารถเชื่อมต่อกับระบบได้ กรุณาลองใหม่อีกครั้ง")
 
201
  with st.spinner("🔍 กำลังค้นหาคำตอบ..."):
202
  result = st.session_state.pipeline.process_query(query)
203
  add_to_history("assistant", result["answer"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  st.rerun()
205
  except Exception as e:
206
  st.error(f"❌ เกิดข้อผิดพลาด: {str(e)}")
207
  elif send_query and not query:
208
  st.warning("⚠️ กรุณาระบุคำถาม")
209
 
210
+ if clear_history:
211
+ st.session_state.chat_history = []
212
+ st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
  if __name__ == "__main__":
215
  main()