|
import os |
|
import datetime |
|
import pandas as pd |
|
from collections import Counter |
|
import gradio as gr |
|
import argilla as rg |
|
|
|
|
|
client = rg.Argilla( |
|
api_url=os.getenv("ARGILLA_API_URL"), api_key=os.getenv("ARGILLA_API_KEY") |
|
) |
|
|
|
|
|
def fetch_data(dataset_name: str, workspace: str): |
|
""" |
|
Fetch dataset from Argilla. |
|
Args: |
|
dataset_name: Name of the dataset. |
|
workspace: Workspace where the dataset is located. |
|
Returns: |
|
Dataset object or None if an error occurs. |
|
""" |
|
try: |
|
dataset = client.datasets(dataset_name, workspace=workspace) |
|
if not dataset: |
|
raise ValueError(f"Dataset '{dataset_name}' not found in workspace '{workspace}'") |
|
return dataset |
|
except Exception as e: |
|
print(f"Error fetching dataset: {e}") |
|
return None |
|
|
|
|
|
def get_progress(dataset) -> dict: |
|
""" |
|
Calculate the annotation progress of the dataset. |
|
Args: |
|
dataset: The dataset to calculate progress for. |
|
Returns: |
|
A dictionary with the total number of records, the number of annotated records, and the progress percentage. |
|
""" |
|
records = list(dataset.records) |
|
total_records = len(records) |
|
annotated_records = len( |
|
[record.status for record in records if record.status == "completed"] |
|
) |
|
progress = (annotated_records / total_records) * 100 if total_records > 0 else 0 |
|
return { |
|
"total": total_records, |
|
"annotated": annotated_records, |
|
"progress": progress, |
|
} |
|
|
|
|
|
def get_leaderboard(dataset) -> dict: |
|
""" |
|
Get the leaderboard of user contributions. |
|
Args: |
|
dataset: The dataset to calculate contributions for. |
|
Returns: |
|
A dictionary with usernames as keys and their contribution counts as values. |
|
""" |
|
contributions = {} |
|
for record in dataset.records: |
|
if record.status == "completed" and record.responses: |
|
responses_list = list(record.responses) |
|
if responses_list: |
|
first_response = responses_list[0] |
|
if hasattr(first_response, "user_id"): |
|
unique_key = record.metadata.get("contribution_id", record.id) |
|
contributions[unique_key] = client.users(id=first_response.user_id).username |
|
return dict(Counter(contributions.values())) |
|
|
|
|
|
def update_dashboard(): |
|
""" |
|
Update the dashboard with the latest data. |
|
Returns: |
|
A DataFrame with the top 5 contributors. |
|
""" |
|
dataset = fetch_data(os.getenv("DATASET_NAME"), os.getenv("WORKSPACE")) |
|
if not dataset: |
|
return pd.DataFrame(columns=["Usuario", "Contribuciones"]) |
|
|
|
user_annotations = get_leaderboard(dataset) |
|
leaderboard_df = pd.DataFrame( |
|
list(user_annotations.items()), columns=["Usuario", "Contribuciones"] |
|
) |
|
leaderboard_df = leaderboard_df.sort_values("Contribuciones", ascending=False).head(5) |
|
|
|
|
|
leaderboard_df.reset_index(drop=True, inplace=True) |
|
|
|
return leaderboard_df |
|
|
|
|
|
|
|
custom_css = """ |
|
.gradio-container { |
|
font-family: 'Poppins', sans-serif; /* Fuente moderna */ |
|
background-color: white; /* Fondo blanco */ |
|
padding: 20px; |
|
border-radius: 10px; |
|
} |
|
h1 { |
|
color: #2c3e50; /* Color oscuro para el título */ |
|
text-align: center; |
|
font-size: 32px; |
|
margin-bottom: 20px; |
|
} |
|
.dataframe { |
|
width: 100%; |
|
border-collapse: collapse; |
|
margin: 0 auto; |
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
|
border-radius: 10px; |
|
overflow: hidden; |
|
background-color: white; /* Fondo blanco para la tabla */ |
|
border: 1px solid white; /* Líneas separadoras blancas */ |
|
} |
|
.dataframe th, .dataframe td { |
|
padding: 12px 15px; |
|
text-align: left; |
|
border-bottom: 1px solid white; /* Líneas separadoras blancas */ |
|
} |
|
.dataframe th { |
|
background-color: #6c757d; /* Color más neutro (gris) */ |
|
color: white; |
|
font-weight: bold; |
|
} |
|
.dataframe tr:nth-child(even) { |
|
background-color: #f8f9fa; /* Fondo gris claro para filas pares */ |
|
} |
|
.dataframe tr:hover { |
|
background-color: #e9ecef; /* Color de hover más suave */ |
|
} |
|
.dataframe tr:first-child { |
|
background-color: #FFD700; /* Dorado para el 1er puesto */ |
|
color: #000; /* Texto negro para mejor contraste */ |
|
} |
|
.dataframe tr:nth-child(2) { |
|
background-color: #C0C0C0; /* Plateado para el 2do puesto */ |
|
color: #000; /* Texto negro para mejor contraste */ |
|
} |
|
.dataframe tr:nth-child(3) { |
|
background-color: #cd7f32; /* Bronce para el 3er puesto */ |
|
color: #000; /* Texto negro para mejor contraste */ |
|
} |
|
.dataframe tr:nth-child(4), .dataframe tr:nth-child(5) { |
|
background-color: #2c3e50; /* Color oscuro para el 4º y 5º puesto */ |
|
color: #fff; /* Texto blanco para mejor contraste */ |
|
} |
|
/* Añadir emojis a los puestos */ |
|
.dataframe tr:first-child td:first-child::before { |
|
content: "🥇 "; /* Emoji para el 1er puesto */ |
|
} |
|
.dataframe tr:nth-child(2) td:first-child::before { |
|
content: "🥈 "; /* Emoji para el 2do puesto */ |
|
} |
|
.dataframe tr:nth-child(3) td:first-child::before { |
|
content: "🥉 "; /* Emoji para el 3er puesto */ |
|
} |
|
.dataframe tr:nth-child(4) td:first-child::before, |
|
.dataframe tr:nth-child(5) td:first-child::before { |
|
content: "🎖️ "; /* Emoji para el 4º y 5º puesto */ |
|
} |
|
/* Estilo para el botón */ |
|
button { |
|
width: auto !important; /* Ancho automático */ |
|
padding: 10px 20px !important; /* Padding más pequeño */ |
|
font-size: 16px !important; |
|
background-color: #6c757d !important; /* Color más neutro */ |
|
color: white !important; |
|
border: none !important; |
|
border-radius: 5px !important; |
|
cursor: pointer !important; |
|
} |
|
button:hover { |
|
background-color: #5a6268 !important; /* Color más oscuro al pasar el ratón */ |
|
} |
|
/* Eliminar scroll */ |
|
.dataframe { |
|
overflow: hidden !important; /* Eliminar scroll */ |
|
} |
|
""" |
|
|
|
|
|
|
|
with gr.Blocks(css=custom_css) as demo: |
|
gr.Markdown("# 🏆 Ranking Contribuciones Letras Carnaval Cádiz") |
|
|
|
with gr.Row(): |
|
leaderboard_output = gr.Dataframe( |
|
headers=["Usuario", "Contribuciones"], |
|
datatype=["str", "number"], |
|
interactive=False, |
|
elem_classes="dataframe", |
|
) |
|
|
|
demo.load( |
|
update_dashboard, |
|
inputs=None, |
|
outputs=[leaderboard_output], |
|
) |
|
gr.Button("🔄 Actualizar").click( |
|
update_dashboard, |
|
inputs=None, |
|
outputs=[leaderboard_output], |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |