3636
3737app = FastAPI ()
3838
39+
3940def json_serializer (obj ):
4041 """JSON serializer for objects not serializable by default json code"""
4142 if isinstance (obj , (datetime .datetime , datetime .date , datetime .time )):
@@ -255,10 +256,16 @@ async def cli_auth(auth_provider: str, code: str, state: str, db_context=Depends
255256 raise e
256257 except Exception as e :
257258 # Catch unexpected errors during OAuth handling
258- raise HTTPException (status_code = 500 , detail = f"Error during { auth_provider } OAuth flow: { e } " ) from e
259+ raise HTTPException (
260+ status_code = 500 ,
261+ detail = f"Error during { auth_provider } OAuth flow: { e } " ,
262+ ) from e
259263
260264 if not user_id or not user_name :
261- raise HTTPException (status_code = 500 ,detail = "Failed to retrieve user ID or username from provider." ,)
265+ raise HTTPException (
266+ status_code = 500 ,
267+ detail = "Failed to retrieve user ID or username from provider." ,
268+ )
262269
263270 try :
264271 with db_context as db :
@@ -268,7 +275,10 @@ async def cli_auth(auth_provider: str, code: str, state: str, db_context=Depends
268275 db .create_user_from_cli (user_id , user_name , cli_id , auth_provider )
269276
270277 except AttributeError as e :
271- raise HTTPException (status_code = 500 , detail = f"Database interface error during update: { e } " ) from e
278+ raise HTTPException (
279+ status_code = 500 ,
280+ detail = f"Database interface error during update: { e } " ,
281+ ) from e
272282 except Exception as e :
273283 raise HTTPException (status_code = 400 , detail = f"Database update failed: { e } " ) from e
274284
@@ -280,6 +290,7 @@ async def cli_auth(auth_provider: str, code: str, state: str, db_context=Depends
280290 "is_reset" : is_reset ,
281291 }
282292
293+
283294async def _stream_submission_response (
284295 submission_request : SubmissionRequest ,
285296 submission_mode_enum : SubmissionMode ,
@@ -298,18 +309,22 @@ async def _stream_submission_response(
298309
299310 while not task .done ():
300311 elapsed_time = time .time () - start_time
301- yield f"event: status\n data: { json .dumps ({'status' : 'processing' ,
302- 'elapsed_time' : round (elapsed_time , 2 )},
303- default = json_serializer )} \n \n "
312+ status_data = json .dumps (
313+ {"status" : "processing" , "elapsed_time" : round (elapsed_time , 2 )},
314+ default = json_serializer ,
315+ )
316+ yield f"event: status\n data: { status_data } \n \n "
304317
305318 try :
306319 await asyncio .wait_for (asyncio .shield (task ), timeout = 15.0 )
307320 except asyncio .TimeoutError :
308321 continue
309322 except asyncio .CancelledError :
310- yield f"event: error\n data: { json .dumps (
311- {'status' : 'error' , 'detail' : 'Submission cancelled' },
312- default = json_serializer )} \n \n "
323+ error_data = json .dumps (
324+ {"status" : "error" , "detail" : "Submission cancelled" },
325+ default = json_serializer ,
326+ )
327+ yield f"event: error\n data: { error_data } \n \n "
313328 return
314329
315330 result , reports = await task
@@ -343,6 +358,7 @@ async def _stream_submission_response(
343358 except asyncio .CancelledError :
344359 pass
345360
361+
346362@app .post ("/{leaderboard_name}/{gpu_type}/{submission_mode}" )
347363async def run_submission ( # noqa: C901
348364 leaderboard_name : str ,
@@ -381,13 +397,13 @@ async def run_submission( # noqa: C901
381397 )
382398 return StreamingResponse (generator , media_type = "text/event-stream" )
383399
400+
384401async def enqueue_background_job (
385402 req : ProcessedSubmissionRequest ,
386403 mode : SubmissionMode ,
387404 backend : KernelBackend ,
388405 manager : BackgroundSubmissionManager ,
389406):
390-
391407 # pre-create the submission for api returns
392408 with backend .db as db :
393409 sub_id = db .create_submission (
@@ -401,7 +417,8 @@ async def enqueue_background_job(
401417 job_id = db .upsert_submission_job_status (sub_id , "initial" , None )
402418 # put submission request in queue
403419 await manager .enqueue (req , mode , sub_id )
404- return sub_id ,job_id
420+ return sub_id , job_id
421+
405422
406423@app .post ("/submission/{leaderboard_name}/{gpu_type}/{submission_mode}" )
407424async def run_submission_async (
@@ -425,37 +442,49 @@ async def run_submission_async(
425442 Raises:
426443 HTTPException: If the kernelbot is not initialized, or header/input is invalid.
427444 Returns:
428- JSONResponse: A JSON response containing job_id and and submission_id for the client to poll for status.
445+ JSONResponse: A JSON response containing job_id and submission_id.
446+ The client can poll for status using these ids.
429447 """
430448 try :
431-
432449 await simple_rate_limit ()
433- logger .info (f"Received submission request for { leaderboard_name } { gpu_type } { submission_mode } " )
434-
450+ logger .info (
451+ "Received submission request for %s %s %s" ,
452+ leaderboard_name ,
453+ gpu_type ,
454+ submission_mode ,
455+ )
435456
436457 # throw error if submission request is invalid
437458 try :
438459 submission_request , submission_mode_enum = await to_submit_info (
439- user_info , submission_mode , file , leaderboard_name , gpu_type , db_context
460+ user_info , submission_mode , file , leaderboard_name , gpu_type , db_context
440461 )
441462
442463 req = prepare_submission (submission_request , backend_instance )
443464
465+ except KernelBotError as e :
466+ raise HTTPException (status_code = e .http_code , detail = str (e )) from e
444467 except Exception as e :
445- raise HTTPException (status_code = 400 , detail = f"failed to prepare submission request: { str (e )} " ) from e
468+ raise HTTPException (
469+ status_code = 400 ,
470+ detail = f"failed to prepare submission request: { str (e )} " ,
471+ ) from e
446472
447473 # prepare submission request before the submission is started
448474 if not req .gpus or len (req .gpus ) != 1 :
449475 raise HTTPException (status_code = 400 , detail = "Invalid GPU type" )
450476
451477 # put submission request to background manager to run in background
452- sub_id ,job_status_id = await enqueue_background_job (
478+ sub_id , job_status_id = await enqueue_background_job (
453479 req , submission_mode_enum , backend_instance , background_submission_manager
454480 )
455481
456482 return JSONResponse (
457483 status_code = 202 ,
458- content = {"details" :{"id" : sub_id , "job_status_id" : job_status_id }, "status" : "accepted" },
484+ content = {
485+ "details" : {"id" : sub_id , "job_status_id" : job_status_id },
486+ "status" : "accepted" ,
487+ },
459488 )
460489 # Preserve FastAPI HTTPException as-is
461490 except HTTPException :
@@ -470,6 +499,7 @@ async def run_submission_async(
470499 logger .error (f"Unexpected error in api submissoin: { e } " )
471500 raise HTTPException (status_code = 500 , detail = "Internal server error" ) from e
472501
502+
473503@app .get ("/leaderboards" )
474504async def get_leaderboards (db_context = Depends (get_db )):
475505 """An endpoint that returns all leaderboards.
0 commit comments