Spaces:
Runtime error
Runtime error
Refactor agent workflow into modular functions
Browse filesThe agent workflow was split into specialized functions for better readability and maintainability. This includes separate steps for agent instantiation, question fetching, agent execution, submission preparation, and answer submission. The modular approach improves reusability and simplifies debugging.
app.py
CHANGED
|
@@ -8,6 +8,7 @@ import pandas as pd
|
|
| 8 |
# --- Constants ---
|
| 9 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 10 |
|
|
|
|
| 11 |
# --- Basic Agent Definition ---
|
| 12 |
# ----- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ------
|
| 13 |
class BasicAgent:
|
|
@@ -19,36 +20,23 @@ class BasicAgent:
|
|
| 19 |
print(f"Agent returning fixed answer: {fixed_answer}")
|
| 20 |
return fixed_answer
|
| 21 |
|
| 22 |
-
def run_and_submit_all( profile: gr.OAuthProfile | None):
|
| 23 |
-
"""
|
| 24 |
-
Fetches all questions, runs the BasicAgent on them, submits all answers,
|
| 25 |
-
and displays the results.
|
| 26 |
-
"""
|
| 27 |
-
# --- Determine HF Space Runtime URL and Repo URL ---
|
| 28 |
-
space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
|
| 29 |
-
|
| 30 |
-
if profile:
|
| 31 |
-
username= f"{profile.username}"
|
| 32 |
-
print(f"User logged in: {username}")
|
| 33 |
-
else:
|
| 34 |
-
print("User not logged in.")
|
| 35 |
-
return "Please Login to Hugging Face with the button.", None
|
| 36 |
-
|
| 37 |
-
api_url = DEFAULT_API_URL
|
| 38 |
-
questions_url = f"{api_url}/questions"
|
| 39 |
-
submit_url = f"{api_url}/submit"
|
| 40 |
|
| 41 |
-
|
| 42 |
try:
|
| 43 |
agent = BasicAgent()
|
| 44 |
except Exception as e:
|
| 45 |
print(f"Error instantiating agent: {e}")
|
| 46 |
return f"Error initializing agent: {e}", None
|
| 47 |
-
# In the case of an app running as a hugging Face space, this link points toward your codebase
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
-
# 2. Fetch Questions
|
| 52 |
print(f"Fetching questions from: {questions_url}")
|
| 53 |
try:
|
| 54 |
response = requests.get(questions_url, timeout=15)
|
|
@@ -68,8 +56,10 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
|
|
| 68 |
except Exception as e:
|
| 69 |
print(f"An unexpected error occurred fetching questions: {e}")
|
| 70 |
return f"An unexpected error occurred fetching questions: {e}", None
|
|
|
|
| 71 |
|
| 72 |
-
|
|
|
|
| 73 |
results_log = []
|
| 74 |
answers_payload = []
|
| 75 |
print(f"Running agent on {len(questions_data)} questions...")
|
|
@@ -90,14 +80,20 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
|
|
| 90 |
if not answers_payload:
|
| 91 |
print("Agent did not produce any answers to submit.")
|
| 92 |
return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
|
|
|
|
| 93 |
|
| 94 |
-
|
|
|
|
| 95 |
submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
|
| 96 |
status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
|
| 97 |
print(status_update)
|
|
|
|
| 98 |
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
| 101 |
try:
|
| 102 |
response = requests.post(submit_url, json=submission_data, timeout=60)
|
| 103 |
response.raise_for_status()
|
|
@@ -140,6 +136,38 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
|
|
| 140 |
return status_message, results_df
|
| 141 |
|
| 142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
# --- Build Gradio Interface using Blocks ---
|
| 144 |
with gr.Blocks() as demo:
|
| 145 |
gr.Markdown("# Basic Agent Evaluation Runner")
|
|
@@ -154,7 +182,9 @@ with gr.Blocks() as demo:
|
|
| 154 |
---
|
| 155 |
**Disclaimers:**
|
| 156 |
Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
|
| 157 |
-
This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution.
|
|
|
|
|
|
|
| 158 |
"""
|
| 159 |
)
|
| 160 |
|
|
|
|
| 8 |
# --- Constants ---
|
| 9 |
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
|
| 10 |
|
| 11 |
+
|
| 12 |
# --- Basic Agent Definition ---
|
| 13 |
# ----- THIS IS WHERE YOU CAN BUILD WHAT YOU WANT ------
|
| 14 |
class BasicAgent:
|
|
|
|
| 20 |
print(f"Agent returning fixed answer: {fixed_answer}")
|
| 21 |
return fixed_answer
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
+
def instantiate_agent(space_id: str):
|
| 25 |
try:
|
| 26 |
agent = BasicAgent()
|
| 27 |
except Exception as e:
|
| 28 |
print(f"Error instantiating agent: {e}")
|
| 29 |
return f"Error initializing agent: {e}", None
|
| 30 |
+
# In the case of an app running as a hugging Face space, this link points toward your codebase
|
| 31 |
+
# ( useful for others so please keep it public)
|
| 32 |
+
agent_code: str = f"https://huggingface.co/spaces/{space_id}/tree/main"
|
| 33 |
+
print(f"{agent_code=}")
|
| 34 |
+
return agent, agent_code
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def fetching_questions(api_url: str = DEFAULT_API_URL):
|
| 38 |
+
questions_url = f"{api_url}/questions"
|
| 39 |
|
|
|
|
| 40 |
print(f"Fetching questions from: {questions_url}")
|
| 41 |
try:
|
| 42 |
response = requests.get(questions_url, timeout=15)
|
|
|
|
| 56 |
except Exception as e:
|
| 57 |
print(f"An unexpected error occurred fetching questions: {e}")
|
| 58 |
return f"An unexpected error occurred fetching questions: {e}", None
|
| 59 |
+
return questions_data
|
| 60 |
|
| 61 |
+
|
| 62 |
+
def run_agent(agent, questions_data):
|
| 63 |
results_log = []
|
| 64 |
answers_payload = []
|
| 65 |
print(f"Running agent on {len(questions_data)} questions...")
|
|
|
|
| 80 |
if not answers_payload:
|
| 81 |
print("Agent did not produce any answers to submit.")
|
| 82 |
return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
|
| 83 |
+
return answers_payload, results_log
|
| 84 |
|
| 85 |
+
|
| 86 |
+
def prepare_submission_data(username:str, agent_code: str, answers_payload: list[dict]):
|
| 87 |
submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
|
| 88 |
status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
|
| 89 |
print(status_update)
|
| 90 |
+
return submission_data
|
| 91 |
|
| 92 |
+
|
| 93 |
+
def submit_answers(submission_data, results_log, api_url: str = DEFAULT_API_URL):
|
| 94 |
+
submit_url = f"{api_url}/submit"
|
| 95 |
+
|
| 96 |
+
print(f"Submitting {len(submission_data.get("answers"))} answers to: {submit_url}")
|
| 97 |
try:
|
| 98 |
response = requests.post(submit_url, json=submission_data, timeout=60)
|
| 99 |
response.raise_for_status()
|
|
|
|
| 136 |
return status_message, results_df
|
| 137 |
|
| 138 |
|
| 139 |
+
def run_and_submit_all( profile: gr.OAuthProfile | None):
|
| 140 |
+
"""
|
| 141 |
+
Fetches all questions, runs the BasicAgent on them, submits all answers,
|
| 142 |
+
and displays the results.
|
| 143 |
+
"""
|
| 144 |
+
# --- Determine HF Space Runtime URL and Repo URL ---
|
| 145 |
+
space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
|
| 146 |
+
|
| 147 |
+
if profile:
|
| 148 |
+
username= f"{profile.username}"
|
| 149 |
+
print(f"User logged in: {username}")
|
| 150 |
+
else:
|
| 151 |
+
print("User not logged in.")
|
| 152 |
+
return "Please Login to Hugging Face with the button.", None
|
| 153 |
+
|
| 154 |
+
# 1. Instantiate Agent ( modify this part to create your agent)
|
| 155 |
+
agent, agent_code = instantiate_agent(space_id)
|
| 156 |
+
|
| 157 |
+
# 2. Fetch Questions
|
| 158 |
+
questions_data = fetching_questions()
|
| 159 |
+
|
| 160 |
+
# 3. Run your Agent
|
| 161 |
+
answers_payload, results_log = run_agent(agent, questions_data)
|
| 162 |
+
|
| 163 |
+
# 4. Prepare submissions
|
| 164 |
+
submission_data = prepare_submission_data(username, agent_code, answers_payload)
|
| 165 |
+
|
| 166 |
+
# 5. Submit
|
| 167 |
+
result_or_output_message, results_df = submit_answers(submission_data, results_log)
|
| 168 |
+
return result_or_output_message, results_df
|
| 169 |
+
|
| 170 |
+
|
| 171 |
# --- Build Gradio Interface using Blocks ---
|
| 172 |
with gr.Blocks() as demo:
|
| 173 |
gr.Markdown("# Basic Agent Evaluation Runner")
|
|
|
|
| 182 |
---
|
| 183 |
**Disclaimers:**
|
| 184 |
Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
|
| 185 |
+
This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution.
|
| 186 |
+
For instance for the delay process of the submit button, a solution could be to cache the answers and
|
| 187 |
+
submit in a separate action or even to answer the questions in async.
|
| 188 |
"""
|
| 189 |
)
|
| 190 |
|