import logging from datetime import datetime, timezone import pathlib import tempfile import json from pathlib import Path import gradio as gr import pandas as pd from huggingface_hub import hf_hub_download, HfApi from huggingface_hub.errors import EntryNotFoundError from about import API, SUBMISSIONS_REPO, RESULTS_REPO, TOKEN, REGISTRATION_REPO from components.registration.config import TEAMS_FILE_NAME, TEAM_COLUMNS from evaluation import evaluate_problem logger = logging.getLogger(__name__) def make_user_clickable(name): link = f"https://huggingface.co/{name}" return f'{name}' def make_boundary_clickable(filename): link = f"https://huggingface.co/datasets/proxima-fusion/constellaration-bench-results/blob/main/{filename}" return f'link' def read_result_from_hub(filename): local_path = hf_hub_download( repo_id=RESULTS_REPO, repo_type="dataset", filename=filename, ) return local_path def read_submission_from_hub(filename): local_path = hf_hub_download( repo_id=SUBMISSIONS_REPO, repo_type="dataset", filename=filename, ) return local_path def write_results(record, result): record.update(result) record["result_filename"] = ( record["submission_filename"].rstrip(".json") + "_results.json" ) record["evaluated"] = True record["objectives"] = json.dumps(record.get("objectives", [])) record["feasibilities"] = json.dumps(record.get("feasibility", [])) if "objective" not in record.keys(): record["objective"] = 0.0 record["minimize_objective"] = True record["feasibility"] = sum(record["feasibility"]) / len(record["feasibility"]) with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as tmp: json.dump(record, tmp) tmp.flush() tmp_name = tmp.name API.upload_file( path_or_fileobj=tmp_name, path_in_repo=record["result_filename"], repo_id=RESULTS_REPO, repo_type="dataset", commit_message=f"Add result data for {record['result_filename']}", ) pathlib.Path(tmp_name).unlink() return def get_user(profile: gr.OAuthProfile | None) -> str: if profile is None: return "Please login to submit a boundary for evaluation." return profile.username def evaluate_boundary(filename): local_path = read_submission_from_hub(filename) with Path(local_path).open("r") as f: raw = f.read() data_dict = json.loads(raw) try: result = evaluate_problem(local_path) except Exception as e: raise gr.Error( f"Evaluation failed: {e}. No results written to results dataset." ) write_results(data_dict, result) return def show_output_box(message): return gr.update(value=message, visible=True) def push_data_to_dataset(df: pd.DataFrame, repo_id: str, filename: str) -> None: """Upload a DataFrame as a UTF-8 CSV file to the HF dataset repository.""" api = HfApi(token=TOKEN) csv_bytes = df.to_csv(index=False).encode("utf-8") api.upload_file( path_or_fileobj=csv_bytes, path_in_repo=filename, repo_id=repo_id, repo_type="dataset", commit_message=f"upsert {filename} – {datetime.now(timezone.utc).isoformat()}", ) def load_data_from_dataset( repo_id: str, filename: str, columns: list[str] ) -> pd.DataFrame: """ Download a CSV file from the HF dataset and return a DataFrame. :param repo_id: The HF dataset repository ID. :param filename: The name of the CSV file to load. :return: Returns the dataset if the file exists. Otherwise, an empty DataFrame with the correct columns. """ try: path = hf_hub_download( repo_id=repo_id, filename=filename, repo_type="dataset", token=TOKEN, ) df = pd.read_csv(path, dtype=str).fillna("") for col in columns: if col not in df.columns: df[col] = "" return df[columns] except EntryNotFoundError: return pd.DataFrame(columns=columns) except Exception as exc: logger.error("Failed to load %s from %s: %s", filename, repo_id, exc) raise def get_team(teams_df: pd.DataFrame, team_name: str) -> pd.Series | None: """Get the team record from teams_df corresponding to given team_name.""" rows = teams_df[teams_df["team_name"] == team_name] return rows.iloc[0] if not rows.empty else None def check_team_has_leader(team_name: str) -> bool: """Return True if the team exists and has a designated leader.""" try: teams_df = load_data_from_dataset( REGISTRATION_REPO, TEAMS_FILE_NAME, TEAM_COLUMNS ) except Exception: return False team = get_team(teams_df, team_name) if team is None: return False return bool((team.get("leader_email") or "").strip())