abhishek thakur commited on
Commit
908a76b
·
unverified ·
1 Parent(s): fc4883c

use oauth by default (#27)

Browse files
competitions/app.py CHANGED
@@ -4,14 +4,13 @@ import threading
4
 
5
  import requests
6
  from fastapi import FastAPI, File, Form, Request, UploadFile
7
- from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
8
  from fastapi.staticfiles import StaticFiles
9
  from fastapi.templating import Jinja2Templates
10
  from huggingface_hub import hf_hub_download
11
  from huggingface_hub.utils import disable_progress_bars
12
  from huggingface_hub.utils._errors import EntryNotFoundError
13
  from loguru import logger
14
- from pydantic import BaseModel
15
 
16
  from competitions import utils
17
  from competitions.errors import AuthenticationError
@@ -29,7 +28,6 @@ COMPETITION_ID = os.environ.get("COMPETITION_ID")
29
  OUTPUT_PATH = os.environ.get("OUTPUT_PATH", "/tmp/model")
30
  START_DATE = os.environ.get("START_DATE", "2000-12-31")
31
  DISABLE_PUBLIC_LB = int(os.environ.get("DISABLE_PUBLIC_LB", 0))
32
- USE_OAUTH = int(os.environ.get("USE_OAUTH", 1))
33
  VERSION_COMMIT_ID = os.environ.get("VERSION_COMMIT_ID", "0687567")
34
 
35
  disable_progress_bars()
@@ -50,28 +48,12 @@ if REQUIREMENTS_FNAME:
50
  utils.install_requirements(REQUIREMENTS_FNAME)
51
 
52
 
53
- class UserTeamNameUpdate(BaseModel):
54
- user_token: str
55
- new_team_name: str
56
-
57
-
58
- class User(BaseModel):
59
- user_token: str
60
-
61
-
62
- class UserLB(BaseModel):
63
- user_token: str
64
- lb: str
65
-
66
-
67
- class UserSubmissionUpdate(BaseModel):
68
- user_token: str
69
- submission_ids: str
70
-
71
-
72
  def run_job_runner():
73
- competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
74
- job_runner = JobRunner(token=HF_TOKEN, competition_info=competition_info, output_path=OUTPUT_PATH)
 
 
 
75
  job_runner.run()
76
 
77
 
@@ -80,8 +62,7 @@ thread.start()
80
 
81
 
82
  app = FastAPI()
83
- if USE_OAUTH == 1:
84
- attach_oauth(app)
85
 
86
  static_path = os.path.join(BASE_DIR, "static")
87
  app.mount("/static", StaticFiles(directory=static_path), name="static")
@@ -109,13 +90,20 @@ async def read_form(request: Request):
109
  return templates.TemplateResponse("index.html", context)
110
 
111
 
112
- @app.get("/oauth_login", response_class=HTMLResponse)
113
- async def oauth_login(request: Request):
114
- return RedirectResponse("/login/huggingface")
 
 
 
 
 
 
 
115
 
116
 
117
  @app.get("/logout", response_class=HTMLResponse)
118
- async def oauth_logout(request: Request):
119
  """Endpoint that logs out the user (e.g. delete cookie session)."""
120
  request.session.pop("oauth_info", None)
121
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
@@ -123,29 +111,17 @@ async def oauth_logout(request: Request):
123
  "request": request,
124
  "logo": competition_info.logo_url,
125
  "competition_type": competition_info.competition_type,
 
 
126
  }
127
 
128
  return templates.TemplateResponse("index.html", context)
129
 
130
 
131
- @app.get("/use_oauth", response_class=JSONResponse)
132
- async def use_oauth(request: Request):
133
- if USE_OAUTH == 1:
134
- if request.session.get("oauth_info") is not None:
135
- try:
136
- utils.user_authentication(request.session.get("oauth_info")["access_token"])
137
- return {"response": 2}
138
- except requests.exceptions.JSONDecodeError:
139
- request.session.pop("oauth_info", None)
140
- return {"response": USE_OAUTH}
141
- return {"response": USE_OAUTH}
142
-
143
-
144
  @app.get("/competition_info", response_class=JSONResponse)
145
  async def get_comp_info(request: Request):
146
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
147
  info = competition_info.competition_desc
148
- # info = markdown.markdown(info)
149
  resp = {"response": info}
150
  return resp
151
 
