Jofthomas commited on
Commit
7d65c66
·
verified ·
1 Parent(s): 9088b99

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -101
app.py CHANGED
@@ -1,46 +1,25 @@
1
  import os
2
  import gradio as gr
3
  import requests
4
- import inspect # To get source code for __repr__
5
  import pandas as pd
6
 
 
7
  # --- Constants ---
8
- DEFAULT_API_URL = "https://jofthomas-unit4-scoring.hf.space/" # Default URL for your FastAPI app
9
 
10
  # --- Basic Agent Definition ---
11
- ## This is where you should implement your own agent and tools
12
-
13
  class BasicAgent:
14
- """
15
- A very simple agent placeholder.
16
- It just returns a fixed string for any question.
17
- """
18
  def __init__(self):
19
  print("BasicAgent initialized.")
20
- # Add any setup if needed
21
-
22
  def __call__(self, question: str) -> str:
23
- """
24
- The agent's logic to answer a question.
25
- This basic version ignores the question content.
26
- """
27
  print(f"Agent received question (first 50 chars): {question[:50]}...")
28
- # Replace this with actual logic if you were building a real agent
29
  fixed_answer = "This is a default answer."
30
  print(f"Agent returning fixed answer: {fixed_answer}")
31
  return fixed_answer
32
-
33
- # __repr__ seems intended to get the *source* code, not just representation
34
- # Let's keep it but note that get_current_script_content might be more robust
35
- # if the class definition changes significantly or relies on external state.
36
  def __repr__(self) -> str:
37
- """
38
- Return the source code required to reconstruct this agent.
39
- NOTE: This might be brittle. Using get_current_script_content is likely safer.
40
- """
41
- imports = [
42
- "import inspect\n"
43
- ]
44
  try:
45
  class_source = inspect.getsource(BasicAgent)
46
  full_source = "\n".join(imports) + "\n" + class_source
@@ -51,17 +30,14 @@ class BasicAgent:
51
 
52
  # --- Gradio UI and Logic ---
53
  def get_current_script_content() -> str:
54
- """Attempts to read and return the content of the currently running script."""
55
  try:
56
- # __file__ holds the path to the current script
57
  script_path = os.path.abspath(__file__)
58
  print(f"Reading script content from: {script_path}")
59
  with open(script_path, 'r', encoding='utf-8') as f:
60
  return f.read()
61
  except NameError:
62
- # __file__ is not defined (e.g., running in an interactive interpreter or frozen app)
63
  print("Warning: __file__ is not defined. Cannot read script content this way.")
64
- # Fallback or alternative method could be added here if needed
65
  return "# Agent code unavailable: __file__ not defined"
66
  except FileNotFoundError:
67
  print(f"Warning: Script file '{script_path}' not found.")
@@ -76,17 +52,27 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
76
  Fetches all questions, runs the BasicAgent on them, submits all answers,
77
  and displays the results.
