SantoshKumar1310 commited on
Commit
fcb3bd3
Β·
verified Β·
1 Parent(s): 52e9388

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +202 -103
app.py CHANGED
@@ -7,6 +7,13 @@ import time
7
  # --- Constants ---
8
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
9
 
 
 
 
 
 
 
 
10
  # --- Basic Agent Definition ---
11
  # πŸ‘‰ You can customize this class with your own logic or tools
12
  class BasicAgent:
@@ -21,55 +28,82 @@ class BasicAgent:
21
  return fixed_answer
22
 
23
 
24
- def check_api_status(api_url: str) -> tuple[bool, str]:
25
- """Check if the API is accessible"""
26
- try:
27
- # Try to access the base URL or a health check endpoint
28
- response = requests.get(api_url, timeout=10)
29
- if response.status_code == 200:
30
- return True, "API is accessible"
31
- else:
32
- return False, f"API returned status code: {response.status_code}"
33
- except requests.exceptions.Timeout:
34
- return False, "API request timed out"
35
- except requests.exceptions.ConnectionError:
36
- return False, "Cannot connect to API (connection error)"
37
- except Exception as e:
38
- return False, f"API check failed: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
 
41
- def run_and_submit_all(profile: gr.OAuthProfile | None):
42
  """
43
  Fetch all questions, run the agent, submit answers, and show results.
44
  """
45
  space_id = os.getenv("SPACE_ID") # Hugging Face Space ID
46
 
47
- if profile:
48
- username = profile.username
49
- print(f"πŸ‘€ User logged in: {username}")
 
 
 
 
50
  else:
51
- print("❌ User not logged in.")
52
- return "❌ Please login to Hugging Face first.", None
53
 
54
  api_url = DEFAULT_API_URL
55
  questions_url = f"{api_url}/questions"
56
  submit_url = f"{api_url}/submit"
57
 
58
- # Check API status first
59
- print("πŸ” Checking API status...")
60
- api_ok, api_msg = check_api_status(api_url)
61
- if not api_ok:
62
- error_msg = (
63
- f"⚠️ API Status Check Failed\n\n"
64
- f"Issue: {api_msg}\n\n"
65
- f"Possible solutions:\n"
66
- f"1. The scoring API at {api_url} may be down or moved\n"
67
- f"2. Check if the API URL is correct\n"
68
- f"3. The Hugging Face Space might need to be restarted\n"
69
- f"4. Try again in a few minutes\n\n"
70
- f"You can verify the API status by visiting: {api_url}"
71
- )
72
- return error_msg, None
 
 
 
 
 
73
 
74
  # 1️⃣ Create Agent
75
  try:
@@ -81,40 +115,45 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
81
  print(f"πŸ“ Agent code link: {agent_code}")
82
 
83
  # 2️⃣ Fetch Questions
84
- try:
85
- print("πŸ“‘ Fetching questions...")
86
- response = requests.get(questions_url, timeout=15)
87
-
88
- if response.status_code == 404:
89
- error_msg = (
90
- f"⚠️ Questions endpoint not found (404)\n\n"
91
- f"The endpoint {questions_url} is not available.\n\n"
92
- f"Possible issues:\n"
93
- f"1. The API structure may have changed\n"
94
- f"2. The scoring service might be under maintenance\n"
95
- f"3. You may need to update the API URL\n\n"
96
- f"Please check the course materials or contact the instructor for the correct API endpoint."
97
- )
98
- return error_msg, None
99
-
100
- response.raise_for_status()
101
- questions_data = response.json()
102
-
103
- if not questions_data:
104
- return "⚠️ Fetched question list is empty or invalid.", None
105
-
106
- print(f"βœ… Retrieved {len(questions_data)} questions.")
107
-
108
- except requests.exceptions.Timeout:
109
- return f"⏱️ Request timed out while fetching questions from {questions_url}", None
110
- except requests.exceptions.ConnectionError:
111
- return f"πŸ”Œ Connection error: Cannot reach {questions_url}", None
112
- except requests.exceptions.HTTPError as e:
113
- return f"❌ HTTP Error fetching questions: {e}", None
114
- except ValueError as e:
115
- return f"❌ Invalid JSON response from questions endpoint: {e}", None
116
- except Exception as e:
117
- return f"❌ Error fetching questions: {e}", None
 
 
 
 
 
118
 
