|
|
""" |
|
|
Deploy Helper Module for communicating with evaluation APIs |
|
|
""" |
|
|
|
|
|
import os |
|
|
import logging |
|
|
import httpx |
|
|
from typing import Dict, Any, Optional |
|
|
from datetime import datetime |
|
|
import json |
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
class DeployHelper: |
|
|
def __init__(self): |
|
|
self.timeout = 30.0 |
|
|
|
|
|
async def notify_evaluation_api(self, |
|
|
evaluation_url: str, |
|
|
email: str, |
|
|
task: str, |
|
|
round_num: int, |
|
|
nonce: str, |
|
|
repo_data: Dict[str, Any], |
|
|
app_metadata: Dict[str, Any]) -> Dict[str, Any]: |
|
|
""" |
|
|
Send deployment metadata to the evaluation API |
|
|
""" |
|
|
try: |
|
|
|
|
|
payload = { |
|
|
"email": email, |
|
|
"task": task, |
|
|
"round": round_num, |
|
|
"nonce": nonce, |
|
|
"timestamp": datetime.utcnow().isoformat(), |
|
|
"deployment": { |
|
|
"repo_name": repo_data.get("repo_name"), |
|
|
"repo_url": repo_data.get("repo_url"), |
|
|
"commit_sha": repo_data.get("commit_sha"), |
|
|
"pages_url": repo_data.get("pages_url"), |
|
|
"success": repo_data.get("success", False) |
|
|
}, |
|
|
"app_metadata": app_metadata |
|
|
} |
|
|
|
|
|
logger.info(f"Sending evaluation notification to: {evaluation_url}") |
|
|
logger.info(f"Payload: {json.dumps(payload, indent=2)}") |
|
|
|
|
|
|
|
|
async with httpx.AsyncClient(timeout=self.timeout) as client: |
|
|
response = await client.post( |
|
|
evaluation_url, |
|
|
json=payload, |
|
|
headers={ |
|
|
"Content-Type": "application/json", |
|
|
"User-Agent": "LLM-Code-Deployment/1.0" |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
logger.info(f"Evaluation API response status: {response.status_code}") |
|
|
logger.info(f"Evaluation API response: {response.text}") |
|
|
|
|
|
if response.status_code == 200: |
|
|
return { |
|
|
"success": True, |
|
|
"status_code": response.status_code, |
|
|
"response": response.json() if response.headers.get("content-type", "").startswith("application/json") else response.text |
|
|
} |
|
|
else: |
|
|
return { |
|
|
"success": False, |
|
|
"status_code": response.status_code, |
|
|
"error": f"Evaluation API returned status {response.status_code}: {response.text}" |
|
|
} |
|
|
|
|
|
except httpx.TimeoutException: |
|
|
logger.error(f"Timeout while calling evaluation API: {evaluation_url}") |
|
|
return { |
|
|
"success": False, |
|
|
"error": "Request timeout" |
|
|
} |
|
|
except httpx.RequestError as e: |
|
|
logger.error(f"Request error while calling evaluation API: {e}") |
|
|
return { |
|
|
"success": False, |
|
|
"error": f"Request error: {str(e)}" |
|
|
} |
|
|
except Exception as e: |
|
|
logger.error(f"Unexpected error while calling evaluation API: {e}") |
|
|
return { |
|
|
"success": False, |
|
|
"error": f"Unexpected error: {str(e)}" |
|
|
} |
|
|
|
|
|
def validate_evaluation_url(self, url: str) -> bool: |
|
|
""" |
|
|
Basic validation of evaluation URL |
|
|
""" |
|
|
try: |
|
|
if not url or not isinstance(url, str): |
|
|
return False |
|
|
|
|
|
|
|
|
if not (url.startswith("http://") or url.startswith("https://")): |
|
|
return False |
|
|
|
|
|
|
|
|
if "." not in url.replace("://", ""): |
|
|
return False |
|
|
|
|
|
return True |
|
|
|
|
|
except Exception: |
|
|
return False |
|
|
|
|
|
def format_deployment_summary(self, |
|
|
repo_data: Dict[str, Any], |
|
|
app_metadata: Dict[str, Any]) -> str: |
|
|
""" |
|
|
Format a human-readable deployment summary |
|
|
""" |
|
|
summary = f""" |
|
|
π Deployment Summary |
|
|
==================== |
|
|
|
|
|
Repository: {repo_data.get('repo_name', 'N/A')} |
|
|
Repository URL: {repo_data.get('repo_url', 'N/A')} |
|
|
GitHub Pages: {repo_data.get('pages_url', 'N/A')} |
|
|
Commit SHA: {repo_data.get('commit_sha', 'N/A')[:8]}... |
|
|
Status: {'β
Success' if repo_data.get('success') else 'β Failed'} |
|
|
|
|
|
App Metadata: |
|
|
- Title: {app_metadata.get('title', 'N/A')} |
|
|
- Description: {app_metadata.get('description', 'N/A')} |
|
|
- Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')} |
|
|
""" |
|
|
return summary.strip() |
|
|
|