78
  """
79
- # --- Determine HF Space URL and Print Environment Info ---
80
  space_host = os.getenv("SPACE_HOST")
81
- hf_space_url = "Runtime: Locally or unknown environment (SPACE_HOST env var not found)"
 
 
 
 
 
82
  if space_host:
83
- # Construct the standard URL format for HF Spaces
84
- hf_space_url = f"Runtime: Hugging Face Space (https://{space_host}.hf.space)"
 
 
 
85
 
86
- # Print runtime info at the start of the function execution
87
  print("\n" + "="*60)
88
  print("Executing run_and_submit_all function...")
89
- print(hf_space_url) # Print the determined runtime URL
 
 
90
  # --- End Environment Info ---
91
 
92
  if profile:
@@ -94,110 +80,80 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
94
  print(f"User logged in: {username}")
95
  else:
96
  print("User not logged in.")
97
- print("="*60 + "\n") # Close the separator block
98
- return "Please Login to Hugging Face with the button.", None # Return early
99
 
100
- print("="*60 + "\n") # Separator after initial checks if logged in
101
 
 
102
  api_url = DEFAULT_API_URL
103
  questions_url = f"{api_url}/questions"
104
  submit_url = f"{api_url}/submit"
105
 
106
- # 1. Instantiate the Agent
107
  try:
108
  agent = BasicAgent()
109
- # Using get_current_script_content() is likely more reliable for submission
110
- # agent_code = agent.__repr__() # Keep if needed, but prefer file content
111
- # print(f"Agent Code via __repr__ (first 200): {agent_code[:200]}...") # Debug
112
  except Exception as e:
113
  print(f"Error instantiating agent: {e}")
114
  return f"Error initializing agent: {e}", None
115
-
116
- # Get agent code by reading the current script file - generally more robust
117
  agent_code = get_current_script_content()
118
  if agent_code.startswith("# Agent code unavailable"):
119
  print("Warning: Using potentially incomplete agent code due to reading error.")
120
- # Optional: Fall back to agent.__repr__() if needed
121
- # agent_code = agent.__repr__()
122
 
123
- # 2. Fetch All Questions
124
  print(f"Fetching questions from: {questions_url}")
125
  try:
126
  response = requests.get(questions_url, timeout=15)
127
- response.raise_for_status() # Raise HTTPError for bad responses (4xx or 5xx)
128
  questions_data = response.json()
129
  if not questions_data:
130
  print("Fetched questions list is empty.")
131
  return "Fetched questions list is empty or invalid format.", None
132
  print(f"Fetched {len(questions_data)} questions.")
133
- # status_update = f"Fetched {len(questions_data)} questions. Running agent..." # For yield/streaming
134
  except requests.exceptions.RequestException as e:
135
  print(f"Error fetching questions: {e}")
136
  return f"Error fetching questions: {e}", None
137
  except requests.exceptions.JSONDecodeError as e:
138
  print(f"Error decoding JSON response from questions endpoint: {e}")
139
- print(f"Response text: {response.text[:500]}") # Log response text for debugging
140
  return f"Error decoding server response for questions: {e}", None
141
- except Exception as e: # Catch other potential errors
142
  print(f"An unexpected error occurred fetching questions: {e}")
143
  return f"An unexpected error occurred fetching questions: {e}", None
144
 
145
- # 3. Run Agent on Each Question
146
- results_log = [] # To store data for the results table
147
- answers_payload = [] # To store data for the submission API
148
  print(f"Running agent on {len(questions_data)} questions...")
149
  for item in questions_data:
150
  task_id = item.get("task_id")
151
  question_text = item.get("question")
152
-
153
  if not task_id or question_text is None:
154
  print(f"Skipping item with missing task_id or question: {item}")
155
  continue
156
-
157
  try:
158
- submitted_answer = agent(question_text) # Call the agent's logic
159
- answers_payload.append({
160
- "task_id": task_id,
161
- "submitted_answer": submitted_answer
162
- })
163
- results_log.append({
164
- "Task ID": task_id,
165
- "Question": question_text,
166
- "Submitted Answer": submitted_answer
167
- })
168
  except Exception as e:
169
  print(f"Error running agent on task {task_id}: {e}")
170
- results_log.append({
171
- "Task ID": task_id,
172
- "Question": question_text,
173
- "Submitted Answer": f"AGENT ERROR: {e}"
174
- })
175
- # Decide if you want to submit agent errors or skip:
176
- # answers_payload.append({"task_id": task_id, "submitted_answer": f"AGENT ERROR: {e}"})
177
 
178
  if not answers_payload:
179
  print("Agent did not produce any answers to submit.")
180
- # Still show results log even if nothing submitted
181
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
182
 
183
  # 4. Prepare Submission
184
- submission_data = {
185
- "username": username.strip(),
186
- "agent_code": agent_code, # Using the code read from file
187
- "answers": answers_payload
188
- }
189
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
190
  print(status_update)
191
 
192
- # 5. Submit to Leaderboard
193
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
194
  try:
195
- # Ensure submission_data is serializable, agent_code should be string
196
- response = requests.post(submit_url, json=submission_data, timeout=60) # Increased timeout further
197
  response.raise_for_status()
198
  result_data = response.json()
199
-
200
- # Prepare final status message and results table
201
  final_status = (
202
  f"Submission Successful!\n"
203
  f"User: {result_data.get('username')}\n"
@@ -208,19 +164,16 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
208
  print("Submission successful.")
209
  results_df = pd.DataFrame(results_log)
210
  return final_status, results_df
211
-
212
  except requests.exceptions.HTTPError as e:
213
  error_detail = f"Server responded with status {e.response.status_code}."
214
  try:
215
- # Try to get more specific error detail from JSON response body
216
  error_json = e.response.json()
217
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
218
  except requests.exceptions.JSONDecodeError:
219
- # If response is not JSON, use the raw text
220
- error_detail += f" Response: {e.response.text[:500]}" # Limit length
221
  status_message = f"Submission Failed: {error_detail}"
222
  print(status_message)
223
- results_df = pd.DataFrame(results_log) # Show attempts even if submission failed
224
  return status_message, results_df
225
  except requests.exceptions.Timeout:
226
  status_message = "Submission Failed: The request timed out."
@@ -232,7 +185,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
232
  print(status_message)
233
  results_df = pd.DataFrame(results_log)
234
  return status_message, results_df
235
- except Exception as e: # Catch unexpected errors during submission phase
236
  status_message = f"An unexpected error occurred during submission: {e}"
237
  print(status_message)
238
  results_df = pd.DataFrame(results_log)
@@ -243,7 +196,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
243
  with gr.Blocks() as demo:
244
  gr.Markdown("# Basic Agent Evaluation Runner")
245
  gr.Markdown(
246
- "Please clone this space, then modify the code to define your agent's logic within the `BasicAgent` class. " # Clarified instructions
247
  "Log in to your Hugging Face account using the button below. This uses your HF username for submission. "
248
  "Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score."
249
  )
@@ -253,28 +206,34 @@ with gr.Blocks() as demo:
253
  run_button = gr.Button("Run Evaluation & Submit All Answers")
254
 
255
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
256
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
 
257
 
258
- # --- Component Interaction ---
259
- # Use the profile information directly from the LoginButton state (implicitly passed)
260
  run_button.click(
261
  fn=run_and_submit_all,
262
- # Input is implicitly the profile data from LoginButton state
263
  outputs=[status_output, results_table]
264
  )
265
 
266
  if __name__ == "__main__":
267
  print("\n" + "-"*30 + " App Starting " + "-"*30)
268
- # Check for SPACE_HOST at startup for information
269
  space_host_startup = os.getenv("SPACE_HOST")
 
 
270
  if space_host_startup:
271
  print(f"✅ SPACE_HOST found: {space_host_startup}")
272
- print(f" App should be available at: https://{space_host_startup}.hf.space")
273
  else:
274
- print("ℹ️ SPACE_HOST environment variable not found (running locally or not on standard HF Space runtime).")
275
- print(" App will likely be available at local URLs printed by Gradio below.")
 
 
 
 
 
 
 
276
  print("-"*(60 + len(" App Starting ")) + "\n")
277
 
278
  print("Launching Gradio Interface for Basic Agent Evaluation...")
279
- # Set share=False as the primary access point is the HF Space URL
280
  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
 
7
+ # (Keep Constants and BasicAgent class as is)
8
  # --- Constants ---
9
+ DEFAULT_API_URL = "https://jofthomas-unit4-scoring.hf.space/"
10
 
11
  # --- Basic Agent Definition ---
 
 
12
  class BasicAgent:
13
+ # ... (keep agent code as is) ...
 
 
 
14
  def __init__(self):
15
  print("BasicAgent initialized.")
 
 
16
  def __call__(self, question: str) -> str:
 
 
 
 
17
  print(f"Agent received question (first 50 chars): {question[:50]}...")
 
18
  fixed_answer = "This is a default answer."
19
  print(f"Agent returning fixed answer: {fixed_answer}")
20
  return fixed_answer
 
 
 
 
21
  def __repr__(self) -> str:
22
+ imports = ["import inspect\n"]
 
 
 
 
 
 
23
  try:
24
  class_source = inspect.getsource(BasicAgent)
25
  full_source = "\n".join(imports) + "\n" + class_source
 
30
 
31
  # --- Gradio UI and Logic ---
32
  def get_current_script_content() -> str:
33
+ # ... (keep function as is) ...
34
  try:
 
35
  script_path = os.path.abspath(__file__)
36
  print(f"Reading script content from: {script_path}")
37
  with open(script_path, 'r', encoding='utf-8') as f:
38
  return f.read()
39
  except NameError:
 
40
  print("Warning: __file__ is not defined. Cannot read script content this way.")
 
41
  return "# Agent code unavailable: __file__ not defined"
42
  except FileNotFoundError:
43
  print(f"Warning: Script file '{script_path}' not found.")
 
52
  Fetches all questions, runs the BasicAgent on them, submits all answers,
53
  and displays the results.
54
  """
