|
| 1 | +from typing import Any |
| 2 | + |
1 | 3 | import requests |
2 | | -from fastapi import HTTPException |
| 4 | +from fastapi import HTTPException, UploadFile |
3 | 5 |
|
4 | 6 | from kernelbot.env import env |
5 | 7 | from libkernelbot.backend import KernelBackend |
6 | 8 | from libkernelbot.consts import SubmissionMode |
| 9 | +from libkernelbot.leaderboard_db import LeaderboardDB |
7 | 10 | from libkernelbot.report import ( |
8 | 11 | Log, |
9 | 12 | MultiProgressReporter, |
10 | 13 | RunProgressReporter, |
11 | 14 | RunResultReport, |
12 | 15 | Text, |
13 | 16 | ) |
14 | | -from libkernelbot.submission import SubmissionRequest, prepare_submission |
| 17 | +from libkernelbot.submission import ( |
| 18 | + SubmissionRequest, |
| 19 | + prepare_submission, |
| 20 | +) |
15 | 21 |
|
16 | 22 |
|
17 | 23 | async def _handle_discord_oauth(code: str, redirect_uri: str) -> tuple[str, str]: |
@@ -183,3 +189,103 @@ async def display_report(self, title: str, report: RunResultReport): |
183 | 189 | elif isinstance(part, Log): |
184 | 190 | self.long_report += f"\n\n## {part.header}:\n" |
185 | 191 | self.long_report += f"```\n{part.content}```" |
| 192 | +# ruff: noqa: C901 |
| 193 | +async def to_submit_info( |
| 194 | + user_info: Any, |
| 195 | + submission_mode: str, |
| 196 | + file: UploadFile, |
| 197 | + leaderboard_name: str, |
| 198 | + gpu_type: str, |
| 199 | + db_context: LeaderboardDB, |
| 200 | +) -> tuple[SubmissionRequest, SubmissionMode]: # noqa: C901 |
| 201 | + user_name = user_info["user_name"] |
| 202 | + user_id = user_info["user_id"] |
| 203 | + |
| 204 | + try: |
| 205 | + submission_mode_enum: SubmissionMode = SubmissionMode( |
| 206 | + submission_mode.lower() |
| 207 | + ) |
| 208 | + except ValueError: |
| 209 | + raise HTTPException( |
| 210 | + status_code=400, |
| 211 | + detail=f"Invalid submission mode value: '{submission_mode}'", |
| 212 | + ) from None |
| 213 | + |
| 214 | + if submission_mode_enum in [SubmissionMode.PROFILE]: |
| 215 | + raise HTTPException( |
| 216 | + status_code=400, |
| 217 | + detail="Profile submissions are not currently supported via API", |
| 218 | + ) |
| 219 | + |
| 220 | + allowed_modes = [ |
| 221 | + SubmissionMode.TEST, |
| 222 | + SubmissionMode.BENCHMARK, |
| 223 | + SubmissionMode.LEADERBOARD, |
| 224 | + ] |
| 225 | + if submission_mode_enum not in allowed_modes: |
| 226 | + raise HTTPException( |
| 227 | + status_code=400, |
| 228 | + detail=f"Submission mode '{submission_mode}' is not supported for this endpoint", |
| 229 | + ) |
| 230 | + |
| 231 | + try: |
| 232 | + with db_context as db: |
| 233 | + leaderboard_item = db.get_leaderboard(leaderboard_name) |
| 234 | + gpus = leaderboard_item.get("gpu_types", []) |
| 235 | + if gpu_type not in gpus: |
| 236 | + supported_gpus = ", ".join(gpus) if gpus else "None" |
| 237 | + raise HTTPException( |
| 238 | + status_code=400, |
| 239 | + detail=f"GPU type '{gpu_type}' is not supported for " |
| 240 | + f"leaderboard '{leaderboard_name}'. Supported GPUs: {supported_gpus}", |
| 241 | + ) |
| 242 | + except HTTPException: |
| 243 | + raise |
| 244 | + except Exception as e: |
| 245 | + raise HTTPException( |
| 246 | + status_code=500, |
| 247 | + detail=f"Internal server error while validating leaderboard/GPU: {e}", |
| 248 | + ) from e |
| 249 | + |
| 250 | + try: |
| 251 | + submission_content = await file.read() |
| 252 | + if not submission_content: |
| 253 | + raise HTTPException( |
| 254 | + status_code=400, |
| 255 | + detail="Empty file submitted. Please provide a file with code.", |
| 256 | + ) |
| 257 | + if len(submission_content) > 1_000_000: |
| 258 | + raise HTTPException( |
| 259 | + status_code=413, |
| 260 | + detail="Submission file is too large (limit: 1MB).", |
| 261 | + ) |
| 262 | + |
| 263 | + except HTTPException: |
| 264 | + raise |
| 265 | + except Exception as e: |
| 266 | + raise HTTPException( |
| 267 | + status_code=400, detail=f"Error reading submission file: {e}" |
| 268 | + ) from e |
| 269 | + |
| 270 | + try: |
| 271 | + submission_code = submission_content.decode("utf-8") |
| 272 | + submission_request = SubmissionRequest( |
| 273 | + code=submission_code, |
| 274 | + file_name=file.filename or "submission.py", |
| 275 | + user_id=user_id, |
| 276 | + user_name=user_name, |
| 277 | + gpus=[gpu_type], |
| 278 | + leaderboard=leaderboard_name, |
| 279 | + ) |
| 280 | + except UnicodeDecodeError: |
| 281 | + raise HTTPException( |
| 282 | + status_code=400, |
| 283 | + detail="Failed to decode submission file content as UTF-8.", |
| 284 | + ) from None |
| 285 | + except Exception as e: |
| 286 | + raise HTTPException( |
| 287 | + status_code=500, |
| 288 | + detail=f"Internal server error creating submission request: {e}", |
| 289 | + ) from e |
| 290 | + |
| 291 | + return submission_request, submission_mode_enum |
0 commit comments