ouhenio's picture
Update app.py
b8ab640 verified
raw
history blame
8.52 kB
import gradio as gr
import argilla as rg
import pandas as pd
import os
import time
from collections import defaultdict
from fastapi import FastAPI
from functools import lru_cache
client = rg.Argilla(
api_url=os.getenv("ARGILLA_API_URL", ""),
api_key=os.getenv("ARGILLA_API_KEY", "")
)
countries = {
"Argentina": {
"iso": "ARG",
"emoji": "๐Ÿ‡ฆ๐Ÿ‡ท"
},
"Bolivia": {
"iso": "BOL",
"emoji": "๐Ÿ‡ง๐Ÿ‡ด"
},
"Chile": {
"iso": "CHL",
"emoji": "๐Ÿ‡จ๐Ÿ‡ฑ"
},
"Colombia": {
"iso": "COL",
"emoji": "๐Ÿ‡จ๐Ÿ‡ด"
},
"Costa Rica": {
"iso": "CRI",
"emoji": "๐Ÿ‡จ๐Ÿ‡ท"
},
"Cuba": {
"iso": "CUB",
"emoji": "๐Ÿ‡จ๐Ÿ‡บ"
},
"Ecuador": {
"iso": "ECU",
"emoji": "๐Ÿ‡ช๐Ÿ‡จ"
},
"El Salvador": {
"iso": "SLV",
"emoji": "๐Ÿ‡ธ๐Ÿ‡ป"
},
"Espaรฑa": {
"iso": "ESP",
"emoji": "๐Ÿ‡ช๐Ÿ‡ธ"
},
"Guatemala": {
"iso": "GTM",
"emoji": "๐Ÿ‡ฌ๐Ÿ‡น"
},
"Honduras": {
"iso": "HND",
"emoji": "๐Ÿ‡ญ๐Ÿ‡ณ"
},
"Mรฉxico": {
"iso": "MEX",
"emoji": "๐Ÿ‡ฒ๐Ÿ‡ฝ"
},
"Nicaragua": {
"iso": "NIC",
"emoji": "๐Ÿ‡ณ๐Ÿ‡ฎ"
},
"Panamรก": {
"iso": "PAN",
"emoji": "๐Ÿ‡ต๐Ÿ‡ฆ"
},
"Paraguay": {
"iso": "PRY",
"emoji": "๐Ÿ‡ต๐Ÿ‡พ"
},
"Perรบ": {
"iso": "PER",
"emoji": "๐Ÿ‡ต๐Ÿ‡ช"
},
"Puerto Rico": {
"iso": "PRI",
"emoji": "๐Ÿ‡ต๐Ÿ‡ท"
},
"Repรบblica Dominicana": {
"iso": "DOM",
"emoji": "๐Ÿ‡ฉ๐Ÿ‡ด"
},
"Uruguay": {
"iso": "URY",
"emoji": "๐Ÿ‡บ๐Ÿ‡พ"
},
"Venezuela": {
"iso": "VEN",
"emoji": "๐Ÿ‡ป๐Ÿ‡ช"
}
}
@lru_cache(maxsize=32)
def get_user_contributions_cached(cache_buster: int):
return get_user_contributions()
def get_user_contributions():
user_contributions = defaultdict(lambda: {"username": "", "contributions": 0, "country_contributions": {}})
user_id_to_username = {}
for country in countries.keys():
iso = countries[country]["iso"]
emoji = countries[country]["emoji"]
dataset_name = f"{emoji} {country} - {iso} - Responder"
try:
print(f"Processing dataset: {dataset_name}")
dataset = client.datasets(dataset_name)
records = list(dataset.records(with_responses=True))
dataset_contributions = defaultdict(int)
for record in records:
record_dict = record.to_dict()
if "answer_1" in record_dict["responses"]:
for answer in record_dict["responses"]["answer_1"]:
if answer["user_id"]:
user_id = answer["user_id"]
dataset_contributions[user_id] += 1
if user_id not in user_id_to_username:
try:
user = client.users(id=user_id)
user_id_to_username[user_id] = user.username
except Exception as e:
print(f"Error getting username for {user_id}: {e}")
user_id_to_username[user_id] = f"User-{user_id[:8]}"
for user_id, count in dataset_contributions.items():
username = user_id_to_username.get(user_id, f"User-{user_id[:8]}")
user_contributions[user_id]["username"] = username
user_contributions[user_id]["contributions"] += count
user_contributions[user_id]["country_contributions"][country] = count
except Exception as e:
print(f"Error processing dataset {dataset_name}: {e}")
rows = []
for user_id, data in user_contributions.items():
row = {
"Username": data["username"],
"Total": data["contributions"],
"Blend-es": data["contributions"]
}
rows.append(row)
df = pd.DataFrame(rows)
if not df.empty:
df = df.sort_values("Total", ascending=False)
return df
app = FastAPI()
last_update_time = 0
cached_data = None
def create_leaderboard_ui():
global cached_data, last_update_time
current_time = time.time()
if cached_data is not None and current_time - last_update_time < 300:
df = cached_data
else:
cache_buster = int(current_time)
df = get_user_contributions_cached(cache_buster)
cached_data = df
last_update_time = current_time
if not df.empty:
df = df.reset_index(drop=True)
df.index = df.index + 1
df = df.rename_axis("Rank")
df = df.reset_index()
df_html = df.to_html(classes="leaderboard-table", border=0, index=False)
styled_html = f"""
<div style="margin: 20px 0;">
<h2>๐Ÿ† Leaderboard of User Contributions</h2>
<p>Last updated: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(last_update_time))}</p>
<style>
.leaderboard-table {{
width: 100%;
border-collapse: collapse;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
border-radius: 8px;
overflow: hidden;
}}
.leaderboard-table th {{
background-color: #1a1a2e;
color: white;
font-weight: bold;
text-align: left;
padding: 14px;
border-bottom: 2px solid #16213e;
}}
.leaderboard-table td {{
padding: 12px 14px;
border-bottom: 1px solid #e0e0e0;
}}
.leaderboard-table tr:nth-child(even) {{
background-color: #f8f9fa;
}}
.leaderboard-table tr:nth-child(odd) {{
background-color: white;
}}
.leaderboard-table tr:hover {{
background-color: #e7f5ff;
}}
.leaderboard-table tr:nth-child(1) {{
background-color: #fff7e6;
}}
.leaderboard-table tr:nth-child(2) {{
background-color: #f8f9fa;
}}
.leaderboard-table tr:nth-child(3) {{
background-color: #fff5f5;
}}
.leaderboard-table tr:nth-child(1) td:first-child {{
background-color: #ffd700;
color: #333;
font-weight: bold;
text-align: center;
border-right: 1px solid #e0e0e0;
}}
.leaderboard-table tr:nth-child(2) td:first-child {{
background-color: #c0c0c0;
color: #333;
font-weight: bold;
text-align: center;
border-right: 1px solid #e0e0e0;
}}
.leaderboard-table tr:nth-child(3) td:first-child {{
background-color: #cd7f32;
color: #333;
font-weight: bold;
text-align: center;
border-right: 1px solid #e0e0e0;
}}
.leaderboard-table tr:nth-child(1) td:nth-child(2) {{
font-weight: bold;
color: #333;
}}
.leaderboard-table tr:nth-child(2) td:nth-child(2) {{
font-weight: bold;
color: #333;
}}
.leaderboard-table tr:nth-child(3) td:nth-child(2) {{
font-weight: bold;
color: #333;
}}
</style>
{df_html}
<p><small>Note: This leaderboard shows user contributions to the BLEND-ES project across all countries.</small></p>
</div>
"""
return styled_html
def refresh_data():
global cached_data, last_update_time
cached_data = None
last_update_time = 0
return create_leaderboard_ui()
with gr.Blocks(theme=gr.themes.Base()) as demo:
with gr.Column(scale=1):
gr.Markdown("""
# ๐Ÿ† Hackaton Leaderboard
""")
leaderboard_html = gr.HTML(create_leaderboard_ui)
refresh_btn = gr.Button("๐Ÿ”„ Refresh Data", variant="primary")
refresh_btn.click(fn=refresh_data, outputs=leaderboard_html)
gr.mount_gradio_app(app, demo, path="/")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)