55
+ # --- Determine HF Space Runtime URL and Repo URL ---
56
  space_host = os.getenv("SPACE_HOST")
57
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID
58
+
59
+ hf_runtime_url = "Runtime: Locally or unknown environment (SPACE_HOST not found)"
60
+ hf_repo_url = "HF Repo URL: Unknown (SPACE_ID not found)"
61
+ hf_repo_tree_url = "HF Repo Tree URL: Unknown (SPACE_ID not found)"
62
+
63
  if space_host:
64
+ hf_runtime_url = f"Runtime URL: https://{space_host}.hf.space"
65
+
66
+ if space_id: # Construct URLs using SPACE_ID
67
+ hf_repo_url = f"HF Repo URL: https://huggingface.co/spaces/{space_id}"
68
+ hf_repo_tree_url = f"HF Repo Tree URL: https://huggingface.co/spaces/{space_id}/tree/main"
69
 
70
+ # Print runtime and repo info at the start
71
  print("\n" + "="*60)
72
  print("Executing run_and_submit_all function...")
73
+ print(hf_runtime_url) # Print the runtime URL (from SPACE_HOST)
74
+ print(hf_repo_url) # Print the base repo URL (from SPACE_ID)
75
+ print(hf_repo_tree_url) # Print the repo tree URL (from SPACE_ID)
76
  # --- End Environment Info ---
