@@ -117,7 +117,7 @@ async def task_get_all(experimentId: str):
117117 tags = ["tasks:{experimentId}" ],
118118)
119119async def task_get_by_id (experimentId : str , task_id : str ):
120- task = await task_service .task_get_by_id (task_id )
120+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
121121 if task is None :
122122 return {"message" : "NOT FOUND" }
123123 return task
@@ -153,7 +153,7 @@ async def task_get_by_type_in_experiment(experimentId: str, type: str):
153153 response_model = TaskFilesResponse ,
154154 summary = "List files associated with a task template (GitHub + local mounts)" ,
155155)
156- async def task_list_files (task_id : str ) -> TaskFilesResponse :
156+ async def task_list_files (experimentId : str , task_id : str ) -> TaskFilesResponse :
157157 """
158158 Return a lightweight list of files associated with a task template.
159159
@@ -163,7 +163,7 @@ async def task_list_files(task_id: str) -> TaskFilesResponse:
163163 readily available.
164164 - If file_mounts is set, it will be returned as-is as a list of local paths.
165165 """
166- task = await task_service .task_get_by_id (task_id )
166+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
167167 if not task :
168168 raise HTTPException (status_code = 404 , detail = "Task not found" )
169169
@@ -207,7 +207,7 @@ async def task_list_files(task_id: str) -> TaskFilesResponse:
207207 # Always list files from the canonical per-task directory.
208208 # This directory contains at minimum task.yaml and may include uploaded files.
209209 try :
210- task_dir = await task_service .get_task_dir (task_id )
210+ task_dir = await task_service .get_task_dir (task_id , experiment_id = experimentId )
211211 if await storage .exists (task_dir ):
212212 entries = await storage .ls (task_dir )
213213 # Build a set of basenames already in local_files for dedup.
@@ -353,7 +353,7 @@ async def task_update_file(experimentId: str, task_id: str, file_path: str, requ
353353 .py, .md, .yaml/.yml, .json, .txt). Request bodies are decoded as UTF-8 and
354354 written in text mode. Binary uploads should use the file-upload endpoint.
355355 """
356- task = await task_service .task_get_by_id (task_id )
356+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
357357 if not task :
358358 raise HTTPException (status_code = 404 , detail = "Task not found" )
359359
@@ -376,7 +376,7 @@ async def task_update_file(experimentId: str, task_id: str, file_path: str, requ
376376 await f .write (body )
377377
378378 if not task .get ("file_mounts" ):
379- await task_service .update_task (task_id , {"file_mounts" : True })
379+ await task_service .update_task (task_id , {"file_mounts" : True }, experiment_id = experimentId )
380380
381381 await cache .invalidate (f"tasks:{ experimentId } " )
382382 return {"message" : "OK" }
@@ -387,7 +387,7 @@ async def task_update_file(experimentId: str, task_id: str, file_path: str, requ
387387 summary = "Delete a file from a task's local workspace directory" ,
388388)
389389async def task_delete_file (experimentId : str , task_id : str , file_path : str ):
390- task = await task_service .task_get_by_id (task_id )
390+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
391391 if not task :
392392 raise HTTPException (status_code = 404 , detail = "Task not found" )
393393
@@ -421,7 +421,7 @@ async def task_upload_file(
421421 task_id : str ,
422422 files : list [UploadFile ] = File (...),
423423):
424- task = await task_service .task_get_by_id (task_id )
424+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
425425 if not task :
426426 raise HTTPException (status_code = 404 , detail = "Task not found" )
427427
@@ -450,7 +450,7 @@ async def task_upload_file(
450450 raise HTTPException (status_code = 400 , detail = "No valid files uploaded" )
451451
452452 if not task .get ("file_mounts" ):
453- await task_service .update_task (task_id , {"file_mounts" : True })
453+ await task_service .update_task (task_id , {"file_mounts" : True }, experiment_id = experimentId )
454454
455455 await cache .invalidate (f"tasks:{ experimentId } " )
456456 return {"status" : "success" , "files" : saved_files }
@@ -460,14 +460,14 @@ async def task_upload_file(
460460 "/{task_id}/github_file/{file_path:path}" ,
461461 summary = "Serve a file from the task's associated GitHub repository for preview" ,
462462)
463- async def task_get_github_file (task_id : str , file_path : str ):
463+ async def task_get_github_file (experimentId : str , task_id : str , file_path : str ):
464464 """
465465 Serve a file from the GitHub repository configured on the task (github_repo_url).
466466
467467 This endpoint uses the same GitHub PAT resolution logic as other GitHub helpers
468468 and is intended for lightweight previews in the UI.
469469 """
470- task = await task_service .task_get_by_id (task_id )
470+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
471471 if not task :
472472 raise HTTPException (status_code = 404 , detail = "Task not found" )
473473
@@ -583,7 +583,7 @@ async def update_task(experimentId: str, task_id: str, new_task: dict = Body()):
583583 if "name" in new_task :
584584 new_task ["name" ] = secure_filename (new_task ["name" ])
585585
586- success = await task_service .update_task (task_id , new_task )
586+ success = await task_service .update_task (task_id , new_task , experiment_id = experimentId )
587587 if success :
588588 # Best-effort invalidation: task detail + this experiment's task lists.
589589 await cache .invalidate (f"tasks:{ experimentId } " )
@@ -594,7 +594,7 @@ async def update_task(experimentId: str, task_id: str, new_task: dict = Body()):
594594
595595@router .get ("/{task_id}/delete" , summary = "Deletes a task" )
596596async def delete_task (experimentId : str , task_id : str ):
597- success = await task_service .delete_task (task_id )
597+ success = await task_service .delete_task (task_id , experiment_id = experimentId )
598598 if success :
599599 # Best-effort invalidation: task detail + this experiment's task lists.
600600 await cache .invalidate (f"tasks:{ experimentId } " )
@@ -899,23 +899,23 @@ async def create_task(
899899
900900@router .get ("/{task_id}/yaml" , summary = "Get task.yaml from the task directory" )
901901async def get_task_yaml (experimentId : str , task_id : str ):
902- task = await task_service .task_get_by_id (task_id )
902+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
903903 if task is None :
904904 raise HTTPException (status_code = 404 , detail = "Task not found" )
905- content = await task_service .read_task_yaml (task_id )
905+ content = await task_service .read_task_yaml (task_id , experiment_id = experimentId )
906906 return PlainTextResponse (content , media_type = "text/plain" )
907907
908908
909909@router .put ("/{task_id}/yaml" , summary = "Save task.yaml and sync index.json" )
910910async def update_task_yaml (experimentId : str , task_id : str , request : Request ):
911911 body = (await request .body ()).decode ("utf-8" )
912- task = await task_service .task_get_by_id (task_id )
912+ task = await task_service .task_get_by_id (task_id , experiment_id = experimentId )
913913 if task is None :
914914 raise HTTPException (status_code = 404 , detail = "Task not found" )
915- await task_service .write_task_yaml (task_id , body )
915+ await task_service .write_task_yaml (task_id , body , experiment_id = experimentId )
916916 task_data = _parse_yaml_to_task_data (body )
917917 task_data .pop ("id" , None )
918- success = await task_service .update_task_from_yaml (task_id , task_data )
918+ success = await task_service .update_task_from_yaml (task_id , task_data , experiment_id = experimentId )
919919 if not success :
920920 raise HTTPException (status_code = 404 , detail = "Task not found" )
921921 await cache .invalidate (f"tasks:{ experimentId } " )
@@ -1120,7 +1120,7 @@ async def import_task_from_gallery(
11201120 await storage .makedirs (task_dir_path , exist_ok = True )
11211121 dest_subdir = storage .join (task_dir_path , os .path .basename (local_task_dir .rstrip ("/" )))
11221122 await storage .copy_dir (local_task_dir , dest_subdir )
1123- await task_service .update_task (task_id , {"file_mounts" : True })
1123+ await task_service .update_task (task_id , {"file_mounts" : True }, experiment_id = experimentId )
11241124
11251125 return {"status" : "success" , "message" : f"Interactive task '{ task_name } ' imported successfully" , "id" : task_id }
11261126
@@ -1532,7 +1532,7 @@ async def import_task_from_team_gallery(
15321532 await f .write (json .dumps (data , indent = 2 ))
15331533 else :
15341534 # No index.json in the copied directory; write at least minimal metadata.
1535- await task_service .update_task (task_id , {"id" : task_id })
1535+ await task_service .update_task (task_id , {"id" : task_id }, experiment_id = experimentId )
15361536 except Exception as e :
15371537 raise HTTPException (
15381538 status_code = 500 , detail = f"Failed to overwrite id in index.json for imported team task: { e } "
@@ -1708,7 +1708,7 @@ async def export_task_to_team_gallery(
17081708 Export a task into the team-specific gallery stored in workspace_dir.
17091709 Tasks store all fields directly (not nested in config).
17101710 """
1711- task = await task_service .task_get_by_id (request .task_id )
1711+ task = await task_service .task_get_by_id (request .task_id , experiment_id = request . experiment_id )
17121712 if not task :
17131713 raise HTTPException (status_code = 404 , detail = "Task not found" )
17141714
0 commit comments