# [dev_251222_01] API Integration Guide **Date:** 2025-12-22 **Type:** 🔨 Development **Status:** 🔄 In Progress **Related Dev:** N/A (Initial documentation) ## Problem Description As a beginner learning API integration, needed comprehensive documentation of the GAIA scoring API to understand how to properly interact with all endpoints. The existing code only uses 2 of 4 available endpoints, missing critical file download functionality that many GAIA questions require. --- ## API Overview **Base URL:** `https://agents-course-unit4-scoring.hf.space` **Purpose:** GAIA benchmark evaluation system that provides test questions, accepts agent answers, calculates scores, and maintains leaderboards. **Documentation Format:** FastAPI with Swagger UI (OpenAPI specification) **Authentication:** None required (public API) ## Complete Endpoint Reference ### Endpoint 1: GET /questions **Purpose:** Retrieve complete list of all GAIA test questions **Request:** ```python import requests api_url = "https://agents-course-unit4-scoring.hf.space" response = requests.get(f"{api_url}/questions", timeout=15) questions = response.json() ``` **Parameters:** None **Response Format:** ```json [ { "task_id": "string", "question": "string", "level": "integer (1-3)", "file_name": "string or null", "file_path": "string or null", ...additional metadata... } ] ``` **Response Codes:** - 200: Success - Returns array of question objects - 500: Server error **Key Fields:** - `task_id`: Unique identifier for each question (required for submission) - `question`: The actual question text your agent needs to answer - `level`: Difficulty level (1=easy, 2=medium, 3=hard) - `file_name`: Name of attached file if question includes one (null if no file) - `file_path`: Path to file on server (null if no file) **Current Implementation:** ✅ Already implemented in app.py:41-73 **Usage in Your Code:** ```python # Existing code location: app.py:54-66 response = requests.get(questions_url, timeout=15) response.raise_for_status() questions_data = response.json() ``` --- ### Endpoint 2: GET /random-question **Purpose:** Get single random question for testing/debugging **Request:** ```python import requests api_url = "https://agents-course-unit4-scoring.hf.space" response = requests.get(f"{api_url}/random-question", timeout=15) question = response.json() ``` **Parameters:** None **Response Format:** ```json { "task_id": "string", "question": "string", "level": "integer", "file_name": "string or null", "file_path": "string or null" } ``` **Response Codes:** - 200: Success - Returns single question object - 404: No questions available - 500: Server error **Current Implementation:** ❌ Not implemented **Use Cases:** - Quick testing during agent development - Debugging specific question types - Iterative development without processing all questions **Example Implementation:** ```python def test_agent_on_random_question(agent): """Test agent on a single random question""" api_url = "https://agents-course-unit4-scoring.hf.space" response = requests.get(f"{api_url}/random-question", timeout=15) if response.status_code == 404: return "No questions available" response.raise_for_status() question_data = response.json() task_id = question_data.get("task_id") question_text = question_data.get("question") answer = agent(question_text) print(f"Task: {task_id}") print(f"Question: {question_text}") print(f"Agent Answer: {answer}") return answer ``` --- ### Endpoint 3: POST /submit **Purpose:** Submit all agent answers for evaluation and receive score **Request:** ```python import requests api_url = "https://agents-course-unit4-scoring.hf.space" submission_data = { "username": "your-hf-username", "agent_code": "https://huggingface.co/spaces/your-space/tree/main", "answers": [ {"task_id": "task_001", "submitted_answer": "42"}, {"task_id": "task_002", "submitted_answer": "Paris"} ] } response = requests.post( f"{api_url}/submit", json=submission_data, timeout=60 ) result = response.json() ``` **Request Body Schema:** ```json { "username": "string (required)", "agent_code": "string (min 10 chars, required)", "answers": [ { "task_id": "string (required)", "submitted_answer": "string | number | integer (required)" } ] } ``` **Field Requirements:** - `username`: Your Hugging Face username (obtained from OAuth profile) - `agent_code`: URL to your agent's source code (typically HF Space repo URL) - `answers`: Array of answer objects, one per question - `task_id`: Must match task_id from /questions endpoint - `submitted_answer`: Can be string, integer, or number depending on question **Response Format:** ```json { "username": "string", "score": 85.5, "correct_count": 17, "total_attempted": 20, "message": "Submission successful!", "timestamp": "2025-12-22T10:30:00.123Z" } ``` **Response Codes:** - 200: Success - Returns score and statistics - 400: Invalid input (missing fields, wrong format) - 404: One or more task_ids not found - 500: Server error **Current Implementation:** ✅ Already implemented in app.py:112-161 **Usage in Your Code:** ```python # Existing code location: app.py:112-135 submission_data = { "username": username.strip(), "agent_code": agent_code, "answers": answers_payload, } response = requests.post(submit_url, json=submission_data, timeout=60) response.raise_for_status() result_data = response.json() ``` **Important Notes:** - Timeout set to 60 seconds (longer than /questions because scoring takes time) - All answers must be submitted together in single request - Score is calculated immediately and returned in response - Results also update the public leaderboard --- ### Endpoint 4: GET /files/{task_id} **Purpose:** Download files attached to questions (images, PDFs, data files, etc.) **Request:** ```python import requests api_url = "https://agents-course-unit4-scoring.hf.space" task_id = "task_001" response = requests.get(f"{api_url}/files/{task_id}", timeout=30) # Save file to disk with open(f"downloaded_{task_id}.file", "wb") as f: f.write(response.content) ``` **Parameters:** - `task_id` (string, required, path parameter): The task_id of the question **Response Format:** - Binary file content (could be image, PDF, CSV, JSON, etc.) - Content-Type header indicates file type **Response Codes:** - 200: Success - Returns file content - 403: Access denied (path traversal attempt blocked) - 404: Task not found OR task has no associated file - 500: Server error **Current Implementation:** ❌ Not implemented - THIS IS CRITICAL GAP **Why This Matters:** Many GAIA questions include attached files that contain essential information for answering the question. Without downloading these files, your agent cannot answer those questions correctly. **Detection Logic:** ```python # Check if question has an attached file question_data = { "task_id": "task_001", "question": "What is shown in the image?", "file_name": "image.png", # Not null = file exists "file_path": "/files/task_001" # Path to file } has_file = question_data.get("file_name") is not None ``` **Example Implementation:** ```python def download_task_file(task_id, save_dir="input/"): """Download file associated with a task_id""" api_url = "https://agents-course-unit4-scoring.hf.space" file_url = f"{api_url}/files/{task_id}" try: response = requests.get(file_url, timeout=30) response.raise_for_status() # Determine file extension from Content-Type or use generic content_type = response.headers.get('Content-Type', '') extension_map = { 'image/png': '.png', 'image/jpeg': '.jpg', 'application/pdf': '.pdf', 'text/csv': '.csv', 'application/json': '.json', } extension = extension_map.get(content_type, '.file') # Save file file_path = f"{save_dir}{task_id}{extension}" with open(file_path, 'wb') as f: f.write(response.content) print(f"Downloaded file for {task_id}: {file_path}") return file_path except requests.exceptions.HTTPError as e: if e.response.status_code == 404: print(f"No file found for task {task_id}") return None raise ``` **Integration Example:** ```python # Enhanced agent workflow for item in questions_data: task_id = item.get("task_id") question_text = item.get("question") file_name = item.get("file_name") # Download file if question has one file_path = None if file_name: file_path = download_task_file(task_id) # Pass both question and file to agent answer = agent(question_text, file_path=file_path) ``` --- ## API Request Flow Diagram ``` Student Agent Workflow: ┌─────────────────────────────────────────────────────────────┐ │ 1. Fetch Questions │ │ GET /questions │ │ → Receive list of all questions with metadata │ └────────────────────┬────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. Process Each Question │ │ For each question: │ │ a) Check if file_name exists │ │ b) If yes: GET /files/{task_id} │ │ → Download and save file │ │ c) Pass question + file to agent │ │ d) Agent generates answer │ └────────────────────┬────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. Submit All Answers │ │ POST /submit │ │ → Send username, agent_code, and all answers │ │ → Receive score and statistics │ └─────────────────────────────────────────────────────────────┘ ``` ## Error Handling Best Practices ### Connection Errors ```python try: response = requests.get(url, timeout=15) response.raise_for_status() except requests.exceptions.Timeout: print("Request timed out") except requests.exceptions.ConnectionError: print("Network connection error") except requests.exceptions.HTTPError as e: print(f"HTTP error: {e.response.status_code}") ``` ### Response Validation ```python # Always validate response format response = requests.get(questions_url) response.raise_for_status() try: data = response.json() except requests.exceptions.JSONDecodeError: print("Invalid JSON response") print(f"Response text: {response.text[:500]}") ``` ### Timeout Recommendations - GET /questions: 15 seconds (fetching list) - GET /random-question: 15 seconds (single question) - GET /files/{task_id}: 30 seconds (file download may be larger) - POST /submit: 60 seconds (scoring all answers takes time) ## Current Implementation Status ### ✅ Implemented Endpoints 1. **GET /questions** - Fully implemented in app.py:41-73 2. **POST /submit** - Fully implemented in app.py:112-161 ### ❌ Missing Endpoints 1. **GET /random-question** - Not implemented (useful for testing) 2. **GET /files/{task_id}** - Not implemented (CRITICAL - many questions need files) ### 🚨 Critical Gap Analysis **Impact of Missing /files Endpoint:** - Questions with attached files cannot be answered correctly - Agent will only see question text, not the actual content to analyze - Significantly reduces potential score on GAIA benchmark **Example Questions That Need Files:** - "What is shown in this image?" → Needs image file - "What is the total in column B?" → Needs spreadsheet file - "Summarize this document" → Needs PDF/text file - "What patterns do you see in this data?" → Needs CSV/JSON file **Estimated Impact:** - GAIA benchmark: ~30-40% of questions include files - Without file handling: Maximum achievable score ~60-70% - With file handling: Can potentially achieve 100% ## Next Steps for Implementation ### Priority 1: Add File Download Support 1. Detect questions with files (check `file_name` field) 2. Download files using GET /files/{task_id} 3. Save files to input/ directory 4. Modify BasicAgent to accept file_path parameter 5. Update agent logic to process files ### Priority 2: Add Testing Endpoint 1. Implement GET /random-question for quick testing 2. Create test script in test/ directory 3. Enable iterative development without full evaluation runs ### Priority 3: Enhanced Error Handling 1. Add retry logic for network failures 2. Validate file downloads (check file size, type) 3. Handle partial failures gracefully ## How to Read FastAPI Swagger Documentation ### Understanding the Swagger UI FastAPI APIs use Swagger UI for interactive documentation. Here's how to read it systematically: ### Main UI Components #### 1. Header Section ``` Agent Evaluation API [0.1.0] [OAS 3.1] /openapi.json ``` **What you learn:** - **API Name:** Service identification - **Version:** `0.1.0` - API version (important for tracking changes) - **OAS 3.1:** OpenAPI Specification standard version - **Link:** `/openapi.json` - raw machine-readable specification #### 2. API Description High-level summary of what the service provides #### 3. Endpoints Section (Expandable List) **HTTP Method Colors:** - **Blue "GET"** = Retrieve/fetch data (read-only, safe to call multiple times) - **Green "POST"** = Submit/create data (writes data, may change state) - **Orange "PUT"** = Update existing data - **Red "DELETE"** = Remove data **Each endpoint shows:** - Path (URL structure) - Short description - Click to expand for details #### 4. Expanded Endpoint Details When you click an endpoint, you get: **Section A: Description** - Detailed explanation of functionality - Use cases and purpose **Section B: Parameters** - **Path Parameters:** Variables in URL like `/files/{task_id}` - **Query Parameters:** Key-value pairs after `?` like `?level=1&limit=10` - Each parameter shows: - Name - Type (string, integer, boolean, etc.) - Required vs Optional - Description - Example values **Section C: Request Body** (POST/PUT only) - JSON structure to send - Field names and types - Required vs optional fields - Example payload - Schema button shows structure **Section D: Responses** - Status codes (200, 400, 404, 500) - Response structure for each code - Example responses - What each status means **Section E: Try It Out Button** - Test API directly in browser - Fill parameters and send real requests - See actual responses #### 5. Schemas Section (Bottom) Reusable data structures used across endpoints: ``` Schemas ├─ AnswerItem ├─ ErrorResponse ├─ ScoreResponse └─ Submission ``` Click each to see: - All fields in the object - Field types and constraints - Required vs optional - Descriptions ### Step-by-Step: Reading One Endpoint **Example: POST /submit** **Step 1:** Click the endpoint to expand **Step 2:** Read description *"Submit agent answers, calculate scores, and update leaderboard"* **Step 3:** Check Parameters - Path parameters? None (URL is just `/submit`) - Query parameters? None **Step 4:** Check Request Body ```json { "username": "string (required)", "agent_code": "string, min 10 chars (required)", "answers": [ { "task_id": "string (required)", "submitted_answer": "string | number | integer (required)" } ] } ``` **Step 5:** Check Responses **200 Success:** ```json { "username": "string", "score": 85.5, "correct_count": 15, "total_attempted": 20, "message": "Success!" } ``` **Other codes:** - 400: Invalid input - 404: Task ID not found - 500: Server error **Step 6:** Write Python code ```python url = "https://agents-course-unit4-scoring.hf.space/submit" payload = { "username": "your-username", "agent_code": "https://...", "answers": [ {"task_id": "task_001", "submitted_answer": "42"} ] } response = requests.post(url, json=payload, timeout=60) result = response.json() ``` ### Information Extraction Checklist For each endpoint, extract: **Basic Info:** - HTTP method (GET, POST, PUT, DELETE) - Endpoint path (URL) - One-line description **Request Details:** - Path parameters (variables in URL) - Query parameters (after ? in URL) - Request body structure (POST/PUT) - Required vs optional fields - Data types and constraints **Response Details:** - Success response structure (200) - Success response example - All possible status codes - Error response structures - What each status code means **Additional Info:** - Authentication requirements - Rate limits - Example requests - Related schemas ### Pro Tips **Tip 1: Start with GET endpoints** Simpler (no request body) and safe to test **Tip 2: Use "Try it out" button** Best way to learn - send real requests and see responses **Tip 3: Check Schemas section** Understanding schemas helps decode complex structures **Tip 4: Copy examples** Most Swagger UIs have example values - use them! **Tip 5: Required vs Optional** Required fields cause 400 error if missing **Tip 6: Read error responses** They tell you what went wrong and how to fix it ### Practice Exercise **Try reading GET /files/{task_id}:** 1. What HTTP method? → GET 2. What's the path parameter? → `task_id` (string, required) 3. What does it return? → File content (binary) 4. What status codes? → 200, 403, 404, 500 5. Python code? → `requests.get(f"{api_url}/files/{task_id}")` ## Learning Resources **Understanding REST APIs:** - REST = Representational State Transfer - APIs communicate using HTTP methods: GET (retrieve), POST (submit), PUT (update), DELETE (remove) - Data typically exchanged in JSON format **Key Concepts:** - **Endpoint:** Specific URL path that performs one action (/questions, /submit) - **Request:** Data you send to the API (parameters, body) - **Response:** Data the API sends back (JSON, files, status codes) - **Status Codes:** - 200 = Success - 400 = Bad request (your input was wrong) - 404 = Not found - 500 = Server error **Python Requests Library:** ```python # GET request - retrieve data response = requests.get(url, params={...}, timeout=15) # POST request - submit data response = requests.post(url, json={...}, timeout=60) # Always check status response.raise_for_status() # Raises error if status >= 400 # Parse JSON response data = response.json() ``` --- ## Key Decisions - **Documentation Structure:** Organized by endpoint with complete examples for each - **Learning Approach:** Beginner-friendly explanations with code examples - **Priority Focus:** Highlighted critical missing functionality (file downloads) - **Practical Examples:** Included copy-paste ready code snippets ## Outcome Created comprehensive API integration guide documenting all 4 endpoints of the GAIA scoring API, identified critical gap in current implementation (missing file download support), and provided actionable examples for enhancement. **Deliverables:** - `dev/dev_251222_01_api_integration_guide.md` - Complete API reference documentation ## Changelog **What was changed:** - Created new documentation file: dev_251222_01_api_integration_guide.md - Documented all 4 API endpoints with request/response formats - Added code examples for each endpoint - Identified critical missing functionality (file downloads) - Provided implementation roadmap for enhancements