Spaces:
Sleeping
Sleeping
| """Client for sending notifications to evaluation URL.""" | |
| import asyncio | |
| from typing import Any | |
| import httpx | |
| from tenacity import retry, stop_after_attempt, wait_exponential | |
| from shared.config import settings | |
| from shared.logger import setup_logger | |
| from shared.models import RepoSubmission | |
| logger = setup_logger(__name__) | |
| class NotificationClient: | |
| """Client for notifying evaluation endpoint about repo submissions.""" | |
| def __init__(self) -> None: | |
| """Initialize notification client.""" | |
| self.retry_delays = settings.get_retry_delays() | |
| self.max_retries = settings.max_retry_attempts | |
| async def notify(self, evaluation_url: str, submission: RepoSubmission) -> bool: | |
| """Send repo submission to evaluation URL with retry logic. | |
| Args: | |
| evaluation_url: URL to send notification to | |
| submission: Repository submission data | |
| Returns: | |
| True if successful, False otherwise | |
| """ | |
| logger.info(f"Sending notification to {evaluation_url}") | |
| logger.debug(f"Submission data: {submission.model_dump()}") | |
| try: | |
| async with httpx.AsyncClient(timeout=30.0) as client: | |
| response = await client.post( | |
| evaluation_url, | |
| json=submission.model_dump(), | |
| headers={"Content-Type": "application/json"}, | |
| ) | |
| if response.status_code == 200: | |
| logger.info(f"Successfully notified {evaluation_url}") | |
| return True | |
| else: | |
| logger.error( | |
| f"Failed to notify {evaluation_url}: " | |
| f"Status {response.status_code}, Response: {response.text}" | |
| ) | |
| raise Exception(f"HTTP {response.status_code}: {response.text}") | |
| except httpx.TimeoutException: | |
| logger.error(f"Timeout while notifying {evaluation_url}") | |
| raise | |
| except Exception as e: | |
| logger.error(f"Error notifying {evaluation_url}: {e}") | |
| raise | |
| async def notify_with_timeout( | |
| self, evaluation_url: str, submission: RepoSubmission, timeout_minutes: int = 10 | |
| ) -> bool: | |
| """Send notification with overall timeout. | |
| Args: | |
| evaluation_url: URL to send notification to | |
| submission: Repository submission data | |
| timeout_minutes: Overall timeout in minutes | |
| Returns: | |
| True if successful, False otherwise | |
| """ | |
| try: | |
| return await asyncio.wait_for( | |
| self.notify(evaluation_url, submission), | |
| timeout=timeout_minutes * 60, | |
| ) | |
| except asyncio.TimeoutError: | |
| logger.error(f"Overall timeout of {timeout_minutes} minutes exceeded") | |
| return False | |