@@ -154,7 +130,6 @@ async def get_comp_info(request: Request):
154
  async def get_dataset_info(request: Request):
155
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
156
  info = competition_info.dataset_desc
157
- # info = markdown.markdown(info)
158
  resp = {"response": info}
159
  return resp
160
 
@@ -171,21 +146,22 @@ async def get_rules(request: Request):
171
  async def get_submission_info(request: Request):
172
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
173
  info = competition_info.submission_desc
174
- # info = markdown.markdown(info)
175
  resp = {"response": info}
176
  return resp
177
 
178
 
179
  @app.post("/leaderboard", response_class=JSONResponse)
180
- async def fetch_leaderboard(request: Request, user_lb: UserLB):
181
- if USE_OAUTH == 1:
182
- if request.session.get("oauth_info") is not None:
183
- user_lb.user_token = request.session.get("oauth_info")["access_token"]
184
 
185
  comp_org = COMPETITION_ID.split("/")[0]
186
- is_user_admin = utils.is_user_admin(user_lb.user_token, comp_org)
 
 
 
187
 
188
- if DISABLE_PUBLIC_LB == 1 and user_lb.lb == "public" and not is_user_admin:
189
  return {"response": "Public leaderboard is disabled by the competition host."}
190
 
191
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
@@ -197,11 +173,11 @@ async def fetch_leaderboard(request: Request, user_lb: UserLB):
197
  token=HF_TOKEN,
198
  scoring_metric=competition_info.scoring_metric,
199
  )
200
- if user_lb.lb == "private":
201
  current_utc_time = datetime.datetime.now()
202
  if current_utc_time < competition_info.end_date and not is_user_admin:
203
  return {"response": "Private leaderboard will be available after the competition ends."}
204
- df = leaderboard.fetch(private=user_lb.lb == "private")
205
 
206
  if len(df) == 0:
207
  return {"response": "No teams yet. Why not make a submission?"}
@@ -210,10 +186,12 @@ async def fetch_leaderboard(request: Request, user_lb: UserLB):
210
 
211
 
212
  @app.post("/my_submissions", response_class=JSONResponse)
213
- async def my_submissions(request: Request, user: User):
214
- if USE_OAUTH == 1:
215
- if request.session.get("oauth_info") is not None:
216
- user.user_token = request.session.get("oauth_info")["access_token"]
 
 
217
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
218
  sub = Submissions(
219
  end_date=competition_info.end_date,
@@ -224,13 +202,13 @@ async def my_submissions(request: Request, user: User):
224
  hardware=competition_info.hardware,
225
  )
226
  try:
227
- subs = sub.my_submissions(user.user_token)
228
  except AuthenticationError:
229
  return {
230
  "response": {
231
  "submissions": "",
232
  "submission_text": SUBMISSION_TEXT.format(competition_info.submission_limit),
233
- "error": "**Invalid token**",
234
  "team_name": "",
235
  }
236
  }
@@ -243,7 +221,7 @@ async def my_submissions(request: Request, user: User):
243
  submission_text = SUBMISSION_TEXT.format(competition_info.submission_limit)
244
  submission_selection_text = SUBMISSION_SELECTION_TEXT.format(competition_info.selection_limit)
245
 
246
- team_name = utils.get_team_name(user.user_token, COMPETITION_ID, HF_TOKEN)
247
 