119
  # 3️⃣ Run Agent
120
  results_log = []
@@ -131,27 +170,42 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
131
  continue
132
 
133
  try:
134
- print(f"Processing question {i+1}/{len(questions_data)}: {task_id}")
135
  submitted_answer = agent(question_text)
136
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
137
  results_log.append({
138
  "Task ID": task_id,
139
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
140
- "Submitted Answer": submitted_answer[:100] + "..." if len(str(submitted_answer)) > 100 else submitted_answer
141
  })
142
  except Exception as e:
143
- error_msg = f"AGENT ERROR: {e}"
144
  print(f"❌ {error_msg} for task {task_id}")
145
  results_log.append({
146
  "Task ID": task_id,
147
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
148
- "Submitted Answer": error_msg
149
  })
150
 
151
  if not answers_payload:
152
  return "⚠️ No answers generated by the agent.", pd.DataFrame(results_log)
153
 
154
- # 4️⃣ Submit Answers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  submission_data = {
156
  "username": username.strip(),
157
  "agent_code": agent_code,
@@ -159,37 +213,39 @@ def run_and_submit_all(profile: gr.OAuthProfile | None):
159
  }
160
 
161
  try:
162
- print("πŸ“€ Submitting answers...")
163
- response = requests.post(submit_url, json=submission_data, timeout=60)
164
 
165
  if response.status_code == 404:
166
  error_msg = (
167
  f"⚠️ Submit endpoint not found (404)\n\n"
168
- f"Generated {len(answers_payload)} answers but cannot submit them.\n"
169
- f"The endpoint {submit_url} is not available.\n\n"
170
- f"Your answers are shown in the table below for reference."
 
 
 
 
171
  )
172
- return error_msg, pd.DataFrame(results_log)
173
 
174
  response.raise_for_status()
175
  result_data = response.json()
176
 
177
  final_status = (
178
- f"βœ… Submission Successful!\n"
179
- f"πŸ‘€ User: {result_data.get('username')}\n"
180
  f"🏁 Score: {result_data.get('score', 'N/A')}% "
181
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
182
- f"πŸ“ Message: {result_data.get('message', 'No message received.')}"
 
183
  )
184
- results_df = pd.DataFrame(results_log)
185
  return final_status, results_df
186
 
187
  except requests.exceptions.Timeout:
188
- return f"⏱️ Submission timed out. Your answers:\n{len(answers_payload)} answers generated but not submitted.", pd.DataFrame(results_log)
189
- except requests.exceptions.HTTPError as e:
190
- return f"❌ HTTP Error during submission: {e}\nYour answers are shown below.", pd.DataFrame(results_log)
191
  except Exception as e:
192
- return f"❌ Submission failed: {e}\nYour answers are shown below.", pd.DataFrame(results_log)
193
 
194
 
195
  # --- Gradio Interface ---
@@ -197,26 +253,69 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
197
  gr.Markdown("# πŸ€– Basic Agent Evaluation Runner")
198
  gr.Markdown(
199
  """
200
- ### Instructions:
201
- 1️⃣ Clone this space on your Hugging Face profile.
202
- 2️⃣ Modify the `BasicAgent` class with your logic.
203
- 3️⃣ Log in below and run evaluation.
 
 
 
 
 
 
 
 
 
 
204
  ---
205
- The process may take time (the agent answers all questions).
206
- You can customize the agent with reasoning, search tools, or memory.
207
 
208
- ⚠️ **Note**: If you see a 404 error, the scoring API may be temporarily unavailable.
209
- Check with your instructor for the correct API endpoint.
 
 
210
  """
211
  )
212
 
213
- gr.LoginButton()
214
- run_button = gr.Button("πŸš€ Run Evaluation & Submit All Answers", variant="primary")
 
 
 
 
 
 
 
 
 
215
 
216
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=8, interactive=False)
217
- results_table = gr.DataFrame(label="Questions and Agent Answers")
 
 
 
 
 
 
 
 
 
218
 
219
- run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
 
222
  if __name__ == "__main__":
 
7
  # --- Constants ---
8
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
9
 
10
+ # Sample questions for offline testing
11
+ SAMPLE_QUESTIONS = [
12
+ {"task_id": "sample_1", "question": "What is 2 + 2?"},
13
+ {"task_id": "sample_2", "question": "What is the capital of France?"},
14
+ {"task_id": "sample_3", "question": "Who wrote 'Romeo and Juliet'?"},
15
+ ]
16
+
17
  # --- Basic Agent Definition ---
