Spaces:
Sleeping
Sleeping
File size: 3,066 Bytes
42f12bd | 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 88 89 90 91 92 93 94 95 96 97 98 99 100 | """
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
|