temp / student /notification_client.py
CheeksTheGeek's picture
Initial commit: LLM Code Deployment System
c5292d8 unverified
Raw
History Blame Contribute Delete
3.01 kB
"""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