18
  # πŸ‘‰ You can customize this class with your own logic or tools
19
  class BasicAgent:
 
28
  return fixed_answer
29
 
30
 
31
+ def check_api_health(api_url: str) -> tuple[bool, str, dict]:
32
+ """Check if the API endpoints are accessible"""
33
+ endpoints_to_check = [
34
+ ("Base URL", api_url),
35
+ ("Questions", f"{api_url}/questions"),
36
+ ("Docs", f"{api_url}/docs"),
37
+ ]
38
+
39
+ results = {}
40
+ for name, url in endpoints_to_check:
41
+ try:
42
+ response = requests.get(url, timeout=10)
43
+ results[name] = {
44
+ "status_code": response.status_code,
45
+ "accessible": response.status_code in [200, 307],
46
+ "url": url
47
+ }
48
+ except requests.exceptions.Timeout:
49
+ results[name] = {"status_code": "Timeout", "accessible": False, "url": url}
50
+ except requests.exceptions.ConnectionError:
51
+ results[name] = {"status_code": "Connection Error", "accessible": False, "url": url}
52
+ except Exception as e:
53
+ results[name] = {"status_code": str(e), "accessible": False, "url": url}
54
+
55
+ # Check if any endpoint is accessible
56
+ any_accessible = any(r["accessible"] for r in results.values())
57
+
58
+ status_msg = "API Health Check:\n"
59
+ for name, result in results.items():
60
+ status = "βœ…" if result["accessible"] else "❌"
61
+ status_msg += f"{status} {name}: {result['status_code']}\n"
62
+
63
+ return any_accessible, status_msg, results
64
 
65
 
66
+ def run_and_submit_all(profile: gr.OAuthProfile | None, use_offline_mode: bool = False):
67
  """
68
  Fetch all questions, run the agent, submit answers, and show results.
69
  """
70
  space_id = os.getenv("SPACE_ID") # Hugging Face Space ID
71
 
72
+ if not use_offline_mode:
73
+ if profile:
74
+ username = profile.username
75
+ print(f"πŸ‘€ User logged in: {username}")
76
+ else:
77
+ print("❌ User not logged in.")
78
+ return "❌ Please login to Hugging Face first (or use offline test mode).", None
79
  else:
80
+ username = "offline_test_user"
81
+ print("πŸ§ͺ Running in offline test mode")
82
 
83
  api_url = DEFAULT_API_URL
84
  questions_url = f"{api_url}/questions"
85
  submit_url = f"{api_url}/submit"
86
 
87
+ # Check API health
88
+ if not use_offline_mode:
89
+ print("πŸ” Checking API health...")
90
+ api_ok, health_msg, health_results = check_api_health(api_url)
91
+ print(health_msg)
92
+
93
+ # If API is completely inaccessible, suggest offline mode
94
+ if not api_ok:
95
+ error_msg = (
96
+ f"⚠️ API Health Check Failed\n\n"
97
+ f"{health_msg}\n"
98
+ f"πŸ”§ Troubleshooting Options:\n\n"
99
+ f"1. **Try Offline Test Mode**: Enable the checkbox below to test your agent locally\n"
100
+ f"2. **Wait and Retry**: The Hugging Face Space may be starting up (can take 1-2 minutes)\n"
101
+ f"3. **Check Space Status**: Visit https://huggingface.co/spaces/agents-course/agents-course-unit4-scoring\n"
102
+ f"4. **Use Alternative Template**: Try the official template at https://huggingface.co/spaces/agents-course/Final_Assignment_Template\n"
103
+ f"5. **Contact Course Support**: Check the course Discord or GitHub for updates\n\n"
104
+ f"πŸ’‘ The API scoring system might be temporarily unavailable or undergoing maintenance."
105
+ )
106
+ return error_msg, None
107
 
108
  # 1️⃣ Create Agent
109
  try:
 
115
  print(f"πŸ“ Agent code link: {agent_code}")
116
 
117
  # 2️⃣ Fetch Questions
