Spaces:
Sleeping
Sleeping
File size: 3,010 Bytes
c5292d8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | """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
@retry(
stop=stop_after_attempt(4),
wait=wait_exponential(multiplier=1, min=1, max=8),
reraise=True,
)
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
|