DrekFretson commited on
Commit
89dd331
·
verified ·
1 Parent(s): 3872031

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -94
app.py CHANGED
@@ -1,95 +1,85 @@
1
-
2
- from __future__ import unicode_literals
3
- import subprocess
4
  import os
5
-
6
- from dotenv import load_dotenv
7
-
8
- load_dotenv()
9
-
10
- os.environ['USER_AGENT'] = 'myagent'
11
-
12
  import gradio as gr
13
  import requests
14
  import inspect
15
- import tempfile
16
- import nest_asyncio
17
  import pandas as pd
 
 
18
 
19
- from agent import MyAgent
20
- from tools import initialize_web_tools
21
 
22
- nest_asyncio.apply()
 
 
23
 
24
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
25
 
26
- def fetch_questions(questions_url):
27
- print(f"Fetching questions from: {questions_url}")
28
- try:
29
- response = requests.get(questions_url, timeout=15)
30
- response.raise_for_status()
31
- questions_data = response.json()
32
- if not questions_data:
33
- print("Fetched questions list is empty.")
34
- return "Fetched questions list is empty or invalid format.", None
35
- print(f"Fetched {len(questions_data)} questions.")
36
- return questions_data
37
- except requests.exceptions.RequestException as e:
38
- print(f"Error fetching questions: {e}")
39
- return f"Error fetching questions: {e}", None
40
- except requests.exceptions.JSONDecodeError as e:
41
- print(f"Error decoding JSON response from questions endpoint: {e}")
42
- print(f"Response text: {response.text[:500]}")
43
- return f"Error decoding server response for questions: {e}", None
44
- except Exception as e:
45
- print(f"An unexpected error occurred fetching questions: {e}")
46
- return f"An unexpected error occurred fetching questions: {e}", None
47
 
48
- def download_file(files_url, task_id):
49
- try:
50
- filename = task_id
51
- response = requests.get(files_url+'/'+filename)
52
- response.raise_for_status()
53
 
54
- filename = response.headers['content-disposition'].split('"')[1]
55
- temp_dir = tempfile.gettempdir()
56
- file_path = os.path.join(temp_dir, filename)
57
- with open(file_path, 'wb') as f:
58
- f.write(response.content)
 
 
 
 
 
 
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  return file_path
61
- except Exception as file_e:
62
- print(f"No file found for task {task_id} or error: {file_e}")
63
  return None
64
 
65
- async def run_my_agent(agent, questions_data, files_url):
66
- results_log = []
67
- answers_payload = []
68
- print(f"Running agent on {len(questions_data)} questions...")
69
- for item in questions_data:
70
- task_id = item.get("task_id")
71
- file_path = download_file(files_url, task_id)
72
- question_text = item.get("question")
73
- if not task_id or question_text is None:
74
- print(f"Skipping item with missing task_id or question: {item}")
75
- continue
76
- try:
77
- submitted_answer = await agent(question_text, file_path, task_id)
78
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
79
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
80
- except Exception as e:
81
- print(f"Error running agent on task {task_id}: {e}")
82
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
83
- return results_log, answers_payload
84
 
85
- async def run_and_submit_all( profile: gr.OAuthProfile | None):
86
  """
87
  Fetches all questions, runs the BasicAgent on them, submits all answers,
88
  and displays the results.
89
  """
90
  # --- Determine HF Space Runtime URL and Repo URL ---
 
 
91
  if profile:
92
- username= f"{profile.username}"
93
  print(f"User logged in: {username}")
94
  else:
95
  print("User not logged in.")
@@ -98,35 +88,98 @@ async def run_and_submit_all( profile: gr.OAuthProfile | None):
98
  api_url = DEFAULT_API_URL
99
  questions_url = f"{api_url}/questions"
100
  submit_url = f"{api_url}/submit"
101
- files_url = f"{api_url}/files"
102
 
103
  # 1. Instantiate Agent ( modify this part to create your agent)
104
  try:
105
- web_tools = initialize_web_tools()
106
- agent = MyAgent(web_tools=web_tools)
107
  except Exception as e:
108
  print(f"Error instantiating agent: {e}")
109
  return f"Error initializing agent: {e}", None
110
  # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
111
- agent_code = f"https://huggingface.co/spaces/{space_id_startup}/tree/main"
112
  print(agent_code)
113
 
114
- # 2. Fetch Questions
115
- questions_data = fetch_questions(questions_url)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
- # 3. Run your Agent
118
- results_log, answers_payload = await run_my_agent(agent, questions_data, files_url)
119
-
120
  if not answers_payload:
121
  print("Agent did not produce any answers to submit.")
122
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
123
 
124
  # 4. Prepare Submission
125
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
 
 
 
 
126
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
127
  print(status_update)
128
 
129
- # 5. Submit
130
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
131
  try:
132
  response = requests.post(submit_url, json=submission_data, timeout=60)
@@ -140,6 +193,7 @@ async def run_and_submit_all( profile: gr.OAuthProfile | None):
140
  f"Message: {result_data.get('message', 'No message received.')}"
141
  )
142
  print("Submission successful.")
 
143
  results_df = pd.DataFrame(results_log)
144
  return final_status, results_df
145
  except requests.exceptions.HTTPError as e:
@@ -172,9 +226,14 @@ async def run_and_submit_all( profile: gr.OAuthProfile | None):
172
 
173
  # --- Build Gradio Interface using Blocks ---
174
  with gr.Blocks() as demo:
