import os import shutil from datetime import datetime, timezone from typing import Optional from src.envs import API, QUEUE_REPO, PROJ_DIR def _file_name(path_or_obj) -> str: if path_or_obj is None: return "" if isinstance(path_or_obj, dict) and "name" in path_or_obj: return os.path.basename(path_or_obj["name"]) if hasattr(path_or_obj, "name"): return os.path.basename(path_or_obj.name) return os.path.basename(str(path_or_obj)) def queue_student_submission( group_id: str, alias: Optional[str], state_dict_file: Optional[str], model_py_file: str, preproc_py_file: str, ) -> tuple[str, str]: """ Uploads submitted files to the private queue dataset for offline evaluation. Layout in repo: {PROJ_DIR}/{group_id} + {alias}/{timestamp}/model.py {PROJ_DIR}/{group_id} + {alias}/{timestamp}/preprocess.py {PROJ_DIR}/{group_id} + {alias}/{timestamp}/model.pt (optional) {PROJ_DIR}/{group_id} + {alias}/{timestamp}/request.json """ if not group_id or not group_id.strip(): raise ValueError("Group ID is required.") group_id = group_id.strip() alias = alias.strip() if isinstance(alias, str) else alias ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ") alias_sanitized = (alias or "NA").replace("/", "_") base_path = f"{PROJ_DIR}/{group_id} + {alias_sanitized}/{ts}" # Prepare a small request.json metadata request_json = { "group_id": group_id, "alias": alias, "timestamp": ts, "status": "PENDING", "datasets": ["img_val"], "has_weights": bool(state_dict_file), } # Save metadata to a temp file for upload tmp_dir = os.path.abspath(os.path.join(".", ".tmp_queue_upload")) os.makedirs(tmp_dir, exist_ok=True) req_local = os.path.join(tmp_dir, f"request_{group_id}_{ts}.json") with open(req_local, "w") as f: import json json.dump(request_json, f) # Upload request API.upload_file( path_or_fileobj=req_local, path_in_repo=f"{base_path}/request.json", repo_id=QUEUE_REPO, repo_type="dataset", commit_message=f"Queue request {group_id}/{ts}", ) # Upload model and preprocess API.upload_file( path_or_fileobj=model_py_file, path_in_repo=f"{base_path}/model.py", repo_id=QUEUE_REPO, repo_type="dataset", commit_message=f"Upload model.py for {group_id}/{ts}", ) API.upload_file( path_or_fileobj=preproc_py_file, path_in_repo=f"{base_path}/preprocess.py", repo_id=QUEUE_REPO, repo_type="dataset", commit_message=f"Upload preprocess.py for {group_id}/{ts}", ) if state_dict_file: API.upload_file( path_or_fileobj=state_dict_file, path_in_repo=f"{base_path}/model.pt", repo_id=QUEUE_REPO, repo_type="dataset", commit_message=f"Upload model.pt for {group_id}/{ts}", ) # Cleanup temporary try: shutil.rmtree(tmp_dir, ignore_errors=True) except Exception: pass return f"Submission queued for Group '{group_id}' at {ts}. Your model will be evaluated shortly.", ts