import gradio as gr import pandas as pd from math import isnan ROWS = [ {"Team_name":"Nguyen Quang Thao","vi-law-nli":0.5816,"vi-law-qa":0.8217,"vilaw-syllo":0.38,"Avg":0.5944333333}, {"Team_name":"NHK","vi-law-nli":0.9333,"vi-law-qa":0.8683,"vilaw-syllo":0.3275,"Avg":0.7097}, {"Team_name":"Innovation-LLM","vi-law-nli":0.9567,"vi-law-qa":0.8367,"vilaw-syllo":0.541666667,"Avg":0.7783555556}, {"Team_name":"Bosch@AI Team","vi-law-nli":0.97,"vi-law-qa":0.9267,"vilaw-syllo":0.535833333,"Avg":0.8108444444}, {"Team_name":"URAx","vi-law-nli":0.945,"vi-law-qa":0.8333,"vilaw-syllo":0.576666667,"Avg":0.7849888889}, {"Team_name":"Abe","vi-law-nli":0.82,"vi-law-qa":0.84,"vilaw-syllo":0.2875,"Avg":0.6491666667}, {"Team_name":"PSLV-Warrior","vi-law-nli":0.8517,"vi-law-qa":0.7483,"vilaw-syllo":0.525,"Avg":0.7083333333}, {"Team_name":"MinLegal","vi-law-nli":0.98,"vi-law-qa":0.8733,"vilaw-syllo":0.530833333,"Avg":0.7947111111}, {"Team_name":"NLPhi","vi-law-nli":0.6517,"vi-law-qa":0.815,"vilaw-syllo":0.479166667,"Avg":0.6486222222}, {"Team_name":"LICTU","vi-law-nli":0.8467,"vi-law-qa":0.8067,"vilaw-syllo":0.5375,"Avg":0.7303}, ] BASE_DF = pd.DataFrame(ROWS) NUM_COLS = ["vi-law-nli", "vi-law-qa", "vilaw-syllo", "Avg"] def _prep_df(df: pd.DataFrame) -> pd.DataFrame: out = df.copy() for c in NUM_COLS: out[c] = pd.to_numeric(out[c], errors="coerce").astype(float).round(6) out = out.sort_values("Avg", ascending=False, kind="mergesort").reset_index(drop=True) out.insert(0, "Rank", range(1, len(out)+1)) return out def _bar_html(v: float) -> str: if v is None or (isinstance(v, float) and isnan(v)): return "-" pct = max(0.0, min(1.0, float(v))) * 100 return f"
{v:.4f}
" def _render_table(df: pd.DataFrame) -> str: cols = ["Rank","Team_name"]+NUM_COLS header = "".join([f"{c}" for c in cols]) rows_html = [] for _, row in df.iterrows(): tds = [ f"{int(row['Rank'])}", f"{row['Team_name']}", f"{_bar_html(row['vi-law-nli'])}", f"{_bar_html(row['vi-law-qa'])}", f"{_bar_html(row['vilaw-syllo'])}", f"{_bar_html(row['Avg'])}", ] rows_html.append(f"{''.join(tds)}") return f"{header}{''.join(rows_html)}
" def _filter_and_sort(search: str, quick: str): df = BASE_DF.copy() if search: terms = [t.strip() for t in search.split(";") if t.strip()] for t in terms: df = df[df["Team_name"].str.contains(t, case=False, na=False)] if quick == "Top 3": df = df.sort_values("Avg", ascending=False).head(3) elif quick == "Top 5": df = df.sort_values("Avg", ascending=False).head(5) else: df = df.sort_values("Avg", ascending=False) return _prep_df(df) def _controller(search, quick): df = _filter_and_sort(search, quick) return _render_table(df), df CUSTOM_CSS = """ :root { --bg: #ffffff; --panel:#f8f9fa; --text:#000000; --muted:#6c757d; --bar:#28a745; --bar-bg:#e9ecef; } /* Global Gradio container styling */ .gradio-container { background: var(--bg) !important; color: var(--text) !important; } /* Main background */ .main { background: var(--bg) !important; } /* Panel backgrounds */ .panel { background: var(--panel) !important; } /* Text elements */ h1, h2, h3, h4, h5, h6, p, span, div { color: var(--text) !important; } /* Form elements */ input, textarea, select { background: #ffffff !important; color: var(--text) !important; border: 1px solid #ced4da !important; } /* Labels */ label { color: var(--text) !important; font-weight: 500 !important; } /* Radio buttons */ .radio-group { background: var(--panel) !important; } .radio-group label { color: var(--text) !important; } /* Buttons */ button { background: var(--bar) !important; color: white !important; border: none !important; } button:hover { background: #218838 !important; } /* Table styling */ .lb-table { width: 100%; border-collapse: collapse; background: var(--bg) !important; } .lb-table thead th { background: var(--panel) !important; padding: 10px; text-align: left; color: var(--text) !important; border-bottom: 2px solid #dee2e6 !important; } .lb-table tbody td { padding: 10px; border-bottom: 1px solid #dee2e6; color: var(--text) !important; } .lb-table td.rank { width: 60px; font-weight: 700; color: var(--text) !important; } .lb-table td.team { min-width: 200px; color: var(--text) !important; } /* Progress bars */ .cell { position: relative; height: 20px; background: var(--bar-bg); border-radius: 6px; } .cell .bar { position: absolute; left: 0; top: 0; bottom: 0; background: var(--bar); } .cell .val { position: absolute; right: 8px; top: 0; bottom: 0; display: flex; align-items: center; color: var(--text) !important; font-weight: 500 !important; } /* Gradio specific overrides */ .gradio-input, .gradio-output { background: var(--bg) !important; color: var(--text) !important; } .gradio-input input, .gradio-input textarea { background: #ffffff !important; color: var(--text) !important; border: 1px solid #ced4da !important; } .gradio-input label { color: var(--text) !important; } .gradio-radio { background: var(--panel) !important; } .gradio-radio label { color: var(--text) !important; } /* Search bar specific styling */ .gradio-input-container { background: var(--bg) !important; } .gradio-input-container label { color: var(--text) !important; background: var(--bg) !important; } /* Target the search input specifically */ .gradio-input input[type="text"] { background: #ffffff !important; color: var(--text) !important; border: 1px solid #ced4da !important; } /* Override any dark backgrounds on input containers */ .gradio-input > div { background: var(--bg) !important; } /* Ensure labels are black text on white background */ .gradio-input label, .gradio-input-container label { color: var(--text) !important; background: var(--bg) !important; } /* Override any panel backgrounds that might be dark */ .gradio-input .panel, .gradio-input .gradio-panel { background: var(--bg) !important; } /* Force all input-related elements to have light backgrounds */ .gradio-input, .gradio-input *, .gradio-input-container, .gradio-input-container * { background: var(--bg) !important; } /* Override any dark backgrounds on the entire row containing search and filter */ .gradio-row { background: var(--bg) !important; } .gradio-row * { background: var(--bg) !important; } /* Specific targeting for search and filter containers */ .gradio-input[data-testid="textbox"], .gradio-input[data-testid="radio"] { background: var(--bg) !important; } .gradio-input[data-testid="textbox"] label, .gradio-input[data-testid="radio"] label { color: var(--text) !important; background: var(--bg) !important; } /* Override any remaining dark backgrounds */ .gradio-input, .gradio-input-container, .gradio-input-container > div { background: var(--bg) !important; } /* Ensure the search input field itself is white */ input[type="text"], input[placeholder*="Tìm team"] { background: #ffffff !important; color: var(--text) !important; border: 1px solid #ced4da !important; } /* Aggressive override for the dark panel container */ .gradio-input, .gradio-input-container, .gradio-input-container > div, .gradio-input > div, .gradio-input > div > div { background: var(--bg) !important; background-color: var(--bg) !important; } /* Force all elements in the search row to have white backgrounds */ .gradio-row, .gradio-row > div, .gradio-row > div > div, .gradio-row .gradio-input, .gradio-row .gradio-input-container { background: var(--bg) !important; background-color: var(--bg) !important; } /* Override any remaining dark backgrounds with maximum specificity */ .gradio-input, .gradio-input *, .gradio-input-container, .gradio-input-container *, .gradio-input > div, .gradio-input > div *, .gradio-input-container > div, .gradio-input-container > div * { background: var(--bg) !important; background-color: var(--bg) !important; } /* Target the specific search and filter components */ .gradio-input[data-testid="textbox"], .gradio-input[data-testid="radio"], .gradio-input[data-testid="textbox"] *, .gradio-input[data-testid="radio"] * { background: var(--bg) !important; background-color: var(--bg) !important; } /* Override any CSS variables that might be setting dark backgrounds */ .gradio-input, .gradio-input-container { --background: var(--bg) !important; --background-color: var(--bg) !important; --panel-background: var(--bg) !important; --panel-background-color: var(--bg) !important; } /* Target the dark panel wrapper specifically */ .gradio-panel, .gradio-panel *, .gradio-container .gradio-panel, .gradio-container .gradio-panel *, .gradio-input .gradio-panel, .gradio-input .gradio-panel * { background: var(--bg) !important; background-color: var(--bg) !important; } /* Override any remaining dark backgrounds with !important */ .gradio-input, .gradio-input-container, .gradio-input-container > div, .gradio-input > div, .gradio-input > div > div, .gradio-input > div > div > div, .gradio-input > div > div > div > div { background: var(--bg) !important; background-color: var(--bg) !important; } /* Force the entire search row to be white */ .gradio-row, .gradio-row *, .gradio-row > div, .gradio-row > div *, .gradio-row > div > div, .gradio-row > div > div * { background: var(--bg) !important; background-color: var(--bg) !important; } /* Maximum specificity override for any dark backgrounds */ .gradio-input, .gradio-input-container, .gradio-input-container > div, .gradio-input > div, .gradio-input > div *, .gradio-input-container > div, .gradio-input-container > div *, .gradio-input > div > div, .gradio-input > div > div *, .gradio-input > div > div > div, .gradio-input > div > div > div * { background: var(--bg) !important; background-color: var(--bg) !important; } /* Download button */ .gradio-button { background: var(--bar) !important; color: white !important; border: none !important; padding: 8px 16px !important; border-radius: 6px !important; } .gradio-button:hover { background: #218838 !important; } """ with gr.Blocks(theme=gr.themes.Soft(), css=CUSTOM_CSS) as demo: gr.Markdown("# 🏆 LegalSLM Leaderboard") with gr.Row(): search = gr.Textbox(placeholder="Tìm team...", label="Search") quick = gr.Radio(choices=["All","Top 3","Top 5"], value="All", label="Quick Filter") html_table = gr.HTML(value=_render_table(_prep_df(BASE_DF))) csv_state = gr.State(_prep_df(BASE_DF)) download = gr.DownloadButton("⬇️ Tải CSV") def _download(df): path = "/tmp/leaderboard.csv" df.to_csv(path,index=False) return path download.click(_download, inputs=[csv_state], outputs=download) for comp in [search, quick]: comp.change(_controller, [search, quick], [html_table, csv_state]) if __name__ == "__main__": demo.launch() # ########################################################____V1_____############################ # # app.py # import gradio as gr # import pandas as pd # from math import isnan # ROWS = [ # {"Team_name":"Nguyen Quang Thao","vi-law-nli":0.5816,"vi-law-qa":0.8217,"vilaw-syllo":0.38,"Avg":0.5944333333}, # {"Team_name":"NHK","vi-law-nli":0.9333,"vi-law-qa":0.8683,"vilaw-syllo":0.3275,"Avg":0.7097}, # {"Team_name":"Innovation-LLM","vi-law-nli":0.9567,"vi-law-qa":0.8367,"vilaw-syllo":0.541666667,"Avg":0.7783555556}, # {"Team_name":"Bosch@AI Team","vi-law-nli":0.97,"vi-law-qa":0.9267,"vilaw-syllo":0.535833333,"Avg":0.8108444444}, # {"Team_name":"URAx","vi-law-nli":0.945,"vi-law-qa":0.8333,"vilaw-syllo":0.576666667,"Avg":0.7849888889}, # {"Team_name":"Abe","vi-law-nli":0.82,"vi-law-qa":0.84,"vilaw-syllo":0.2875,"Avg":0.6491666667}, # {"Team_name":"PSLV-Warrior","vi-law-nli":0.565,"vi-law-qa":0.0333,"vilaw-syllo":0.525,"Avg":0.3744333333}, # {"Team_name":"MinLegal","vi-law-nli":0.98,"vi-law-qa":0.8733,"vilaw-syllo":0.530833333,"Avg":0.7947111111}, # {"Team_name":"NLPhi","vi-law-nli":0.6517,"vi-law-qa":0.815,"vilaw-syllo":0.479166667,"Avg":0.6486222222}, # {"Team_name":"LICTU","vi-law-nli":0.8467,"vi-law-qa":0.8067,"vilaw-syllo":0.5375,"Avg":0.7303}, # ] # BASE_DF = pd.DataFrame(ROWS) # NUM_COLS = ["vi-law-nli", "vi-law-qa", "vilaw-syllo", "Avg"] # def _prep_df(df: pd.DataFrame) -> pd.DataFrame: # out = df.copy() # for c in NUM_COLS: # out[c] = pd.to_numeric(out[c], errors="coerce").astype(float).round(6) # out = out.sort_values("Avg", ascending=False, kind="mergesort").reset_index(drop=True) # out.insert(0, "Rank", range(1, len(out)+1)) # return out # def _bar_html(v: float) -> str: # if v is None or (isinstance(v, float) and isnan(v)): # return "-" # pct = max(0.0, min(1.0, float(v))) * 100 # return f"
{v:.4f}
" # def _render_table(df: pd.DataFrame) -> str: # cols = ["Rank","Team_name"]+NUM_COLS # header = "".join([f"{c}" for c in cols]) # rows_html = [] # for _, row in df.iterrows(): # tds = [ # f"{int(row['Rank'])}", # f"{row['Team_name']}", # f"{_bar_html(row['vi-law-nli'])}", # f"{_bar_html(row['vi-law-qa'])}", # f"{_bar_html(row['vilaw-syllo'])}", # f"{_bar_html(row['Avg'])}", # ] # rows_html.append(f"{''.join(tds)}") # return f"{header}{''.join(rows_html)}
" # def _filter_and_sort(search: str, quick: str): # df = BASE_DF.copy() # if search: # terms = [t.strip() for t in search.split(";") if t.strip()] # for t in terms: # df = df[df["Team_name"].str.contains(t, case=False, na=False)] # if quick == "Top 3": # df = df.sort_values("Avg", ascending=False).head(3) # elif quick == "Top 5": # df = df.sort_values("Avg", ascending=False).head(5) # else: # df = df.sort_values("Avg", ascending=False) # return _prep_df(df) # def _controller(search, quick): # df = _filter_and_sort(search, quick) # return _render_table(df), df # CUSTOM_CSS = """ # :root { # --bg: #0e1116; --panel:#12161f; --text:#e6e6e6; --muted:#9aa3b2; --bar:#2ea043; --bar-bg:#1f2a36; # } # .gradio-container {background: var(--bg)!important; color: var(--text);} # .lb-table { width:100%; border-collapse: collapse; } # .lb-table thead th { background: var(--panel); padding: 10px; text-align:left; } # .lb-table tbody td { padding: 10px; border-bottom: 1px solid #1d2430; } # .lb-table td.rank { width:60px; font-weight:700; } # .lb-table td.team { min-width:200px; } # .cell { position:relative; height:20px; background: var(--bar-bg); border-radius:6px; } # .cell .bar { position:absolute; left:0; top:0; bottom:0; background: var(--bar);} # .cell .val { position:absolute; right:8px; top:0; bottom:0; display:flex; align-items:center; } # """ # with gr.Blocks(css=CUSTOM_CSS) as demo: # gr.Markdown("# 🏆 LegalSLM Leaderboard") # with gr.Row(): # search = gr.Textbox(placeholder="Tìm team...", label="Search") # quick = gr.Radio(choices=["All","Top 3","Top 5"], value="All", label="Quick Filter") # html_table = gr.HTML(value=_render_table(_prep_df(BASE_DF))) # csv_state = gr.State(_prep_df(BASE_DF)) # download = gr.DownloadButton("⬇️ Tải CSV") # def _download(df): # path = "/tmp/leaderboard.csv" # df.to_csv(path,index=False) # return path # download.click(_download, inputs=[csv_state], outputs=download) # for comp in [search, quick]: # comp.change(_controller, [search, quick], [html_table, csv_state]) # if __name__ == "__main__": # demo.launch()