175
- gr.Markdown("# Basic Agent Evaluation Runner")
176
  gr.Markdown(
177
  """
 
 
 
 
 
178
  **Instructions:**
179
  1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
180
  2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
@@ -190,20 +249,19 @@ with gr.Blocks() as demo:
190
 
191
  run_button = gr.Button("Run Evaluation & Submit All Answers")
192
 
193
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
 
 
194
  # Removed max_rows=10 from DataFrame constructor
195
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
196
 
197
- run_button.click(
198
- fn=run_and_submit_all,
199
- outputs=[status_output, results_table],
200
- )
201
 
202
  if __name__ == "__main__":
203
- print("\n" + "-"*30 + " App Starting " + "-"*30)
204
  # Check for SPACE_HOST and SPACE_ID at startup for information
205
  space_host_startup = os.getenv("SPACE_HOST")
206
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
207
 
208
  if space_host_startup:
209
  print(f"✅ SPACE_HOST found: {space_host_startup}")
@@ -211,14 +269,18 @@ if __name__ == "__main__":
211
  else:
212
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
213
 
214
- if space_id_startup: # Print repo URLs if SPACE_ID is found
215
  print(f"✅ SPACE_ID found: {space_id_startup}")
216
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
217
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
 
 
218
  else:
219
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
 
 
220
 
221
- print("-"*(60 + len(" App Starting ")) + "\n")
222
 
223
  print("Launching Gradio Interface for Basic Agent Evaluation...")
224
- demo.launch(debug=True, share=False)
 
 
 
 
1
  import os
 
 
 
 
 
 
 
2
  import gradio as gr
3
  import requests
4
  import inspect
 
 
5
  import pandas as pd
6
+ from agent import SmolAgent
7
+ import json
8
 
9
+ # --- Constants ---
10
+ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
11
 
12
+ USE_CACHE = False # Set to False to disable caching
13
+ CACHE_FILE = "cache/answers_cache.json"
14
+ QUESTIONS_CACHE_FILE = "cache/questions_cache.json"
15
 
 
16
 
17
+ def load_cache(filename):
18
+ if not USE_CACHE:
19
+ print(f"Caching is disabled. Not loading from {filename}.")
20
+ return None
21
+ else:
22
+ if os.path.exists(filename):
23
+ try:
24
+ with open(filename, "r") as f:
25
+ return json.load(f)
26
+ except Exception as e:
27
+ print(f"Failed to load cache from {filename}: {e}")
28
+ return None
 
 
 
 
 
 
 
 
 
29
 
 
 
 
 
 
30
 
31
+ def save_cache(filename, data):
32
+ if not USE_CACHE:
33
+ print(f"Caching is disabled. Not loading from {filename}.")
34
+ return None
35
+ else:
36
+ try:
37
+ with open(filename, "w") as f:
38
+ json.dump(data, f)
39
+ except Exception as e:
40
+ print(f"Failed to save cache to {filename}: {e}")
41
+
42
 
43
+ def download_file(task_id):
44
+ """
45
+ Downloads a file for the given task_id from the /files/{task_id} endpoint,
46
+ extracts the filename from the Content-Disposition header, and saves it to disk.
47
+ Returns the local file path if successful, else None.
48
+ """
49
+ api_url = DEFAULT_API_URL
50
+ file_url = f"{api_url}/files/{task_id}"
51
+ try:
52
+ response = requests.get(file_url, stream=True, timeout=30)
53
+ response.raise_for_status()
54
+ content_disp = response.headers.get("content-disposition", "")
55
+ filename = None
56
+ if "filename=" in content_disp:
57
+ filename = content_disp.split("filename=")[-1].strip('"; ')
58
+ if not filename:
59
+ filename = f"{task_id}.txt"
60
+ os.makedirs("cache", exist_ok=True)
61
+ file_path = os.path.join("cache", filename)
62
+ with open(file_path, "wb") as f:
63
+ for chunk in response.iter_content(chunk_size=8192):
64
+ if chunk:
65
+ f.write(chunk)
66
+ print(f"Downloaded file for task {task_id} to {file_path}")
67
  return file_path
68
+ except Exception as e:
69
+ print(f"Failed to download file for task {task_id}: {e}")
70
  return None
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ def run_and_submit_all(profile: gr.OAuthProfile | None):
74
  """
75
  Fetches all questions, runs the BasicAgent on them, submits all answers,
76
  and displays the results.
77
  """
78
  # --- Determine HF Space Runtime URL and Repo URL ---
79
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
80
+
81
  if profile:
82
+ username = f"{profile.username}"
83
  print(f"User logged in: {username}")
84
  else:
85
  print("User not logged in.")
 
88
  api_url = DEFAULT_API_URL
89
  questions_url = f"{api_url}/questions"
90
  submit_url = f"{api_url}/submit"
 
91
 
92
  # 1. Instantiate Agent ( modify this part to create your agent)
93
  try:
94
+ agent = SmolAgent()
 
95
  except Exception as e:
96
  print(f"Error instantiating agent: {e}")
97
  return f"Error initializing agent: {e}", None
98
  # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
99
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
100
  print(agent_code)
101
 
102
+ # 2. Fetch Questions (with caching)
103
+ questions_data = load_cache(QUESTIONS_CACHE_FILE)
104
+ if questions_data:
105
+ print(f"Loaded {len(questions_data)} questions from cache.")
106
+ else:
107
+ print(f"Fetching questions from: {questions_url}")
108
+ try:
109
+ response = requests.get(questions_url, timeout=15)
110
+ response.raise_for_status()
111
+ questions_data = response.json()
112
+ if not questions_data:
113
+ print("Fetched questions list is empty.")
114
+ return "Fetched questions list is empty or invalid format.", None
115
+ print(f"Fetched {len(questions_data)} questions.")
116
+ save_cache(QUESTIONS_CACHE_FILE, questions_data)
117
+ except requests.exceptions.RequestException as e:
118
+ print(f"Error fetching questions: {e}")
119
+ return f"Error fetching questions: {e}", None
120
+ except requests.exceptions.JSONDecodeError as e:
121
+ print(f"Error decoding JSON response from questions endpoint: {e}")
122
+ print(f"Response text: {response.text[:500]}")
123
+ return f"Error decoding server response for questions: {e}", None
124
+ except Exception as e:
125
+ print(f"An unexpected error occurred fetching questions: {e}")
126
+ return f"An unexpected error occurred fetching questions: {e}", None
127
+
128
+ # 3. Run your Agent (with answer caching)
129
+ results_log = []
130
+ answers_payload = []
131
+ answers_cache = load_cache(CACHE_FILE) or {}
132
+ print(f"Running agent on {len(questions_data)} questions...")
133
+ for item in questions_data:
134
+ task_id = item.get("task_id")
135
+ question_text = item.get("question")
136
+ if not task_id or question_text is None:
137
+ print(f"Skipping item with missing task_id or question: {item}")
138
+ continue
139
+ file_name = item.get("file_name")
140
+
141
+ # Check if answer is cached
142
+ if task_id in answers_cache:
143
+ submitted_answer = answers_cache[task_id]
144
+ print(f"Loaded cached answer for task {task_id}")
145
+ else:
146
+ try:
147
+ if len(file_name) > 0:
148
+ file = download_file(task_id)
149
+ print(f"File for task {file_name} downloaded: {file}")
150
+ submitted_answer = agent.run(question_text, file_path=file)
151
+ else:
152
+ submitted_answer = agent.run(question_text)
153
+ answers_cache[task_id] = submitted_answer
154
+ save_cache(CACHE_FILE, answers_cache)
155
+ except Exception as e:
156
+ print(f"Error running agent on task {task_id}: {e}")
157
+ submitted_answer = f"AGENT ERROR: {e}"
158
+ answers_payload.append(
159
+ {"task_id": task_id, "submitted_answer": submitted_answer}
160
+ )
161
+ results_log.append(
162
+ {
163
+ "Task ID": task_id,
164
+ "Question": question_text,
165
+ "Submitted Answer": submitted_answer,
166
+ }
167
+ )
168
 
 
 
 
169
  if not answers_payload:
170
  print("Agent did not produce any answers to submit.")
171
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
172
 
173
  # 4. Prepare Submission
174
+ submission_data = {
175
+ "username": username.strip(),
176
+ "agent_code": agent_code,
177
+ "answers": answers_payload,
178
+ }
179
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
180
  print(status_update)
181
 
182
+ # # 5. Submit
183
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
184
  try:
185
  response = requests.post(submit_url, json=submission_data, timeout=60)
 
193
  f"Message: {result_data.get('message', 'No message received.')}"
194
  )
195
  print("Submission successful.")
196
+ print(final_status)
197
  results_df = pd.DataFrame(results_log)
198
  return final_status, results_df
199
  except requests.exceptions.HTTPError as e:
 
226
 
227
  # --- Build Gradio Interface using Blocks ---
228
  with gr.Blocks() as demo:
229
+ gr.Markdown("# Robin's Basic Agent Evaluation Space")
230
  gr.Markdown(
231
  """
232
+ ### Description
233
+ My submission for the final assigment of the huggingface agent course.
234
+ I chose to use the smolagents library to create a simple agent and stay away from the bigger multimodel models.
235
+ By providing specifc tools to handle image and audio files.
236
+ ### Original Instructions
237
  **Instructions:**
238
  1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
239
  2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
 
249
 
250
  run_button = gr.Button("Run Evaluation & Submit All Answers")
251
 
252
+ status_output = gr.Textbox(
253
+ label="Run Status / Submission Result", lines=5, interactive=False
254
+ )
255
  # Removed max_rows=10 from DataFrame constructor
256
  results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
257
 
258
+ run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table])
 
 
 
259
 
260
  if __name__ == "__main__":
261
+ print("\n" + "-" * 30 + " App Starting " + "-" * 30)
262
  # Check for SPACE_HOST and SPACE_ID at startup for information
263
  space_host_startup = os.getenv("SPACE_HOST")
264
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
265
 
266
  if space_host_startup:
267
  print(f"✅ SPACE_HOST found: {space_host_startup}")
 
269
  else:
270
  print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
271
 
272
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
273
  print(f"✅ SPACE_ID found: {space_id_startup}")
274
  print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
275
+ print(
276
+ f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main"
277
+ )
278
  else:
279
+ print(
280
+ "ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined."
281
+ )
282
 
283
+ print("-" * (60 + len(" App Starting ")) + "\n")
284
 
285
  print("Launching Gradio Interface for Basic Agent Evaluation...")
286
+ demo.launch(debug=True, share=False)