Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import requests | |
| import os | |
| import pandas as pd | |
| import numpy as np | |
| import matplotlib | |
| matplotlib.use('Agg') | |
| import matplotlib.pyplot as plt | |
| import io | |
| import base64 | |
| import json | |
| import time | |
| import subprocess | |
| from huggingface_hub import Repository | |
| # ----------------------------------------------------------------------------- | |
| # CONFIGURACIÓN DEL REPO DEL SPACE Y DE LA REFERENCIA | |
| # ----------------------------------------------------------------------------- | |
| SPACE_REPO_URL = "https://huggingface.co/spaces/JulioContrerasH/my-challenge" | |
| SPACE_LOCAL_DIR = "." # Usa la carpeta actual (el mismo repo del Space) | |
| # URL de tu archivo de referencia CSV en un dataset (por ejemplo, "reference.csv") | |
| REFERENCE_FILE_URL = ( | |
| "https://huggingface.co/datasets/JulioContrerasH/my-challenge-submissions/resolve/main/reference.csv" | |
| ) | |
| LOCAL_REF_PATH = "reference.csv" # Lo guardaremos con este nombre local | |
| def git_set_identity(name: str, email: str): | |
| """Configura la identidad de git en el repo local.""" | |
| try: | |
| subprocess.run(["git", "config", "user.name", name], check=True) | |
| subprocess.run(["git", "config", "user.email", email], check=True) | |
| except Exception as e: | |
| print("Error setting git identity:", e) | |
| def setup_local_repo_for_push(): | |
| """ | |
| Inicializa un objeto 'Repository' apuntando al mismo repo del Space. | |
| Requiere un token con permisos de escritura, guardado en HF_SPACE_TOKEN | |
| como secret en la configuración del Space. | |
| También configura user_name y user_email para que los commits no den error. | |
| """ | |
| token = os.environ.get("HF_SPACE_TOKEN", None) # Revisar que se llame así en los secrets | |
| if not token: | |
| print("WARNING: HF_SPACE_TOKEN no está configurado. No se podrá hacer push.") | |
| return None | |
| repo = Repository( | |
| local_dir=SPACE_LOCAL_DIR, | |
| clone_from=SPACE_REPO_URL, | |
| use_auth_token=token | |
| ) | |
| # Configurar user.name y user.email | |
| git_set_identity("JulioContrerasH", "[email protected]") | |
| # Forzar la URL remota para que lleve el token | |
| # user: "__token__" (literal) y password: <token> | |
| new_url = f"https://__token__:{token}@huggingface.co/spaces/JulioContrerasH/my-challenge" | |
| subprocess.run(["git", "remote", "set-url", "origin", new_url], cwd=".", check=True) | |
| # Por si se actualizó el Space en remoto | |
| try: | |
| repo.git_pull() | |
| except: | |
| pass | |
| return repo | |
| # Inicializamos la posibilidad de hacer push a nuestro Space | |
| space_repo = setup_local_repo_for_push() | |
| def add_submission_entry(entry): | |
| """ | |
| Abre/crea submissions.jsonl (en la raíz del Space), | |
| agrega la nueva 'entry', y hace commit+push al repo. | |
| """ | |
| global space_repo | |
| if space_repo is None: | |
| print("No repo handle (space_repo is None). Skipping save.") | |
| return | |
| submissions_file = "submissions.jsonl" | |
| # 1) Traer la última versión de remoto (por si hubo otros commits) | |
| space_repo.git_pull() | |
| # 2) Leer el archivo actual (si existe) | |
| submissions = [] | |
| if os.path.exists(submissions_file): | |
| with open(submissions_file, "r") as f: | |
| for line in f: | |
| line = line.strip() | |
| if line: | |
| submissions.append(json.loads(line)) | |
| # 3) Añadir la nueva entrada | |
| submissions.append(entry) | |
| # 4) Guardar sobrescribiendo | |
| with open(submissions_file, "w") as f: | |
| for s in submissions: | |
| f.write(json.dumps(s) + "\n") | |
| # 5) Hacer commit y push | |
| space_repo.git_add(submissions_file) | |
| space_repo.git_commit("Add new submission entry") | |
| try: | |
| space_repo.git_push() | |
| print("Submission pushed successfully to the Space repo.") | |
| except Exception as e: | |
| print("Error pushing submission:", e) | |
| # ----------------------------------------------------------------------------- | |
| # DESCARGA DEL ARCHIVO DE REFERENCIA | |
| # ----------------------------------------------------------------------------- | |
| def download_reference(): | |
| """ | |
| Descarga el CSV de referencia desde el dataset en Hugging Face, | |
| guardándolo como 'reference.csv' si no existe aún. | |
| """ | |
| if not os.path.exists(LOCAL_REF_PATH): | |
| print("Descargando archivo de referencia...") | |
| r = requests.get(REFERENCE_FILE_URL) | |
| r.raise_for_status() | |
| with open(LOCAL_REF_PATH, 'wb') as f: | |
| f.write(r.content) | |
| print("Descarga completa:", LOCAL_REF_PATH) | |
| download_reference() # Se ejecuta al iniciar el Space | |
| # ----------------------------------------------------------------------------- | |
| # LÓGICA DE EVALUACIÓN | |
| # ----------------------------------------------------------------------------- | |
| def evaluate_prediction(pred_path, ref_path): | |
| """ | |
| Lee el CSV subido (pred_path) y el CSV de referencia (ref_path), | |
| Calcula el MRE y RMSE, y retorna un dict con resultados. | |
| Formato esperado: | |
| - reference.csv: [wavelength, power] | |
| - predictions.csv: [wavelength, prediction] | |
| """ | |
| # Leer la referencia | |
| df_ref = pd.read_csv(ref_path) | |
| # Leer la predicción | |
| df_pred = pd.read_csv(pred_path) | |
| # Merge en base a 'wavelength' | |
| df_merged = pd.merge(df_ref, df_pred, on='wavelength', how='inner') | |
| real = df_merged['power'].values | |
| pred = df_merged['prediction'].values | |
| # Calcular MRE | |
| mre = np.abs((pred - real) / real) | |
| mre_mean = mre.mean() | |
| # Calcular RMSE | |
| rmse = np.sqrt(np.mean((pred - real)**2)) | |
| # Retornar | |
| return { | |
| "mre_mean": float(mre_mean), | |
| "rmse": float(rmse), | |
| "mre_spectrum": mre.tolist() | |
| } | |
| def evaluate_and_save(pred_file, participant_name): | |
| """ | |
| 1. Toma el archivo subido (pred_file). | |
| 2. Evalúa comparándolo con la referencia (LOCAL_REF_PATH). | |
| 3. Agrega la entrada a submissions.jsonl. | |
| 4. Genera una gráfica y mensaje de resultados. | |
| """ | |
| if not pred_file: | |
| return "No file uploaded", None | |
| pred_path = pred_file.name | |
| results = evaluate_prediction(pred_path, LOCAL_REF_PATH) | |
| # Guardar submission en submissions.jsonl | |
| submission_entry = { | |
| "submission_id": int(time.time()), | |
| "participant": participant_name, | |
| "mre_mean": results["mre_mean"], | |
| "rmse": results["rmse"], | |
| "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") | |
| } | |
| add_submission_entry(submission_entry) | |
| # Graficar | |
| mre_spectrum = results["mre_spectrum"] | |
| plt.figure(figsize=(6,4)) | |
| plt.plot(np.arange(len(mre_spectrum)), mre_spectrum, marker='o', label='MRE Spectrum') | |
| plt.xlabel('Index') | |
| plt.ylabel('MRE') | |
| plt.title('Spectral Error') | |
| plt.legend() | |
| buf = io.BytesIO() | |
| plt.savefig(buf, format='png') | |
| plt.close() | |
| buf.seek(0) | |
| img_str = base64.b64encode(buf.read()).decode('utf-8') | |
| img_str = f"data:image/png;base64,{img_str}" | |
| # Mensaje final | |
| message = ( | |
| f"Participant: {participant_name}\n" | |
| f"MRE mean: {results['mre_mean']:.4f}\n" | |
| f"RMSE: {results['rmse']:.4f}" | |
| ) | |
| return message, img_str | |
| # ----------------------------------------------------------------------------- | |
| # INTERFAZ GRADIO | |
| # ----------------------------------------------------------------------------- | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# My Challenge\nSube tu archivo de predicciones en CSV para evaluar tu modelo.") | |
| participant_name = gr.Textbox(label="Nombre del participante") | |
| pred_file = gr.File(label="Subir archivo CSV (predictions.csv)") | |
| output_message = gr.Textbox(label="Resultados") | |
| output_image = gr.HTML(label="Gráfica") | |
| submit_btn = gr.Button("Evaluar") | |
| submit_btn.click( | |
| fn=evaluate_and_save, | |
| inputs=[pred_file, participant_name], | |
| outputs=[output_message, output_image] | |
| ) | |
| demo.launch() | |