77
 
78
  if profile:
 
80
  print(f"User logged in: {username}")
81
  else:
82
  print("User not logged in.")
83
+ print("="*60 + "\n")
84
+ return "Please Login to Hugging Face with the button.", None
85
 
86
+ print("="*60 + "\n")
87
 
88
+ # ... (rest of the function remains the same) ...
89
  api_url = DEFAULT_API_URL
90
  questions_url = f"{api_url}/questions"
91
  submit_url = f"{api_url}/submit"
92
 
93
+ # 1. Instantiate Agent
94
  try:
95
  agent = BasicAgent()
 
 
 
96
  except Exception as e:
97
  print(f"Error instantiating agent: {e}")
98
  return f"Error initializing agent: {e}", None
 
 
99
  agent_code = get_current_script_content()
100
  if agent_code.startswith("# Agent code unavailable"):
101
  print("Warning: Using potentially incomplete agent code due to reading error.")
 
 
102
 
103
+ # 2. Fetch Questions
104
  print(f"Fetching questions from: {questions_url}")
105
  try:
106
  response = requests.get(questions_url, timeout=15)
107
+ response.raise_for_status()
108
  questions_data = response.json()
109
  if not questions_data:
110
  print("Fetched questions list is empty.")
111
  return "Fetched questions list is empty or invalid format.", None
112
  print(f"Fetched {len(questions_data)} questions.")
 
113
  except requests.exceptions.RequestException as e:
114
  print(f"Error fetching questions: {e}")
115
  return f"Error fetching questions: {e}", None
116
  except requests.exceptions.JSONDecodeError as e:
117
  print(f"Error decoding JSON response from questions endpoint: {e}")
