Spaces:
Sleeping
Sleeping
| """ | |
| Evaluation API notification with retry logic | |
| Sends deployment metadata to evaluation endpoint | |
| """ | |
| import requests | |
| import time | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| def notify_evaluation_api( | |
| evaluation_url: str, | |
| email: str, | |
| task: str, | |
| round: int, | |
| nonce: str, | |
| repo_url: str, | |
| commit_sha: str, | |
| pages_url: str, | |
| max_retries: int = 5 | |
| ) -> bool: | |
| """ | |
| Notify evaluation API with deployment details | |
| Implements exponential backoff retry logic | |
| Args: | |
| evaluation_url: Evaluation API endpoint | |
| email: Student email | |
| task: Task identifier | |
| round: Round number (1 or 2) | |
| nonce: Security nonce from request | |
| repo_url: GitHub repository URL | |
| commit_sha: Latest commit SHA | |
| pages_url: GitHub Pages URL | |
| max_retries: Maximum retry attempts | |
| Returns: | |
| True if notification successful, False otherwise | |
| """ | |
| payload = { | |
| "email": email, | |
| "task": task, | |
| "round": round, | |
| "nonce": nonce, | |
| "repo_url": repo_url, | |
| "commit_sha": commit_sha, | |
| "pages_url": pages_url | |
| } | |
| headers = { | |
| "Content-Type": "application/json" | |
| } | |
| # Exponential backoff: 1, 2, 4, 8, 16 seconds | |
| for attempt in range(max_retries): | |
| try: | |
| logger.info(f"Notifying evaluation API (attempt {attempt + 1}/{max_retries})...") | |
| logger.info(f"URL: {evaluation_url}") | |
| logger.info(f"Payload: {payload}") | |
| response = requests.post( | |
| evaluation_url, | |
| json=payload, | |
| headers=headers, | |
| timeout=30 | |
| ) | |
| if response.status_code == 200: | |
| logger.info(f"✓ Evaluation API returned HTTP 200") | |
| logger.info(f"Response: {response.text}") | |
| return True | |
| else: | |
| logger.warning(f"Evaluation API returned HTTP {response.status_code}") | |
| logger.warning(f"Response: {response.text}") | |
| # Don't retry on 4xx errors (client errors) | |
| if 400 <= response.status_code < 500: | |
| logger.error("Client error - not retrying") | |
| return False | |
| except requests.exceptions.Timeout: | |
| logger.warning(f"Request timeout on attempt {attempt + 1}") | |
| except requests.exceptions.ConnectionError as e: | |
| logger.warning(f"Connection error on attempt {attempt + 1}: {e}") | |
| except Exception as e: | |
| logger.error(f"Unexpected error on attempt {attempt + 1}: {e}") | |
| # Exponential backoff (except on last attempt) | |
| if attempt < max_retries - 1: | |
| wait_time = 2 ** attempt | |
| logger.info(f"Retrying in {wait_time} seconds...") | |
| time.sleep(wait_time) | |
| logger.error(f"✗ Failed to notify evaluation API after {max_retries} attempts") | |
| return False | |