import os import datetime import pandas as pd from collections import Counter import gradio as gr import argilla as rg # Configuración de Argilla 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) # Reset index for better display leaderboard_df.reset_index(drop=True, inplace=True) return leaderboard_df # Custom CSS for styling 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 */ } """ # Gradio Interface with gr.Blocks(css=custom_css) as demo: gr.Markdown("# 🏆 Ranking Contribuciones Letras Carnaval Cádiz") # Emoji en el título with gr.Row(): leaderboard_output = gr.Dataframe( headers=["Usuario", "Contribuciones"], # Cambiado a "Usuario" y "Contribuciones" datatype=["str", "number"], interactive=False, elem_classes="dataframe", ) demo.load( update_dashboard, inputs=None, outputs=[leaderboard_output], ) gr.Button("🔄 Actualizar").click( # Emoji en el botón y texto "Actualizar" update_dashboard, inputs=None, outputs=[leaderboard_output], ) if __name__ == "__main__": demo.launch()