emeses commited on
Commit
176deb5
·
1 Parent(s): 28b51d8

Update space

Browse files
Files changed (1) hide show
  1. app.py +130 -139
app.py CHANGED
@@ -1,169 +1,160 @@
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
 
3
  import requests
4
  from bs4 import BeautifulSoup
5
- import pandas as pd
6
-
7
- client = InferenceClient("meta-llama/Llama-3.2-3B-Instruct")
8
 
9
- data = [] # Global variable to store table data
 
10
 
11
- def respond(message, history, system_message, max_tokens=2048, temperature=0.7, top_p=0.9):
12
- messages = [{"role": "system", "content": system_message}]
13
- for val in history:
14
- if val[0]:
15
- messages.append({"role": "user", "content": val[0]})
16
- if val[1]:
17
- messages.append({"role": "assistant", "content": val[1]})
18
- messages.append({"role": "user", "content": message})
19
- response = ""
20
- for message in client.chat_completion(
21
- messages,
22
- max_tokens=max_tokens,
23
- stream=True,
24
- temperature=temperature,
25
- top_p=top_p,
26
- ):
27
- token = message.choices[0].delta.content
28
- response += token
29
- yield response
 
 
 
 
 
 
 
30
 
31
- def extract_table(url):
32
- global data
33
  try:
 
34
  response = requests.get(url)
35
  response.raise_for_status()
36
- soup = BeautifulSoup(response.text, "html.parser")
37
- table = soup.find("table")
 
 
38
  if not table:
39
  return "<p>No table found on page</p>"
40
-
41
- # Extract data
42
- data = []
43
- rows = table.find_all("tr")
44
- for i, row in enumerate(rows[1:]): # Skip header row
45
- cells = row.find_all("td")
46
- if len(cells) >= 2:
47
- data.append({"Index": i, "Date": cells[0].text.strip()[:10], "Topic": cells[1].text.strip()})
48
-
49
- # Generate HTML table with buttons that trigger Gradio events
50
- html_rows = ""
51
- for row in data:
52
- html_rows += f"""
53
- <tr>
54
- <td>{row['Date']}</td>
55
- <td>{row['Topic']}</td>
56
- <td><button class="gr-button gr-button-lg" onclick="handle_topic_click({row['Index']})">Prepare</button></td>
57
- </tr>
58
- """
59
- html_table = f"""
60
- <table border="1">
61
- <tr>
62
- <th>Date</th>
63
- <th>Topic</th>
64
- <th>Action</th>
65
- </tr>
66
- {html_rows}
67
- </table>
68
- <script>
69
- function handle_topic_click(index) {{
70
- const prepareInput = document.querySelector('#prepareInput textarea');
71
- if (prepareInput) {{
72
- prepareInput.value = index;
73
- prepareInput.dispatchEvent(new Event('input'));
74
- document.querySelector('#prepareSubmit').click();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  }}
76
  }}
77
- </script>
 
 
 
78
  """
79
- return html_table
 
80
  except Exception as e:
81
  return f"<p>Error: {str(e)}</p>"
82
 
83
- def handle_prepare(index, history):
84
  try:
85
- index = int(index)
86
- if 0 <= index < len(data):
87
- topic = data[index]["Topic"]
88
- prompt = f"Prepare a 10-minute reading on what I should know before the class for the topic: {topic}"
89
- history = history or []
90
- history.append((prompt, None))
91
- return history
92
  except Exception as e:
93
- print(f"Error in handle_prepare: {e}")
94
- return history or []
95
 
96
- def prepare_message(index, history, system_msg):
97
- try:
98
- index = int(index)
99
- if 0 <= index < len(data):
100
- topic = data[index]["Topic"]
101
- return f"Prepare a 10-minute reading for topic: {topic}", history, system_msg
102
- except Exception as e:
103
- print(f"Error in prepare_message: {e}")
104
- return "", history, system_msg
105
-
106
- def user_message(message, history):
107
- history = history or []
108
- history.append((message, None))
109
- return "", history
110
-
111
- def clear_chat():
112
- return [], []
113
-
114
- # Gradio app
115
  with gr.Blocks() as demo:
116
  with gr.Row():
 
117
  with gr.Column(scale=1):
118
- url_input = gr.Textbox(value="https://id2223kth.github.io/schedule/", label="Table URL")
119
- table_output = gr.HTML(label="Extracted Table")
120
- extract_btn = gr.Button("Extract Table")
 
 
 
121
 
122
- # Hidden components for prepare functionality
123
- prepare_input = gr.Textbox(visible=False, elem_id="prepareInput")
124
- prepare_submit = gr.Button("Prepare Submit", visible=False, elem_id="prepareSubmit")
125
-
 
 
 
126
  with gr.Column(scale=2):
127
- chatbot = gr.Chatbot()
128
- msg = gr.Textbox(label="Message")
129
- system_message = gr.Textbox(
130
- value="Student class preparation companion.",
131
- label="System message"
132
  )
133
 
134
- with gr.Row():
135
- submit = gr.Button("Submit")
136
- clear = gr.Button("Clear")
137
-
138
- # Event handlers
139
- extract_btn.click(
140
- fn=extract_table,
141
- inputs=[url_input],
142
- outputs=[table_output]
143
- )
144
-
145
- submit.click(
146
- user_message,
147
- inputs=[msg, chatbot],
148
- outputs=[msg, chatbot]
149
- ).then(
150
- respond,
151
- inputs=[msg, chatbot, system_message],
152
- outputs=[chatbot]
153
- )
154
-
155
- # Handle prepare button clicks
156
- prepare_submit.click(
157
- handle_prepare,
158
- inputs=[prepare_input, chatbot],
159
- outputs=[chatbot]
160
- ).then(
161
- respond,
162
- inputs=[prepare_input, chatbot, system_message],
163
- outputs=[chatbot]
164
- )
165
-
166
- clear.click(fn=clear_chat, outputs=[chatbot, msg])
167
-
168
  if __name__ == "__main__":