118
+ print(f"Response text: {response.text[:500]}")
119
  return f"Error decoding server response for questions: {e}", None
120
+ except Exception as e:
121
  print(f"An unexpected error occurred fetching questions: {e}")
122
  return f"An unexpected error occurred fetching questions: {e}", None
123
 
124
+ # 3. Run Agent
125
+ results_log = []
126
+ answers_payload = []
127
  print(f"Running agent on {len(questions_data)} questions...")
128
  for item in questions_data:
129
  task_id = item.get("task_id")
130
  question_text = item.get("question")
 
131
  if not task_id or question_text is None:
132
  print(f"Skipping item with missing task_id or question: {item}")
133
  continue
 
134
  try:
135
+ submitted_answer = agent(question_text)
136
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
137
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
 
 
 
 
 
 
 
138
  except Exception as e:
139
  print(f"Error running agent on task {task_id}: {e}")
140
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
 
 
 
 
 
 
141
 
142
  if not answers_payload:
143
  print("Agent did not produce any answers to submit.")
 
144
  return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
145
 
146
  # 4. Prepare Submission
147
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
 
 
 
 
148
  status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
149
  print(status_update)
150
 
151
+ # 5. Submit
152
  print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
153
  try:
154
+ response = requests.post(submit_url, json=submission_data, timeout=60)
 
155
  response.raise_for_status()
156
  result_data = response.json()
 
 
157
  final_status = (
158
  f"Submission Successful!\n"
159
  f"User: {result_data.get('username')}\n"
 
164
  print("Submission successful.")
165
  results_df = pd.DataFrame(results_log)
166
  return final_status, results_df
 
167
  except requests.exceptions.HTTPError as e:
168
  error_detail = f"Server responded with status {e.response.status_code}."
169
  try:
 
170
  error_json = e.response.json()
171
  error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
172
  except requests.exceptions.JSONDecodeError:
173
+ error_detail += f" Response: {e.response.text[:500]}"
 
174
  status_message = f"Submission Failed: {error_detail}"
175
  print(status_message)
176
+ results_df = pd.DataFrame(results_log)
177
  return status_message, results_df
178
  except requests.exceptions.Timeout:
179
  status_message = "Submission Failed: The request timed out."
 
185
  print(status_message)
186
  results_df = pd.DataFrame(results_log)
187
  return status_message, results_df
188
+ except Exception as e:
189
  status_message = f"An unexpected error occurred during submission: {e}"
190
  print(status_message)
191
  results_df = pd.DataFrame(results_log)
 
196
  with gr.Blocks() as demo:
197
  gr.Markdown("# Basic Agent Evaluation Runner")
198
  gr.Markdown(
199
+ "Please clone this space, then modify the code to define your agent's logic within the `BasicAgent` class. "
200
  "Log in to your Hugging Face account using the button below. This uses your HF username for submission. "
201
  "Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score."
202
  )
 
206
  run_button = gr.Button("Run Evaluation & Submit All Answers")
207
 
208
  status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
209
+ # Removed max_rows=10 from DataFrame constructor
210
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
211
 
 
 
212
  run_button.click(
213
  fn=run_and_submit_all,
 
214
  outputs=[status_output, results_table]
215
  )
216
 
217
  if __name__ == "__main__":
218
  print("\n" + "-"*30 + " App Starting " + "-"*30)
219
+ # Check for SPACE_HOST and SPACE_ID at startup for information
220
  space_host_startup = os.getenv("SPACE_HOST")
221
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
222
+
223
  if space_host_startup:
224
  print(f"✅ SPACE_HOST found: {space_host_startup}")
225
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
226
  else:
227
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
228
+
229
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
230
+ print(f"✅ SPACE_ID found: {space_id_startup}")
231
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
232
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
233
+ else:
234
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
235
+
236
  print("-"*(60 + len(" App Starting ")) + "\n")
237
 
238
  print("Launching Gradio Interface for Basic Agent Evaluation...")
 
239
  demo.launch(debug=True, share=False)