galb-dai commited on
Commit
999b1fd
·
1 Parent(s): 8c131f3

Update app.

Browse files
Files changed (1) hide show
  1. app.py +116 -26
app.py CHANGED
@@ -7,7 +7,7 @@ from gradio.themes import Base, colors, sizes
7
  from gradio_leaderboard import Leaderboard, SelectColumns
8
  from huggingface_hub import whoami
9
 
10
- # Updated import to get the new HTML variable
11
  from src.about import CITATION_BUTTON_LABEL, CITATION_BUTTON_TEXT, EVALUATION_QUEUE_TEXT, WHAT_IS_F1_HTML
12
  from src.datamodel.data import F1Data
13
  from src.display.css_html_js import custom_css
@@ -21,8 +21,8 @@ from src.validation.validate import MAX_INPUT_LENGTH, MIN_INPUT_LENGTH, is_submi
21
 
22
  logger = get_logger(__name__)
23
 
24
- ENSURE_ALL_PRESENT = False
25
- SPLIT = "warmup"
26
 
27
  lbdb = F1Data(
28
  cp_ds_name=CODE_PROBLEMS_REPO,
@@ -32,6 +32,7 @@ lbdb = F1Data(
32
  )
33
 
34
  leaderboard_df = None
 
35
  logger.info("Initialized LBDB")
36
 
37
 
@@ -41,23 +42,29 @@ def restart_space():
41
 
42
 
43
  def refresh_leaderboard_data():
 
44
  global leaderboard_df
45
  try:
46
  logger.info("Loading leaderboard data...")
47
  new_leaderboard_df = get_leaderboard_df(RESULTS_REPO)
 
48
  if new_leaderboard_df is not None:
49
  logger.info("Leaderboard data refreshed successfully")
50
  leaderboard_df = new_leaderboard_df
51
  else:
52
  logger.warning("No new leaderboard data found")
 
53
  except Exception as e:
54
  logger.error(f"Error refreshing leaderboard data: {e}")
 
55
 
56
 
57
  def init_leaderboard(dataframe: pd.DataFrame):
 
58
  if dataframe is None:
59
  raise ValueError("Leaderboard DataFrame is None.")
60
- return Leaderboard(
 
61
  value=dataframe,
62
  datatype=[c.type for c in fields(AutoEvalColumn)],
63
  select_columns=SelectColumns(
@@ -70,6 +77,8 @@ def init_leaderboard(dataframe: pd.DataFrame):
70
  bool_checkboxgroup_label="Hide models",
71
  interactive=False,
72
  )
 
 
73
 
74
 
75
  def add_solution_cbk(
@@ -80,33 +89,67 @@ def add_solution_cbk(
80
  profile: gr.OAuthProfile | None,
81
  oauth_token: gr.OAuthToken | None,
82
  ):
 
 
 
 
83
  if profile is None or oauth_token is None:
84
  return styled_error("Please sign in with Hugging Face before submitting.")
 
 
 
 
 
 
 
85
  user_info = fetch_user_info(oauth_token)
 
86
  stable_id = user_info.get("id") if user_info else None
 
 
87
  if not stable_id:
88
  return styled_error("Could not retrieve your stable user ID. Please try signing in again.")
 
 
89
  if not profile.username:
90
  return styled_error("Could not retrieve username. Please try signing in again.")
 
 
 
91
  try:
 
92
  if not submission_path:
93
  return styled_error("Please upload JSONL submission file.")
94
- if not is_submission_file_valid(submission_path, is_warmup_dataset=(SPLIT == "warmup")):
 
 
 
 
95
  return styled_error("Failed to read JSONL submission file. Please try again later.")
96
- for val, val_name in [(system_name, "System name"), (org, "Organisation name"), (sys_type, "System type")]:
 
 
 
 
 
 
97
  if len(val) == 0:
98
  return styled_error(f"Please fill in the '{val_name}' field.")
 
99
  if not is_valid(val):
100
  return styled_error(
101
- f"{val_name} is invalid! Must only contain characters [a-zA-Z0-9], spaces, or the special characters '-' and '.', and be of length between {MIN_INPUT_LENGTH} and {MAX_INPUT_LENGTH}."
 
 
102
  )
103
  except Exception:
104
  logger.warning("Failed to process user submission", exc_info=True)
105
- return styled_error("An error occurred. Please try again later.")
 
106
  return add_new_solutions(
107
  lbdb,
108
  profile.username,
109
- stable_id,
110
  system_name,
111
  org,
112
  sys_type,
@@ -117,32 +160,46 @@ def add_solution_cbk(
117
 
118
 
119
  def gate_submission(oauth_token: gr.OAuthToken | None):
 
 
 
 
120
  if oauth_token is None:
 
121
  return gr.update(visible=True), gr.update(visible=False)
122
  try:
123
  whoami(oauth_token.token)
 
124
  return gr.update(visible=False), gr.update(visible=True)
125
  except Exception:
 
126
  return gr.update(visible=True), gr.update(visible=False)
127
 
128
 
129
  def get_theme():
130
- return Base(
131
- primary_hue=colors.cyan,
132
- secondary_hue=colors.pink,
133
- neutral_hue=colors.gray,
134
- text_size=sizes.text_md,
 
 
 
 
135
  spacing_size=sizes.spacing_md,
136
  radius_size=sizes.radius_md,
137
  ).set(
138
- body_background_fill="#0b0f14",
139
- background_fill_primary="#0b0f14",
140
- background_fill_secondary="#0e141a",
 
141
  )
 
142
 
143
 
144
  blocks = gr.Blocks(css=custom_css, theme=get_theme())
145
  with blocks:
 
146
  gr.Image(
147
  "assets/banner.png",
148
  interactive=False,
@@ -152,24 +209,37 @@ with blocks:
152
  elem_classes=["banner_image"],
153
  )
154
 
155
- # The main layout is now controlled by these three tabs
 
 
156
  with gr.Tabs(elem_classes="tab-buttons") as tabs:
 
157
  with gr.TabItem("What is FormulaOne", id=0):
158
  gr.HTML(WHAT_IS_F1_HTML)
159
 
160
- with gr.TabItem("🏅 FormulaOne Leaderboard", id=1):
161
- refresh_leaderboard_data()
162
- assert leaderboard_df is not None, "Leaderboard data failed to load."
 
163
  leaderboard_component = init_leaderboard(leaderboard_df)
164
 
165
- with gr.TabItem("🚀 Submit Solutions", id=2):
 
 
166
  with gr.Column():
167
- gr.Markdown(EVALUATION_QUEUE_TEXT, elem_classes="markdown-text")
 
 
 
168
  gr.Markdown("# ✉️✨ Submit your solutions", elem_classes="markdown-text")
 
 
169
  login_box = gr.Group(visible=True)
170
  with login_box:
171
  gr.Markdown("Please sign in with Hugging Face to submit")
172
  gr.LoginButton()
 
 
173
  submit_panel = gr.Group(visible=False)
174
  with submit_panel:
175
  with gr.Row():
@@ -183,25 +253,45 @@ with blocks:
183
  value=ModelType.LLM.to_str(),
184
  interactive=True,
185
  )
 
186
  submission_file = gr.File(label="JSONL solutions file", file_types=[".jsonl"])
 
 
187
  submit_button = gr.Button("Submit", variant="primary")
188
  submission_result = gr.Markdown()
 
189
  submit_button.click(
190
  add_solution_cbk,
191
- [system_name_textbox, org_textbox, sys_type_dropdown, submission_file],
 
 
 
 
 
192
  submission_result,
193
  )
194
 
195
  with gr.Row():
 
196
  with gr.Accordion(CITATION_BUTTON_LABEL, open=False):
197
- gr.Code(value=CITATION_BUTTON_TEXT.strip(), elem_id="citation-block")
 
 
 
198
 
 
 
199
  blocks.load(lambda: leaderboard_df, inputs=[], outputs=[leaderboard_component])
 
 
200
  blocks.load(gate_submission, inputs=None, outputs=[login_box, submit_panel])
201
 
 
 
202
  scheduler = BackgroundScheduler()
203
  scheduler.add_job(restart_space, "interval", seconds=1800)
204
  scheduler.add_job(refresh_leaderboard_data, "interval", seconds=120)
205
  scheduler.start()
206
-
207
  blocks.queue(default_concurrency_limit=40).launch()
 
 
7
  from gradio_leaderboard import Leaderboard, SelectColumns
8
  from huggingface_hub import whoami
9
 
10
+ # MODIFICATION: Changed imports from `about.py`
11
  from src.about import CITATION_BUTTON_LABEL, CITATION_BUTTON_TEXT, EVALUATION_QUEUE_TEXT, WHAT_IS_F1_HTML
12
  from src.datamodel.data import F1Data
13
  from src.display.css_html_js import custom_css
 
21
 
22
  logger = get_logger(__name__)
23
 
24
+ ENSURE_ALL_PRESENT = False # TODO: Switch to True.
25
+ SPLIT = "warmup" # TODO temp
26
 
27
  lbdb = F1Data(
28
  cp_ds_name=CODE_PROBLEMS_REPO,
 
32
  )
33
 
34
  leaderboard_df = None
35
+
36
  logger.info("Initialized LBDB")
37
 
38
 
 
42
 
43
 
44
  def refresh_leaderboard_data():
45
+ """Refresh the leaderboard data from the latest results"""
46
  global leaderboard_df
47
  try:
48
  logger.info("Loading leaderboard data...")
49
  new_leaderboard_df = get_leaderboard_df(RESULTS_REPO)
50
+
51
  if new_leaderboard_df is not None:
52
  logger.info("Leaderboard data refreshed successfully")
53
  leaderboard_df = new_leaderboard_df
54
  else:
55
  logger.warning("No new leaderboard data found")
56
+ return None
57
  except Exception as e:
58
  logger.error(f"Error refreshing leaderboard data: {e}")
59
+ return None
60
 
61
 
62
  def init_leaderboard(dataframe: pd.DataFrame):
63
+
64
  if dataframe is None:
65
  raise ValueError("Leaderboard DataFrame is None.")
66
+
67
+ lb = Leaderboard(
68
  value=dataframe,
69
  datatype=[c.type for c in fields(AutoEvalColumn)],
70
  select_columns=SelectColumns(
 
77
  bool_checkboxgroup_label="Hide models",
78
  interactive=False,
79
  )
80
+ lb.col_count = (1, "fixed")
81
+ return lb
82
 
83
 
84
  def add_solution_cbk(
 
89
  profile: gr.OAuthProfile | None,
90
  oauth_token: gr.OAuthToken | None,
91
  ):
92
+ logger.info("Fetching user details for submission")
93
+ logger.info("PROFILE %s", profile)
94
+ logger.info("TOKEN %s", oauth_token)
95
+
96
  if profile is None or oauth_token is None:
97
  return styled_error("Please sign in with Hugging Face before submitting.")
98
+
99
+ # Display handle and display name (may change over time)
100
+ logger.info(f"User handle: {profile.username}")
101
+ display_name = profile.name or profile.username
102
+ logger.info(f"Display name: {display_name}")
103
+
104
+ # Stable account id
105
  user_info = fetch_user_info(oauth_token)
106
+ logger.info("Logged in user info: %s", user_info)
107
  stable_id = user_info.get("id") if user_info else None
108
+ logger.info(f"User stable ID: {stable_id}")
109
+
110
  if not stable_id:
111
  return styled_error("Could not retrieve your stable user ID. Please try signing in again.")
112
+ user_id = stable_id
113
+
114
  if not profile.username:
115
  return styled_error("Could not retrieve username. Please try signing in again.")
116
+ # We rely on underscores as separators in submission ID, replace it with "-".
117
+ # user_id = profile.username.replace("_", "-")
118
+
119
  try:
120
+ # Validating the submission file.
121
  if not submission_path:
122
  return styled_error("Please upload JSONL submission file.")
123
+
124
+ if not is_submission_file_valid(
125
+ submission_path,
126
+ is_warmup_dataset=(SPLIT == "warmup"),
127
+ ):
128
  return styled_error("Failed to read JSONL submission file. Please try again later.")
129
+
130
+ # Validating all user-supplied arguments.
131
+ for val, val_name in [
132
+ (system_name, "System name"),
133
+ (org, "Organisation name"),
134
+ (sys_type, "System type"),
135
+ ]:
136
  if len(val) == 0:
137
  return styled_error(f"Please fill in the '{val_name}' field.")
138
+
139
  if not is_valid(val):
140
  return styled_error(
141
+ f"{val_name} is invalid! Must only contain characters [a-zA-Z0-9], spaces, "
142
+ + "or the special characters '-' and '.', and be of length between "
143
+ + f"{MIN_INPUT_LENGTH} and {MAX_INPUT_LENGTH}."
144
  )
145
  except Exception:
146
  logger.warning("Failed to process user submission", exc_info=True)
147
+ return styled_error("An error occurred. Please try again later.") # Intentionally vague.
148
+
149
  return add_new_solutions(
150
  lbdb,
151
  profile.username,
152
+ user_id,
153
  system_name,
154
  org,
155
  sys_type,
 
160
 
161
 
162
  def gate_submission(oauth_token: gr.OAuthToken | None):
163
+ """
164
+ @brief Toggles the visibility of the login box and submission panel based on the user's login status.
165
+ """
166
+ logger.info("GATE TOKEN %s", oauth_token)
167
  if oauth_token is None:
168
+ logger.info("GATE: NO TOKEN")
169
  return gr.update(visible=True), gr.update(visible=False)
170
  try:
171
  whoami(oauth_token.token)
172
+ logger.info("GATE: TOKEN IS VALID")
173
  return gr.update(visible=False), gr.update(visible=True)
174
  except Exception:
175
+ logger.info("GATE: TOKEN HAS EXPIRED")
176
  return gr.update(visible=True), gr.update(visible=False)
177
 
178
 
179
  def get_theme():
180
+ cyber_theme = Base(
181
+ # neon-ish accents driven by hues (affects tabs, primary buttons, sliders, etc.)
182
+ primary_hue=colors.cyan, # selected tab / primary controls
183
+ secondary_hue=colors.pink, # secondary accents
184
+ neutral_hue=colors.gray, # keep neutrals subtle
185
+ # # techno font
186
+ # font=gr.themes.GoogleFont("Orbitron"),
187
+ # font_mono=gr.themes.GoogleFont("JetBrains Mono"),
188
+ text_size=sizes.text_md, # keep defaults
189
  spacing_size=sizes.spacing_md,
190
  radius_size=sizes.radius_md,
191
  ).set(
192
+ # keep overrides minimal—dark canvas; let hues do the rest
193
+ body_background_fill="#0b0f14", # deep blue-black
194
+ background_fill_primary="#0b0f14", # panels
195
+ background_fill_secondary="#0e141a", # subtle contrast
196
  )
197
+ return cyber_theme
198
 
199
 
200
  blocks = gr.Blocks(css=custom_css, theme=get_theme())
201
  with blocks:
202
+
203
  gr.Image(
204
  "assets/banner.png",
205
  interactive=False,
 
209
  elem_classes=["banner_image"],
210
  )
211
 
212
+ # MODIFICATION: Removed the top-level gr.HTML(TITLE) and gr.Markdown(INTRODUCTION_TEXT)
213
+ # The entire layout is now inside the gr.Tabs component.
214
+
215
  with gr.Tabs(elem_classes="tab-buttons") as tabs:
216
+ # MODIFICATION: Added a new TabItem for the "What is FormulaOne" page
217
  with gr.TabItem("What is FormulaOne", id=0):
218
  gr.HTML(WHAT_IS_F1_HTML)
219
 
220
+ # MODIFICATION: Changed the label and ID for the Leaderboard tab
221
+ with gr.TabItem("🏅 FormulaOne Leaderboard", elem_id="formulaone-leaderboard-tab-table", id=1):
222
+ refresh_leaderboard_data() # updates leaderboard_df
223
+ assert leaderboard_df is not None
224
  leaderboard_component = init_leaderboard(leaderboard_df)
225
 
226
+ # MODIFICATION: Changed the label and ID for the Submit Solutions tab
227
+ with gr.TabItem("🚀 Submit Solutions", elem_id="formulaone-submit-tab-table", id=2):
228
+ logger.info("Tab submission")
229
  with gr.Column():
230
+ with gr.Row():
231
+ gr.Markdown(EVALUATION_QUEUE_TEXT, elem_classes="markdown-text")
232
+
233
+ with gr.Row():
234
  gr.Markdown("# ✉️✨ Submit your solutions", elem_classes="markdown-text")
235
+
236
+ # Shown when logged OUT
237
  login_box = gr.Group(visible=True)
238
  with login_box:
239
  gr.Markdown("Please sign in with Hugging Face to submit")
240
  gr.LoginButton()
241
+
242
+ # Shown when logged IN
243
  submit_panel = gr.Group(visible=False)
244
  with submit_panel:
245
  with gr.Row():
 
253
  value=ModelType.LLM.to_str(),
254
  interactive=True,
255
  )
256
+
257
  submission_file = gr.File(label="JSONL solutions file", file_types=[".jsonl"])
258
+
259
+ logger.info("Submit button")
260
  submit_button = gr.Button("Submit", variant="primary")
261
  submission_result = gr.Markdown()
262
+
263
  submit_button.click(
264
  add_solution_cbk,
265
+ [
266
+ system_name_textbox,
267
+ org_textbox,
268
+ sys_type_dropdown,
269
+ submission_file,
270
+ ],
271
  submission_result,
272
  )
273
 
274
  with gr.Row():
275
+ logger.info("Citation")
276
  with gr.Accordion(CITATION_BUTTON_LABEL, open=False):
277
+ gr.Code(
278
+ value=CITATION_BUTTON_TEXT.strip(),
279
+ elem_id="citation-block",
280
+ )
281
 
282
+ # UI refresh triggers latest data swap.
283
+ # The work already happened in the background - refresh_leaderboard_data().
284
  blocks.load(lambda: leaderboard_df, inputs=[], outputs=[leaderboard_component])
285
+
286
+ # On initial load (and after OAuth redirect), toggle the UI based on login status.
287
  blocks.load(gate_submission, inputs=None, outputs=[login_box, submit_panel])
288
 
289
+
290
+ logger.info("Scheduler")
291
  scheduler = BackgroundScheduler()
292
  scheduler.add_job(restart_space, "interval", seconds=1800)
293
  scheduler.add_job(refresh_leaderboard_data, "interval", seconds=120)
294
  scheduler.start()
295
+ logger.info("Launch")
296
  blocks.queue(default_concurrency_limit=40).launch()
297
+ logger.info("Done")