169
  demo.launch()
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
+ import pandas as pd
4
  import requests
5
  from bs4 import BeautifulSoup
 
 
 
6
 
7
+ # Initialize HF client
8
+ client = InferenceClient("meta-llama/Llama-2-7b-chat-hf")
9
 
10
+ def respond(message, history, max_tokens=512, temperature=0.7, top_p=0.95):
11
+ try:
12
+ # Format messages including history
13
+ messages = []
14
+ for user_msg, assistant_msg in history:
15
+ messages.append({"role": "user", "content": user_msg})
16
+ messages.append({"role": "assistant", "content": assistant_msg})
17
+ messages.append({"role": "user", "content": message})
18
+
19
+ # Generate response
20
+ response = ""
21
+ for chunk in client.chat_completion(
22
+ messages,
23
+ max_tokens=max_tokens,
24
+ temperature=temperature,
25
+ top_p=top_p,
26
+ stream=True,
27
+ ):
28
+ if hasattr(chunk.choices[0].delta, 'content'):
29
+ token = chunk.choices[0].delta.content
30
+ if token:
31
+ response += token
32
+ return response
33
+
34
+ except Exception as e:
35
+ return f"Error: {str(e)}"
36
 
37
+ def extract_schedule(url):
 
38
  try:
39
+ # Fetch and parse webpage
40
  response = requests.get(url)
41
  response.raise_for_status()
42
+ soup = BeautifulSoup(response.text, 'html.parser')
43
+
44
+ # Find table and extract data
45
+ table = soup.find('table')
46
  if not table:
47
  return "<p>No table found on page</p>"
48
+
49
+ schedule_data = []
50
+ rows = table.find_all('tr')
51
+ for row in rows[1:]:
52
+ cells = row.find_all('td')
53
+ if len(cells) >= 4:
54
+ date = cells[0].text.strip()
55
+ topic = cells[1].text.strip()
56
+
57
+ if date and topic and not topic.startswith('See Canvas'):
58
+ schedule_data.append({
59
+ 'Date': date[:10],
60
+ 'Topic': topic,
61
+ 'Action': f"""
62
+ <button
63
+ onclick="triggerChatbotPreparation('{topic.replace("'", "")}')"
64
+ class="prepare-btn">
65
+ Prepare
66
+ </button>
67
+ """
68
+ })
69
+
70
+ df = pd.DataFrame(schedule_data)
71
+
72
+ # Convert to HTML with styling and JavaScript
73
+ html = f"""
74
+ <style>
75
+ table {{
76
+ border-collapse: collapse;
77
+ width: 100%;
78
+ font-size: 12px;
79
+ }}
80
+ th, td {{
81
+ border: 1px solid black;
82
+ padding: 6px;
83
+ text-align: left;
84
+ font-family: Arial, sans-serif;
85
+ }}
86
+ .prepare-btn {{
87
+ padding: 4px 8px;
88
+ font-size: 11px;
89
+ cursor: pointer;
90
+ }}
91
+ </style>
92
+ <script>
93
+ function triggerChatbotPreparation(topic) {{
94
+ // Find all Gradio textareas
95
+ const textareas = document.querySelectorAll('.gradio-container textarea');
96
+
97
+ // Find the first textarea (assuming it's the input)
98
+ const textbox = textareas[0];
99
+
100
+ if (textbox) {{
101
+ // Set the value
102
+ const preparationMessage = `prepare 5 minutes reading important parts related to ${topic}`;
103
+ textbox.value = preparationMessage;
104
+
105
+ // Trigger input and change events
106
+ const inputEvent = new Event('input', {{ bubbles: true }});
107
+ const changeEvent = new Event('change', {{ bubbles: true }});
108
+ textbox.dispatchEvent(inputEvent);
109
+ textbox.dispatchEvent(changeEvent);
110
+
111
+ // Find and click the send button
112
+ const sendButtons = document.querySelectorAll('.gradio-container button');
113
+ for (let button of sendButtons) {{
114
+ if (button.getAttribute('aria-label') === 'Send') {{
115
+ button.click();
116
+ break;
117
  }}
118
  }}
119
+ }}
120
+ }}
121
+ </script>
122
+ {df.to_html(index=False, escape=False)}
123
  """
124
+ return html
125
+
126
  except Exception as e:
127
  return f"<p>Error: {str(e)}</p>"
128
 
129
+ def display_schedule(url):
130
  try:
131
+ html_table = extract_schedule(url)
132
+ return html_table # Already HTML string
 
 
 
 
 
133
  except Exception as e:
134
+ return str(e)
 
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  with gr.Blocks() as demo:
137
  with gr.Row():
138
+ # Left Column - Schedule
139
  with gr.Column(scale=1):
140
+ url_input = gr.Textbox(
141
+ value="https://id2223kth.github.io/schedule/",
142
+ label="Schedule URL"
143
+ )
144
+ schedule_output = gr.HTML(label="Extracted Schedule")
145
+ extract_btn = gr.Button("Extract Schedule")
146
 
147
+ extract_btn.click(
148
+ fn=display_schedule,
149
+ inputs=[url_input],
150
+ outputs=[schedule_output]
151
+ )
152
+
153
+ # Right Column - Chatbot
154
  with gr.Column(scale=2):
155
+ chatbot = gr.ChatInterface(
156
+ respond
 
 
 
157
  )
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  if __name__ == "__main__":
160
  demo.launch()