Download app.py from agents-course/Final_Assignment_Template: direct link, hf CLI and curl.
- Browser
- Download file 6.35 kB
-
https://huggingface.co/spaces/agents-course/Final_Assignment_Template/resolve/refs%2Fpr%2F636/app.py
- Command line
-
hf download hf://spaces/agents-course/Final_Assignment_Template@refs/pr/636/app.py
-
curl -L -o app.py https://huggingface.co/spaces/agents-course/Final_Assignment_Template/resolve/refs%2Fpr%2F636/app.py
6.35 kB
| import os | |
| import re | |
| import tempfile | |
| import gradio as gr | |
| import pandas as pd | |
| import requests | |
| from smolagents import ( | |
| CodeAgent, | |
| DuckDuckGoSearchTool, | |
| VisitWebpageTool, | |
| tool, | |
| ) | |
| try: | |
| from smolagents import InferenceClientModel as HFModel | |
| except ImportError: # older smolagents versions | |
| from smolagents import HfApiModel as HFModel | |
| # --- Constants --- | |
| DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space" | |
| MODEL_ID = os.getenv("MODEL_ID", "Qwen/Qwen2.5-Coder-32B-Instruct") | |
| # --- Tools --- | |
| def get_task_file(task_id: str) -> str: | |
| """Download the file attached to a task (if any) and return its content or local path. | |
| Args: | |
| task_id: The task_id of the question that has an attached file. | |
| """ | |
| try: | |
| r = requests.get(f"{DEFAULT_API_URL}/files/{task_id}", timeout=60) | |
| r.raise_for_status() | |
| except Exception as e: | |
| return f"No file could be downloaded for this task: {e}" | |
| disposition = r.headers.get("content-disposition", "") | |
| match = re.search(r'filename="?([^";]+)"?', disposition) | |
| name = match.group(1) if match else f"{task_id}.bin" | |
| path = os.path.join(tempfile.gettempdir(), name) | |
| with open(path, "wb") as f: | |
| f.write(r.content) | |
| lower = name.lower() | |
| try: | |
| if lower.endswith((".xlsx", ".xls")): | |
| sheets = pd.read_excel(path, sheet_name=None) | |
| return "\n\n".join( | |
| f"Sheet '{s}':\n{df.to_string()}" for s, df in sheets.items() | |
| )[:20000] | |
| if lower.endswith((".txt", ".csv", ".py", ".json", ".md")): | |
| return r.content.decode("utf-8", errors="replace")[:20000] | |
| except Exception as e: | |
| return f"File saved at {path} but could not be parsed: {e}" | |
| return ( | |
| f"File saved at {path} (type: {name.split('.')[-1]}). " | |
| "It is a binary file (image/audio/other); handle it with Python code." | |
| ) | |
| SYSTEM_HINT = """You are solving GAIA-style questions. Rules: | |
| - Use tools (web search, visiting pages, reading attached files, Python) to find the answer. | |
| - Your final answer must be ONLY the answer: a number, a short string, or a comma-separated list. | |
| - Do NOT write 'FINAL ANSWER', explanations, units unless asked, or full sentences. | |
| - Numbers: no thousands separators, no currency/percent symbols unless asked. | |
| - Strings: no articles (a, the) and no abbreviations unless asked. | |
| - Lists: comma-separated, in the order requested. | |
| - If the question mentions an attached file, call get_task_file with the given task_id. | |
| """ | |
| # --- Agent --- | |
| class BasicAgent: | |
| def __init__(self): | |
| model = HFModel(model_id=MODEL_ID, token=os.getenv("HF_TOKEN")) | |
| self.agent = CodeAgent( | |
| tools=[DuckDuckGoSearchTool(), VisitWebpageTool(), get_task_file], | |
| model=model, | |
| additional_authorized_imports=[ | |
| "pandas", "numpy", "requests", "re", "json", | |
| "datetime", "math", "bs4", "collections", "itertools", | |
| ], | |
| max_steps=12, | |
| ) | |
| def __call__(self, question: str, task_id: str = "", has_file: bool = False) -> str: | |
| prompt = f"{SYSTEM_HINT}\n\ntask_id: {task_id}\n" | |
| if has_file: | |
| prompt += "This task has an attached file (use get_task_file).\n" | |
| prompt += f"\nQuestion: {question}" | |
| answer = str(self.agent.run(prompt)).strip() | |
| answer = re.sub(r"(?i)^\s*final answer\s*:\s*", "", answer) | |
| return answer.strip().rstrip(".") if len(answer) > 1 else answer | |
| # --- Run & submit --- | |
| def run_and_submit_all(profile: gr.OAuthProfile | None): | |
| space_id = os.getenv("SPACE_ID") | |
| if not profile: | |
| return "Please log in to Hugging Face with the button.", None | |
| username = profile.username | |
| api_url = DEFAULT_API_URL | |
| agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main" | |
| try: | |
| agent = BasicAgent() | |
| except Exception as e: | |
| return f"Error initializing agent: {e}", None | |
| try: | |
| response = requests.get(f"{api_url}/questions", timeout=30) | |
| response.raise_for_status() | |
| questions = response.json() | |
| except Exception as e: | |
| return f"Error fetching questions: {e}", None | |
| results_log, answers_payload = [], [] | |
| for item in questions: | |
| task_id = item.get("task_id") | |
| question = item.get("question") | |
| has_file = bool(item.get("file_name")) | |
| if not task_id or question is None: | |
| continue | |
| try: | |
| answer = agent(question, task_id=task_id, has_file=has_file) | |
| except Exception as e: | |
| answer = f"AGENT ERROR: {e}" | |
| answers_payload.append({"task_id": task_id, "submitted_answer": answer}) | |
| results_log.append( | |
| {"Task ID": task_id, "Question": question, "Submitted Answer": answer} | |
| ) | |
| if not answers_payload: | |
| return "Agent produced no answers.", pd.DataFrame(results_log) | |
| submission = { | |
| "username": username.strip(), | |
| "agent_code": agent_code, | |
| "answers": answers_payload, | |
| } | |
| try: | |
| resp = requests.post(f"{api_url}/submit", json=submission, timeout=120) | |
| resp.raise_for_status() | |
| data = resp.json() | |
| status = ( | |
| f"Submission successful!\n" | |
| f"User: {data.get('username')}\n" | |
| f"Score: {data.get('score')}% " | |
| f"({data.get('correct_count')}/{data.get('total_attempted')} correct)\n" | |
| f"Message: {data.get('message')}" | |
| ) | |
| return status, pd.DataFrame(results_log) | |
| except Exception as e: | |
| return f"Submission failed: {e}", pd.DataFrame(results_log) | |
| # --- Gradio UI --- | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Agents Course - Final Assignment") | |
| gr.Markdown( | |
| "1. Log in with your Hugging Face account.\n" | |
| "2. Click the button to run the agent on all questions and submit.\n" | |
| "This can take several minutes." | |
| ) | |
| gr.LoginButton() | |
| run_button = gr.Button("Run Evaluation & Submit All Answers") | |
| status_output = gr.Textbox(label="Run Status / Submission Result", lines=5) | |
| results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True) | |
| run_button.click(fn=run_and_submit_all, outputs=[status_output, results_table]) | |
| if __name__ == "__main__": | |
| demo.launch(debug=True, share=False) |