my-challenge / app.py
JulioContrerasH's picture
Upload: Multiple files to assets directory
0834c9b verified
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", "contrerasnetk@gmail.com")
# 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()