118
+ if use_offline_mode:
119
+ print("πŸ§ͺ Using sample questions for offline testing")
120
+ questions_data = SAMPLE_QUESTIONS
121
+ else:
122
+ try:
123
+ print("πŸ“‘ Fetching questions from API...")
124
+ response = requests.get(questions_url, timeout=30)
125
+
126
+ if response.status_code == 404:
127
+ error_msg = (
128
+ f"⚠️ Questions endpoint returned 404\n\n"
129
+ f"The endpoint {questions_url} is not found.\n\n"
130
+ f"This might mean:\n"
131
+ f"β€’ The Hugging Face Space is still starting up (try waiting 60 seconds)\n"
132
+ f"β€’ The Space has been moved or the API structure changed\n"
133
+ f"β€’ The Space is in a sleep/stopped state\n\n"
134
+ f"πŸ”§ Solutions:\n"
135
+ f"1. Enable 'Offline Test Mode' below to test locally\n"
136
+ f"2. Visit the Space directly: https://huggingface.co/spaces/agents-course/agents-course-unit4-scoring\n"
137
+ f"3. Check the official template: https://huggingface.co/spaces/agents-course/Final_Assignment_Template\n"
138
+ f"4. Join the course Discord for real-time help\n\n"
139
+ f"πŸ’‘ Tip: Offline mode lets you test your agent logic without needing the API!"
140
+ )
141
+ return error_msg, None
142
+
143
+ response.raise_for_status()
144
+ questions_data = response.json()
145
+
146
+ if not questions_data:
147
+ return "⚠️ Fetched question list is empty.", None
148
+
149
+ print(f"βœ… Retrieved {len(questions_data)} questions from API.")
150
+
151
+ except requests.exceptions.Timeout:
152
+ return f"⏱️ Request timed out. The API might be slow to respond. Try enabling offline test mode.", None
153
+ except requests.exceptions.ConnectionError:
154
+ return f"πŸ”Œ Cannot connect to API. Try offline test mode or check your internet connection.", None
155
+ except Exception as e:
156
+ return f"❌ Error fetching questions: {e}\n\nTry using offline test mode to test your agent locally.", None
157
 
158
  # 3️⃣ Run Agent
159
  results_log = []
 
170
  continue
171
 
172
  try:
173
+ print(f"Processing {i+1}/{len(questions_data)}: {task_id}")
174
  submitted_answer = agent(question_text)
175
  answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
176
  results_log.append({
177
  "Task ID": task_id,
178
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
179
+ "Your Answer": str(submitted_answer)[:100] + "..." if len(str(submitted_answer)) > 100 else str(submitted_answer)
180
  })
181
  except Exception as e:
182
+ error_msg = f"ERROR: {e}"
183
  print(f"❌ {error_msg} for task {task_id}")
184
  results_log.append({
185
  "Task ID": task_id,
186
  "Question": question_text[:100] + "..." if len(question_text) > 100 else question_text,
187
+ "Your Answer": error_msg
188
  })
189
 
190
  if not answers_payload:
191
  return "⚠️ No answers generated by the agent.", pd.DataFrame(results_log)
192
 
193
+ results_df = pd.DataFrame(results_log)
194
+
195
+ # 4️⃣ Submit Answers (skip in offline mode)
196
+ if use_offline_mode:
197
+ final_status = (
198
+ f"πŸ§ͺ Offline Test Mode - Agent Run Complete!\n\n"
199
+ f"βœ… Successfully generated {len(answers_payload)} answers\n"
200
+ f"πŸ“ Review your answers in the table below\n\n"
201
+ f"ℹ️ To submit for real scoring:\n"
202
+ f"1. Disable offline test mode\n"
203
+ f"2. Wait for the API to be available\n"
204
+ f"3. Run the evaluation again\n\n"
205
+ f"πŸ’‘ Your agent logic is working! Just needs API connection for scoring."
206
+ )
207
+ return final_status, results_df
208
+
209
  submission_data = {
210
  "username": username.strip(),
211
  "agent_code": agent_code,
 
213
  }
214
 
215
  try:
216
+ print("πŸ“€ Submitting answers to API...")
217
+ response = requests.post(submit_url, json=submission_data, timeout=90)
218
 
219
  if response.status_code == 404:
220
  error_msg = (
221
  f"⚠️ Submit endpoint not found (404)\n\n"
222
+ f"βœ… Good news: Your agent generated {len(answers_payload)} answers!\n"
223
+ f"❌ Bad news: Cannot submit them - API endpoint unavailable\n\n"
224
+ f"Your answers are saved in the table below.\n\n"
225
+ f"Next steps:\n"
226
+ f"β€’ Try again in a few minutes (Space might be starting)\n"
227
+ f"β€’ Use the official submission template\n"
228
+ f"β€’ Contact course instructors for API status"
229
  )
