TRAIL / app.py
Jitin Krishnan
test
fb83d75
import gradio as gr
import pandas as pd
import os
import shutil
import json
from zipfile import ZipFile
import re
# Function to load leaderboard data from a CSV file
def load_leaderboard_data(csv_file_path):
try:
df = pd.read_csv(csv_file_path)
return df
except Exception as e:
print(f"Error loading CSV file: {e}")
return pd.DataFrame()
def save_zip_and_extract_json(zip_path):
if not zip_path:
return "Please upload a ZIP file."
try:
# 1) Determine Space name and persistent base dir
cwd = os.getcwd()
space_name = os.path.basename(cwd)
base_dir = os.path.join("data", space_name, "uploaded_jsons")
os.makedirs(base_dir, exist_ok=True)
# 2) Copy the zip into base_dir
zip_dest = os.path.join(base_dir, os.path.basename(zip_path))
shutil.copy(zip_path, zip_dest)
# 3) Extract only .json files
extracted = []
with ZipFile(zip_dest, 'r') as archive:
for member in archive.namelist():
if member.lower().endswith(".json"):
archive.extract(member, path=base_dir)
extracted.append(member)
if not extracted:
return "No JSON files found in the ZIP."
return f"Extracted JSON files:\n" + "\n".join(extracted)
except Exception as e:
return f"Error processing ZIP file: {str(e)}"
# Load the leaderboard data
leaderboard1 = load_leaderboard_data("leaderboard_swe.csv")
leaderboard2 = load_leaderboard_data("leaderboard_gaia.csv")
# Create the Gradio interface
with gr.Blocks() as demo:
gr.Markdown("# πŸ† TRAIL: Trace Reasoning and Agentic Issue Localization Leaderboard")
with gr.Tab("LEADERBOARD"):
with gr.Row():
with gr.Column():
gr.Markdown("## TRAIL-SWE Leaderboard")
gr.Dataframe(leaderboard1)
with gr.Column():
gr.Markdown("## TRAIL-GAIA Leaderboard")
gr.Dataframe(leaderboard2)
with gr.Tab("SUBMIT ZIP"):
gr.Markdown("## Submit Your ZIP of JSONs")
#with gr.Row():
with gr.Column():
file_input = gr.File(
label="Upload ZIP File",
file_types=['.zip']
)
submit_button = gr.Button("Submit", interactive=True)
output = gr.Textbox(label="Status")
def process_upload(file):
if file is None:
return "Please upload a ZIP file."
try:
return save_zip_and_extract_json(file.name)
except Exception as e:
return f"Error: {str(e)}"
submit_button.click(
fn=process_upload,
inputs=file_input,
outputs=output
)
with open("README.md", "r", encoding="utf-8") as f:
README_CONTENT = f.read()
yaml_front_matter = re.compile(r"^---\s*.*?\s*---\s*", re.DOTALL)
readme_content_without_yaml = re.sub(yaml_front_matter, "", README_CONTENT).strip()
with gr.Tab("README"):
gr.Markdown(readme_content_without_yaml)
if __name__ == "__main__":
demo.launch()
"""
import gradio as gr
import pandas as pd
import os
import json
import uuid
import hashlib
from datetime import datetime
from huggingface_hub import HfApi, login, HfFolder
# Configuration
LEADERBOARD_CSV = "leaderboard.csv"
SUBMISSIONS_FOLDER = "submissions"
CONFIG_FILE = "config.json"
DEFAULT_COLUMNS = ["rank", "submission_name", "score", "user", "timestamp"]
VERIFY_USERS = False # Set to True to enable HF authentication
# Default configuration
DEFAULT_CONFIG = {
"title": "Hugging Face Competition Leaderboard",
"description": "Submit your results for the competition",
"metric_name": "Score",
"higher_is_better": True,
"max_submissions_per_user": 5,
"allow_submission_edits": True
}
# Ensure submissions folder exists
os.makedirs(SUBMISSIONS_FOLDER, exist_ok=True)
# Load or create config
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r") as f:
config = json.load(f)
else:
config = DEFAULT_CONFIG
with open(CONFIG_FILE, "w") as f:
json.dump(config, f, indent=2)
# Initialize leaderboard if it doesn't exist
if not os.path.exists(LEADERBOARD_CSV):
pd.DataFrame(columns=DEFAULT_COLUMNS).to_csv(LEADERBOARD_CSV, index=False)
def read_leaderboard():
#Read the current leaderboard
if os.path.exists(LEADERBOARD_CSV):
df = pd.read_csv(LEADERBOARD_CSV)
return df
return pd.DataFrame(columns=DEFAULT_COLUMNS)
def verify_user(username, token):
#Verify a user with their Hugging Face token
if not VERIFY_USERS:
return True
try:
api = HfApi(token=token)
user_info = api.whoami()
return user_info["name"] == username
except:
return False
def count_user_submissions(username):
#Count how many submissions a user already has
df = read_leaderboard()
return len(df[df["user"] == username])
def update_leaderboard():
#Update the leaderboard based on submissions
# Read all submissions
submissions = []
for filename in os.listdir(SUBMISSIONS_FOLDER):
if filename.endswith(".json"):
with open(os.path.join(SUBMISSIONS_FOLDER, filename), "r") as f:
try:
data = json.load(f)
submissions.append(data)
except json.JSONDecodeError:
print(f"Error decoding {filename}")
if not submissions:
return pd.DataFrame(columns=DEFAULT_COLUMNS)
# Create dataframe and sort by score
df = pd.DataFrame(submissions)
# Sort based on configuration (higher or lower is better)
ascending = not config.get("higher_is_better", True)
df = df.sort_values("score", ascending=ascending)
# Add rank
df["rank"] = range(1, len(df) + 1)
# Save updated leaderboard
df.to_csv(LEADERBOARD_CSV, index=False)
return df
def submit(submission_name, score, username, hf_token="", submission_details=None):
#Add a new submission to the leaderboard
if not submission_name or not username:
return "Submission name and username are required", None
try:
score = float(score)
except ValueError:
return "Score must be a valid number", None
# Verify user if enabled
if VERIFY_USERS and not verify_user(username, hf_token):
return "Invalid Hugging Face credentials", None
# Check submission limit
max_submissions = config.get("max_submissions_per_user", 5)
if count_user_submissions(username) >= max_submissions:
return f"You've reached the maximum of {max_submissions} submissions", None
# Create submission entry
submission_id = str(uuid.uuid4())[:8]
submission = {
"submission_id": submission_id,
"submission_name": submission_name,
"score": score,
"user": username,
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
# Add optional details
if submission_details:
submission["details"] = submission_details
# Save submission to file
filename = f"{username}_{submission_name.replace(' ', '_')}_{submission_id}.json"
with open(os.path.join(SUBMISSIONS_FOLDER, filename), "w") as f:
json.dump(submission, f)
# Update leaderboard
leaderboard = update_leaderboard()
return f"Submission '{submission_name}' added successfully!", leaderboard
def render_leaderboard():
#Display the current leaderboard
df = update_leaderboard()
if len(df) == 0:
return "No submissions yet."
# Format the dataframe for display
display_df = df[DEFAULT_COLUMNS].copy()
return display_df
# Create the Gradio interface
with gr.Blocks(title=config["title"]) as demo:
gr.Markdown(f"# {config['title']}")
gr.Markdown(f"{config['description']}")
with gr.Tab("Leaderboard"):
gr.Markdown("## Current Rankings")
metric_name = config.get("metric_name", "Score")
higher_better = "higher is better" if config.get("higher_is_better", True) else "lower is better"
gr.Markdown(f"*Ranked by {metric_name} ({higher_better})*")
leaderboard_output = gr.Dataframe(
headers=["Rank", "Submission", metric_name, "User", "Timestamp"],
datatype=["number", "str", "number", "str", "str"],
interactive=False
)
refresh_btn = gr.Button("Refresh Leaderboard")
refresh_btn.click(render_leaderboard, inputs=[], outputs=[leaderboard_output])
with gr.Tab("Submit"):
gr.Markdown("## Submit Your Results")
with gr.Row():
with gr.Column():
submission_name = gr.Textbox(label="Submission Name", placeholder="MyAwesomeModel v1.0")
score = gr.Number(label=metric_name, precision=4)
username = gr.Textbox(label="Username", placeholder="Your Hugging Face username")
# Only show token field if verification is enabled
if VERIFY_USERS:
hf_token = gr.Textbox(
label="Hugging Face Token",
placeholder="hf_...",
type="password"
)
else:
hf_token = gr.Textbox(visible=False)
submission_details = gr.Textbox(
label="Additional Details (optional)",
placeholder="Model details, training info, etc.",
lines=5
)
submit_btn = gr.Button("Submit to Leaderboard")
submit_output = gr.Markdown()
submission_leaderboard = gr.Dataframe(
headers=["Rank", "Submission", metric_name, "User", "Timestamp"],
datatype=["number", "str", "number", "str", "str"],
interactive=False
)
submit_btn.click(
submit,
inputs=[submission_name, score, username, hf_token, submission_details],
outputs=[submit_output, submission_leaderboard]
)
# Add admin tab if desired
with gr.Tab("About"):
gr.Markdown("## About This Leaderboard")
# Initialize the leaderboard on load
demo.load(render_leaderboard, inputs=[], outputs=[leaderboard_output])
if __name__ == "__main__":
demo.launch()
"""