248
  resp = {
249
  "response": {
@@ -261,15 +239,15 @@ async def new_submission(
261
  request: Request,
262
  submission_file: UploadFile = File(None),
263
  hub_model: str = Form(...),
264
- token: str = Form(None),
265
  submission_comment: str = Form(None),
266
  ):
267
  if submission_comment is None:
268
  submission_comment = ""
269
 
270
- if USE_OAUTH == 1:
271
- if request.session.get("oauth_info") is not None:
272
- token = request.session.get("oauth_info")["access_token"]
 
273
 
274
  if token is None:
275
  return {"response": "Invalid token"}
@@ -303,10 +281,11 @@ async def new_submission(
303
 
304
 
305
  @app.post("/update_selected_submissions", response_class=JSONResponse)
306
- def update_selected_submissions(request: Request, user_sub: UserSubmissionUpdate):
307
- if USE_OAUTH == 1:
308
- if request.session.get("oauth_info") is not None:
309
- user_sub.user_token = request.session.get("oauth_info")["access_token"]
 
310
 
311
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
312
  sub = Submissions(
@@ -317,25 +296,29 @@ def update_selected_submissions(request: Request, user_sub: UserSubmissionUpdate
317
  competition_type=competition_info.competition_type,
318
  hardware=competition_info.hardware,
319
  )
320
- submission_ids = user_sub.submission_ids.split(",")
321
  submission_ids = [s.strip() for s in submission_ids]
322
  if len(submission_ids) > competition_info.selection_limit:
323
  return {
324
  "success": False,
325
  "error": f"Please select at most {competition_info.selection_limit} submissions.",
326
  }
327
- sub.update_selected_submissions(user_token=user_sub.user_token, selected_submission_ids=submission_ids)
328
  return {"success": True, "error": ""}
329
 
330
 
331
  @app.post("/update_team_name", response_class=JSONResponse)
332
- def update_team_name(request: Request, user_team: UserTeamNameUpdate):
333
- if USE_OAUTH == 1:
334
- if request.session.get("oauth_info") is not None:
335
- user_team.user_token = request.session.get("oauth_info")["access_token"]
 
 
 
 
336
 
337
  try:
338
- utils.update_team_name(user_team.user_token, user_team.new_team_name, COMPETITION_ID, HF_TOKEN)
339
  return {"success": True, "error": ""}
340
  except Exception as e:
341
  return {"success": False, "error": str(e)}
 
4
 
5
  import requests
6
  from fastapi import FastAPI, File, Form, Request, UploadFile
7
+ from fastapi.responses import HTMLResponse, JSONResponse
8
  from fastapi.staticfiles import StaticFiles
9
  from fastapi.templating import Jinja2Templates
10
  from huggingface_hub import hf_hub_download
11
  from huggingface_hub.utils import disable_progress_bars
12
  from huggingface_hub.utils._errors import EntryNotFoundError
13
  from loguru import logger
 
14
 
15
  from competitions import utils
16
  from competitions.errors import AuthenticationError
 
28
  OUTPUT_PATH = os.environ.get("OUTPUT_PATH", "/tmp/model")
29
  START_DATE = os.environ.get("START_DATE", "2000-12-31")
30
  DISABLE_PUBLIC_LB = int(os.environ.get("DISABLE_PUBLIC_LB", 0))
 
31
  VERSION_COMMIT_ID = os.environ.get("VERSION_COMMIT_ID", "0687567")
32
 
33
  disable_progress_bars()
 
48
  utils.install_requirements(REQUIREMENTS_FNAME)
49
 
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  def run_job_runner():
52
+ job_runner = JobRunner(
53
+ competition_id=COMPETITION_ID,
54
+ token=HF_TOKEN,
55
+ output_path=OUTPUT_PATH,
56
+ )
57
  job_runner.run()
58
 
59
 
 
62
 
63
 
64
  app = FastAPI()
65
+ attach_oauth(app)
 
66
 
67
  static_path = os.path.join(BASE_DIR, "static")
68
  app.mount("/static", StaticFiles(directory=static_path), name="static")
 
90
  return templates.TemplateResponse("index.html", context)
91
 
92
 
93
+ @app.get("/login_status", response_class=JSONResponse)
94
+ async def use_oauth(request: Request):
95
+ if request.session.get("oauth_info") is not None:
96
+ try:
97
+ utils.user_authentication(request.session.get("oauth_info")["access_token"])
98
+ return {"response": 2}
99
+ except requests.exceptions.JSONDecodeError:
100
+ request.session.pop("oauth_info", None)
101
+ return {"response": 1}
102
+ return {"response": 1}
103
 
104
 
105
  @app.get("/logout", response_class=HTMLResponse)
106
+ async def user_logout(request: Request):
107
  """Endpoint that logs out the user (e.g. delete cookie session)."""
108
  request.session.pop("oauth_info", None)
109
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
 
111
  "request": request,
112
  "logo": competition_info.logo_url,
113
  "competition_type": competition_info.competition_type,
114
+ "version_commit_id": VERSION_COMMIT_ID[:7],
115
+ "rules_available": competition_info.rules is not None,
116
  }
117
 
118
  return templates.TemplateResponse("index.html", context)
119
 
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  @app.get("/competition_info", response_class=JSONResponse)
122
  async def get_comp_info(request: Request):
123
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
124
  info = competition_info.competition_desc
 
125
  resp = {"response": info}
126
  return resp
127
 
 
130
  async def get_dataset_info(request: Request):
131
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
132
  info = competition_info.dataset_desc
 
133
  resp = {"response": info}
134
  return resp
135
 
 
146
  async def get_submission_info(request: Request):
147
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
148
  info = competition_info.submission_desc
 
149
  resp = {"response": info}
150
  return resp
151
 
152
 
153
  @app.post("/leaderboard", response_class=JSONResponse)
154
+ async def fetch_leaderboard(request: Request, lb: str):
155
+ if request.session.get("oauth_info") is not None:
156
+ user_token = request.session.get("oauth_info").get("access_token")
 
157
 
158
  comp_org = COMPETITION_ID.split("/")[0]
159
+ if user_token is not None:
160
+ is_user_admin = utils.is_user_admin(user_token, comp_org)
161
+ else:
162
+ is_user_admin = False
163
 
164
+ if DISABLE_PUBLIC_LB == 1 and lb == "public" and not is_user_admin:
165
  return {"response": "Public leaderboard is disabled by the competition host."}
166
 
167
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
 
173
  token=HF_TOKEN,
174
  scoring_metric=competition_info.scoring_metric,
175
  )
176
+ if lb == "private":
177
  current_utc_time = datetime.datetime.now()
178
  if current_utc_time < competition_info.end_date and not is_user_admin:
179
  return {"response": "Private leaderboard will be available after the competition ends."}
180
+ df = leaderboard.fetch(private=lb == "private")
181
 
182
  if len(df) == 0:
183
  return {"response": "No teams yet. Why not make a submission?"}
 
186
 
187
 
188
  @app.post("/my_submissions", response_class=JSONResponse)
189
+ async def my_submissions(request: Request):
190
+ if request.session.get("oauth_info") is not None:
191
+ user_token = request.session.get("oauth_info")["access_token"]
192
+ else:
193
+ user_token = "abc"
194
+
195
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
196
  sub = Submissions(
197
  end_date=competition_info.end_date,
 
202
  hardware=competition_info.hardware,
203
  )
204
  try:
205
+ subs = sub.my_submissions(user_token)
206
  except AuthenticationError:
207
  return {
208
  "response": {
209
  "submissions": "",
210
  "submission_text": SUBMISSION_TEXT.format(competition_info.submission_limit),
211
+ "error": "**Invalid token. Please login.**",
212
  "team_name": "",
213
  }
214
  }
 
221
  submission_text = SUBMISSION_TEXT.format(competition_info.submission_limit)
222
  submission_selection_text = SUBMISSION_SELECTION_TEXT.format(competition_info.selection_limit)
223
 
224
+ team_name = utils.get_team_name(user_token, COMPETITION_ID, HF_TOKEN)
225
 
226
  resp = {
227
  "response": {
 
239
  request: Request,
240
  submission_file: UploadFile = File(None),
241
  hub_model: str = Form(...),
 
242
  submission_comment: str = Form(None),
243
  ):
244
  if submission_comment is None:
245
  submission_comment = ""
246
 
247
+ if request.session.get("oauth_info") is not None:
248
+ token = request.session.get("oauth_info")["access_token"]
249
+ else:
250
+ token = None
251
 
252
  if token is None:
253
  return {"response": "Invalid token"}
 
281
 
282
 
283
  @app.post("/update_selected_submissions", response_class=JSONResponse)
284
+ def update_selected_submissions(request: Request, submission_ids: str):
285
+ if request.session.get("oauth_info") is not None:
286
+ user_token = request.session.get("oauth_info")["access_token"]
287
+ else:
288
+ return {"success": False, "error": "Invalid token"}
289
 
290
  competition_info = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
291
  sub = Submissions(
 
296
  competition_type=competition_info.competition_type,
297
  hardware=competition_info.hardware,
298
  )
299
+ submission_ids = submission_ids.split(",")
300
  submission_ids = [s.strip() for s in submission_ids]
301
  if len(submission_ids) > competition_info.selection_limit:
302
  return {
303
  "success": False,
304
  "error": f"Please select at most {competition_info.selection_limit} submissions.",
305
  }
306
+ sub.update_selected_submissions(user_token=user_token, selected_submission_ids=submission_ids)
307
  return {"success": True, "error": ""}
308
 
309
 
310
  @app.post("/update_team_name", response_class=JSONResponse)
311
+ def update_team_name(request: Request, new_team_name: str):
312
+ if request.session.get("oauth_info") is not None:
313
+ user_token = request.session.get("oauth_info")["access_token"]
314
+ else:
315
+ return {"success": False, "error": "Invalid token"}
316
+
317
+ if str(new_team_name).strip() == "":
318
+ return {"success": False, "error": "Team name cannot be empty."}
319
 
320
  try:
321
+ utils.update_team_name(user_token, new_team_name, COMPETITION_ID, HF_TOKEN)
322
  return {"success": True, "error": ""}
323
  except Exception as e:
324
  return {"success": False, "error": str(e)}
competitions/create.py CHANGED
@@ -253,7 +253,6 @@ def _create(
253
  private=True,
254
  )
255
  api.add_space_secret(repo_id=f"{organization}/{competition_name}", key="HF_TOKEN", value=user_token)
256
- api.add_space_secret(repo_id=f"{organization}/{competition_name}", key="USE_OAUTH", value="1")
257
  api.add_space_secret(
258
  repo_id=f"{organization}/{competition_name}",
259
  key="COMPETITION_ID",
 
253
  private=True,
254
  )
255
  api.add_space_secret(repo_id=f"{organization}/{competition_name}", key="HF_TOKEN", value=user_token)
 
256
  api.add_space_secret(
257
  repo_id=f"{organization}/{competition_name}",
258
  key="COMPETITION_ID",
competitions/oauth.py CHANGED
@@ -25,10 +25,7 @@ RANDOM_STRING = "".join(random.choices(string.ascii_letters + string.digits, k=2
25
 
26
 
27
  def attach_oauth(app: fastapi.FastAPI):
28
- if os.environ.get("SPACE_ID") is not None and int(os.environ.get("USE_OAUTH", 0)) == 1:
29
- _add_oauth_routes(app)
30
- else:
31
- return
32
  # Session Middleware requires a secret key to sign the cookies. Let's use a hash
33
  # of the OAuth secret key to make it unique to the Space + updated in case OAuth
34
  # config gets updated.
@@ -86,8 +83,21 @@ def _add_oauth_routes(app: fastapi.FastAPI) -> None:
86
  try:
87
  oauth_info = await oauth.huggingface.authorize_access_token(request) # type: ignore
88
  except MismatchingStateError:
89
- print("Session dict:", dict(request.session))
90
- raise
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  request.session["oauth_info"] = oauth_info
92
  return _redirect_to_target(request)
93
 
 
25
 
26
 
27
  def attach_oauth(app: fastapi.FastAPI):
28
+ _add_oauth_routes(app)
 
 
 
29
  # Session Middleware requires a secret key to sign the cookies. Let's use a hash
30
  # of the OAuth secret key to make it unique to the Space + updated in case OAuth
31
  # config gets updated.
 
83
  try:
84
  oauth_info = await oauth.huggingface.authorize_access_token(request) # type: ignore
85
  except MismatchingStateError:
86
+ # If the state mismatch, it is very likely that the cookie is corrupted.
87
+ # There is a bug reported in authlib that causes the token to grow indefinitely if the user tries to login
88
+ # repeatedly. Since cookies cannot get bigger than 4kb, the token will be truncated at some point - hence
89
+ # losing the state. A workaround is to delete the cookie and redirect the user to the login page again.
90
+ # See https://github.com/lepture/authlib/issues/622 for more details.
91
+ login_uri = "/login/huggingface"
92
+ if "_target_url" in request.query_params:
93
+ login_uri += "?" + urllib.parse.urlencode( # Keep same _target_url as before
94
+ {"_target_url": request.query_params["_target_url"]}
95
+ )
96
+ for key in list(request.session.keys()):
97
+ # Delete all keys that are related to the OAuth state
98
+ if key.startswith("_state_huggingface"):
99
+ request.session.pop(key)
100
+ return RedirectResponse(login_uri)
101
  request.session["oauth_info"] = oauth_info
102
  return _redirect_to_target(request)
103
 
competitions/runner.py CHANGED
@@ -26,11 +26,12 @@ _DOCKERFILE = _DOCKERFILE.replace("\n", " ").replace(" ", "\n").strip()
26
 
27
  @dataclass
28
  class JobRunner:
29
- competition_info: CompetitionInfo
30
  token: str
31
  output_path: str
32
 
33
  def __post_init__(self):
 
34
  self.competition_id = self.competition_info.competition_id
35
  self.competition_type = self.competition_info.competition_type
36
  self.metric = self.competition_info.metric
 
26
 
27
  @dataclass
28
  class JobRunner:
29
+ competition_id: str
30
  token: str
31
  output_path: str
32
 
33
  def __post_init__(self):
34
+ self.competition_info = CompetitionInfo(competition_id=self.competition_id, autotrain_token=self.token)
35
  self.competition_id = self.competition_info.competition_id
36
  self.competition_type = self.competition_info.competition_type
37
  self.metric = self.competition_info.metric
competitions/templates/index.html CHANGED
@@ -70,10 +70,8 @@
70
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
71
  articleLoadingSpinner.classList.remove('hidden');
72
 
73
- const userToken = document.getElementById('user_token').value;
74
  const payload = {
75
  lb: leaderboardType,
76
- user_token: userToken
77
  };
78
 
79
  fetch('/leaderboard', {
@@ -109,7 +107,6 @@
109
  }
110
 
111
  function fetchAndDisplaySubmissions() {
112
- const userToken = document.getElementById('user_token').value;
113
  const apiEndpoint = '/my_submissions';
114
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
115
  articleLoadingSpinner.classList.remove('hidden');
@@ -118,8 +115,7 @@
118
  method: 'POST',
119
  headers: {
120
  'Content-Type': 'application/json',
121
- },
122
- body: JSON.stringify({ "user_token": userToken })
123
  };
124
 
125
  fetch(apiEndpoint, requestOptions)
@@ -160,10 +156,10 @@
160
  // add a text field which displays team name and a button to update team name
161
  contentDiv.innerHTML = marked.parse(data.response.submission_text) + tableHTML;
162
  document.getElementById('updateSelectedSubmissionsButton').addEventListener('click', function () {
163
- updateSelectedSubmissions(userToken);
164
  });
165
  document.getElementById('updateTeamNameButton').addEventListener('click', function () {
166
- updateTeamName(userToken);
167
  });
168
  } else {
169
  // Display message if there are no submissions
@@ -201,7 +197,6 @@
201
 
202
  function fetchAndDisplayTeamInfo() {
203
  const apiEndpoint = '/team_info';
204
- const userToken = document.getElementById('user_token').value;
205
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
206
  articleLoadingSpinner.classList.remove('hidden');
207
 
@@ -209,8 +204,7 @@
209
  method: 'POST',
210
  headers: {
211
  'Content-Type': 'application/json',
212
- },
213
- body: JSON.stringify({ "user_token": userToken })
214
  };
215
  fetch(apiEndpoint, requestOptions)
216
  .then(response => {
@@ -332,20 +326,17 @@
332
  }
333
 
334
  function checkOAuth() {
335
- var url = "/use_oauth";
336
  makeApiRequest(url, function (response) {
337
  if (response === 1) {
338
- document.getElementById("userToken").style.display = "none";
339
  document.getElementById("loginButton").style.display = "block";
340
  document.getElementById("logoutButton").style.display = "none";
341
  } else if (response === 2) {
342
- document.getElementById("userToken").style.display = "none";
343
  document.getElementById("loginButton").style.display = "none";
344
  document.getElementById("logoutButton").style.display = "block";
345
  }
346
  });
347
  }
348
-
349
  window.onload = checkOAuth;
350
  </script>
351
  </head>
@@ -463,13 +454,6 @@
463
  </li>
464
  </ul>
465
  </li>
466
- <li id="userToken">
467
- <label for="user_token" class="text-xs font-medium">Hugging Face <a
468
- href="https://huggingface.co/settings/tokens" target="_blank">Token</a> (read-only)
469
- </label>
470
- <input type="password" name="user_token" id="user_token"
471
- class="mt-1 block w-full border border-gray-300 px-3 py-1.5 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
472
- </li>
473
  <li id="loginButton" style="display: none;">
474
  <a href="/login/huggingface" target="_blank"
475
  class="flex bg-blue-500 hover:bg-blue-700 text-white text-center font-bold py-2 px-4 rounded">Login
@@ -589,9 +573,6 @@
589
  return;
590
  }
591
 
592
- var token = document.getElementById('user_token').value;
593
- formData.append('token', token);
594
-
595
  var submissionComment = document.getElementById('submission_comment').value;
596
  formData.append('submission_comment', submissionComment);
597
 
@@ -615,7 +596,7 @@
615
  </script>
616
 
617
  <script>
618
- function updateSelectedSubmissions(userToken) {
619
  const selectedSubmissions = document.querySelectorAll('input[name="selectedSubmissions"]:checked');
620
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
621
  articleLoadingSpinner.classList.remove('hidden');
@@ -631,7 +612,6 @@
631
  'Content-Type': 'application/json',
632
  },
633
  body: JSON.stringify({
634
- "user_token": userToken,
635
  "submission_ids": selectedSubmissionIds.join(',')
636
  })
637
  };
@@ -664,7 +644,7 @@
664
  </script>
665
 
666
  <script>
667
- function updateTeamName(userToken) {
668
  const teamName = document.getElementById('team_name').value;
669
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
670
  articleLoadingSpinner.classList.remove('hidden');
@@ -676,7 +656,6 @@
676
  'Content-Type': 'application/json',
677
  },
678
  body: JSON.stringify({
679
- "user_token": userToken,
680
  "new_team_name": teamName
681
  })
682
  };
 
70
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
71
  articleLoadingSpinner.classList.remove('hidden');
72
 
 
73
  const payload = {
74
  lb: leaderboardType,
 
75
  };
76
 
77
  fetch('/leaderboard', {
 
107
  }
108
 
109
  function fetchAndDisplaySubmissions() {
 
110
  const apiEndpoint = '/my_submissions';
111
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
112
  articleLoadingSpinner.classList.remove('hidden');
 
115
  method: 'POST',
116
  headers: {
117
  'Content-Type': 'application/json',
118
+ }
 
119
  };
120
 
121
  fetch(apiEndpoint, requestOptions)
 
156
  // add a text field which displays team name and a button to update team name
157
  contentDiv.innerHTML = marked.parse(data.response.submission_text) + tableHTML;
158
  document.getElementById('updateSelectedSubmissionsButton').addEventListener('click', function () {
159
+ updateSelectedSubmissions();
160
  });
161
  document.getElementById('updateTeamNameButton').addEventListener('click', function () {
162
+ updateTeamName();
163
  });
164
  } else {
165
  // Display message if there are no submissions
 
197
 
198
  function fetchAndDisplayTeamInfo() {
199
  const apiEndpoint = '/team_info';
 
200
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
201
  articleLoadingSpinner.classList.remove('hidden');
202
 
 
204
  method: 'POST',
205
  headers: {
206
  'Content-Type': 'application/json',
207
+ }
 
208
  };
209
  fetch(apiEndpoint, requestOptions)
210
  .then(response => {
 
326
  }
327
 
328
  function checkOAuth() {
329
+ var url = "/login_status";
330
  makeApiRequest(url, function (response) {
331
  if (response === 1) {
 
332
  document.getElementById("loginButton").style.display = "block";
333
  document.getElementById("logoutButton").style.display = "none";
334
  } else if (response === 2) {
 
335
  document.getElementById("loginButton").style.display = "none";
336
  document.getElementById("logoutButton").style.display = "block";
337
  }
338
  });
339
  }
 
340
  window.onload = checkOAuth;
341
  </script>
342
  </head>
 
454
  </li>
455
  </ul>
456
  </li>
 
 
 
 
 
 
 
457
  <li id="loginButton" style="display: none;">
458
  <a href="/login/huggingface" target="_blank"
459
  class="flex bg-blue-500 hover:bg-blue-700 text-white text-center font-bold py-2 px-4 rounded">Login
 
573
  return;
574
  }
575
 
 
 
 
576
  var submissionComment = document.getElementById('submission_comment').value;
577
  formData.append('submission_comment', submissionComment);
578
 
 
596
  </script>
597
 
598
  <script>
599
+ function updateSelectedSubmissions() {
600
  const selectedSubmissions = document.querySelectorAll('input[name="selectedSubmissions"]:checked');
601
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
602
  articleLoadingSpinner.classList.remove('hidden');
 
612
  'Content-Type': 'application/json',
613
  },
614
  body: JSON.stringify({
 
615
  "submission_ids": selectedSubmissionIds.join(',')
616
  })
617
  };
 
644
  </script>
645
 
646
  <script>
647
+ function updateTeamName() {
648
  const teamName = document.getElementById('team_name').value;
649
  const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
650
  articleLoadingSpinner.classList.remove('hidden');
 
656
  'Content-Type': 'application/json',
657
  },
658
  body: JSON.stringify({
 
659
  "new_team_name": teamName
660
  })
661
  };