230
+ return error_msg, results_df
231
 
232
  response.raise_for_status()
233
  result_data = response.json()
234
 
235
  final_status = (
236
+ f"πŸŽ‰ Submission Successful!\n\n"
237
+ f"πŸ‘€ Username: {result_data.get('username')}\n"
238
  f"🏁 Score: {result_data.get('score', 'N/A')}% "
239
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n\n"
240
+ f"πŸ“ {result_data.get('message', 'No message received.')}\n\n"
241
+ f"πŸ”— Check the leaderboard to see your ranking!"
242
  )
 
243
  return final_status, results_df
244
 
245
  except requests.exceptions.Timeout:
246
+ return f"⏱️ Submission timed out after 90 seconds.\n\nβœ… Your agent generated {len(answers_payload)} answers (see table below)\n❌ But submission failed due to timeout.\n\nTry again or contact course support.", results_df
 
 
247
  except Exception as e:
248
+ return f"❌ Submission failed: {e}\n\nβœ… Your agent generated {len(answers_payload)} answers (see table below)\n\nTry submitting again later.", results_df
249
 
250
 
251
  # --- Gradio Interface ---
 
253
  gr.Markdown("# πŸ€– Basic Agent Evaluation Runner")
254
  gr.Markdown(
255
  """
256
+ ### πŸ“‹ Instructions:
257
+ 1️⃣ **Clone this space** to your Hugging Face profile
258
+ 2️⃣ **Customize the `BasicAgent` class** with your logic (add tools, reasoning, etc.)
259
+ 3️⃣ **Log in** and run the evaluation
260
+
261
+ ---
262
+
263
+ ### ⚠️ API Issues?
264
+ If you're seeing 404 errors, the scoring API might be temporarily unavailable:
265
+ - βœ… **Use Offline Test Mode** (checkbox below) to test your agent locally
266
+ - ⏰ **Wait 1-2 minutes** for the Hugging Face Space to wake up
267
+ - πŸ”— **Check official template**: [Final Assignment Template](https://huggingface.co/spaces/agents-course/Final_Assignment_Template)
268
+ - πŸ’¬ **Get help**: Join the [course Discord](https://discord.gg/hugging-face)
269
+
270
  ---
 
 
271
 
272
+ ### πŸ’‘ Tips:
273
+ - The agent will answer ALL questions (this takes time!)
274
+ - Customize your agent with: reasoning, web search, calculators, file readers, etc.
275
+ - Aim for 30%+ score to get your certificate!
276
  """
277
  )
278
 
279
+ with gr.Row():
280
+ gr.LoginButton()
281
+
282
+ with gr.Row():
283
+ offline_mode = gr.Checkbox(
284
+ label="πŸ§ͺ Offline Test Mode (test agent without API)",
285
+ value=False,
286
+ info="Enable this to test your agent with sample questions when the API is unavailable"
287
+ )
288
+
289
+ run_button = gr.Button("πŸš€ Run Evaluation & Submit", variant="primary", size="lg")
290
 
291
+ status_output = gr.Textbox(
292
+ label="πŸ“Š Status / Results",
293
+ lines=10,
294
+ interactive=False,
295
+ show_copy_button=True
296
+ )
297
+
298
+ results_table = gr.DataFrame(
299
+ label="πŸ“ Questions and Agent Answers",
300
+ wrap=True
301
+ )
302
 
303
+ gr.Markdown(
304
+ """
305
+ ---
306
+ ### πŸ”— Helpful Resources:
307
+ - [Course Materials](https://huggingface.co/learn/agents-course)
308
+ - [Official Template](https://huggingface.co/spaces/agents-course/Final_Assignment_Template)
309
+ - [GAIA Benchmark Info](https://huggingface.co/gaia-benchmark)
310
+ - [Course Discord](https://discord.gg/hugging-face)
311
+ """
312
+ )
313
+
314
+ run_button.click(
315
+ fn=run_and_submit_all,
316
+ inputs=[offline_mode],
317
+ outputs=[status_output, results_table]
318
+ )
319
 
320
 
321
  if __name__ == "__main__":