Abhishek Thakur
commited on
Commit
·
42c2745
1
Parent(s):
c2fd2d2
further improvements
Browse files- competitions/app.py +29 -8
- competitions/evaluate.py +0 -1
- competitions/leaderboard.py +18 -9
- competitions/runner.py +1 -0
- competitions/submissions.py +42 -11
- competitions/templates/index.html +63 -26
- competitions/utils.py +4 -3
competitions/app.py
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import os
|
2 |
import threading
|
3 |
|
@@ -6,9 +7,11 @@ from fastapi import FastAPI, File, Form, Request, UploadFile
|
|
6 |
from fastapi.responses import HTMLResponse, JSONResponse
|
7 |
from fastapi.staticfiles import StaticFiles
|
8 |
from fastapi.templating import Jinja2Templates
|
|
|
9 |
from loguru import logger
|
10 |
from pydantic import BaseModel
|
11 |
|
|
|
12 |
from competitions.info import CompetitionInfo
|
13 |
from competitions.leaderboard import Leaderboard
|
14 |
from competitions.runner import JobRunner
|
@@ -20,6 +23,9 @@ HF_TOKEN = os.environ.get("HF_TOKEN", None)
|
|
20 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
21 |
COMPETITION_ID = os.getenv("COMPETITION_ID")
|
22 |
OUTPUT_PATH = os.getenv("OUTPUT_PATH", "/tmp/model")
|
|
|
|
|
|
|
23 |
COMP_INFO = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
|
24 |
|
25 |
|
@@ -91,8 +97,12 @@ async def get_leaderboard(request: Request, lb: str):
|
|
91 |
eval_higher_is_better=COMP_INFO.eval_higher_is_better,
|
92 |
max_selected_submissions=COMP_INFO.selection_limit,
|
93 |
competition_id=COMPETITION_ID,
|
94 |
-
|
95 |
)
|
|
|
|
|
|
|
|
|
96 |
df = leaderboard.fetch(private=lb == "private")
|
97 |
logger.info(df)
|
98 |
resp = {"response": df.to_markdown(index=False)}
|
@@ -108,7 +118,15 @@ async def my_submissions(request: Request, user: User):
|
|
108 |
token=HF_TOKEN,
|
109 |
competition_type=COMP_INFO.competition_type,
|
110 |
)
|
111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
112 |
subs = pd.concat([success_subs, failed_subs], axis=0)
|
113 |
subs = subs.to_markdown(index=False)
|
114 |
if len(subs.strip()) == 0:
|
@@ -140,10 +158,13 @@ async def new_submission(
|
|
140 |
token=HF_TOKEN,
|
141 |
competition_type=COMP_INFO.competition_type,
|
142 |
)
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
149 |
return {"response": "Invalid competition type"}
|
|
|
1 |
+
import datetime
|
2 |
import os
|
3 |
import threading
|
4 |
|
|
|
7 |
from fastapi.responses import HTMLResponse, JSONResponse
|
8 |
from fastapi.staticfiles import StaticFiles
|
9 |
from fastapi.templating import Jinja2Templates
|
10 |
+
from huggingface_hub.utils import disable_progress_bars
|
11 |
from loguru import logger
|
12 |
from pydantic import BaseModel
|
13 |
|
14 |
+
from competitions.errors import AuthenticationError
|
15 |
from competitions.info import CompetitionInfo
|
16 |
from competitions.leaderboard import Leaderboard
|
17 |
from competitions.runner import JobRunner
|
|
|
23 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
24 |
COMPETITION_ID = os.getenv("COMPETITION_ID")
|
25 |
OUTPUT_PATH = os.getenv("OUTPUT_PATH", "/tmp/model")
|
26 |
+
|
27 |
+
disable_progress_bars()
|
28 |
+
|
29 |
COMP_INFO = CompetitionInfo(competition_id=COMPETITION_ID, autotrain_token=HF_TOKEN)
|
30 |
|
31 |
|
|
|
97 |
eval_higher_is_better=COMP_INFO.eval_higher_is_better,
|
98 |
max_selected_submissions=COMP_INFO.selection_limit,
|
99 |
competition_id=COMPETITION_ID,
|
100 |
+
token=HF_TOKEN,
|
101 |
)
|
102 |
+
if lb == "private":
|
103 |
+
current_utc_time = datetime.datetime.utcnow()
|
104 |
+
if current_utc_time < COMP_INFO.end_date:
|
105 |
+
return {"response": "Private leaderboard will be available after the competition ends."}
|
106 |
df = leaderboard.fetch(private=lb == "private")
|
107 |
logger.info(df)
|
108 |
resp = {"response": df.to_markdown(index=False)}
|
|
|
118 |
token=HF_TOKEN,
|
119 |
competition_type=COMP_INFO.competition_type,
|
120 |
)
|
121 |
+
try:
|
122 |
+
success_subs, failed_subs = sub.my_submissions(user.user_token)
|
123 |
+
except AuthenticationError:
|
124 |
+
return {
|
125 |
+
"response": {
|
126 |
+
"submissions": "**Invalid token**",
|
127 |
+
"submission_text": SUBMISSION_TEXT.format(COMP_INFO.submission_limit),
|
128 |
+
}
|
129 |
+
}
|
130 |
subs = pd.concat([success_subs, failed_subs], axis=0)
|
131 |
subs = subs.to_markdown(index=False)
|
132 |
if len(subs.strip()) == 0:
|
|
|
158 |
token=HF_TOKEN,
|
159 |
competition_type=COMP_INFO.competition_type,
|
160 |
)
|
161 |
+
try:
|
162 |
+
if COMP_INFO.competition_type == "generic":
|
163 |
+
resp = sub.new_submission(token, submission_file, submission_comment)
|
164 |
+
return {"response": f"Success! You have {resp} submissions remaining today."}
|
165 |
+
elif COMP_INFO.competition_type == "code":
|
166 |
+
resp = sub.new_submission(token, hub_model, submission_comment)
|
167 |
+
return {"response": f"Success! You have {resp} submissions remaining today."}
|
168 |
+
except AuthenticationError:
|
169 |
+
return {"response": "Invalid token"}
|
170 |
return {"response": "Invalid competition type"}
|
competitions/evaluate.py
CHANGED
@@ -75,7 +75,6 @@ def generate_submission_file(params):
|
|
75 |
@utils.monitor
|
76 |
def run(params):
|
77 |
logger.info(params)
|
78 |
-
logger.info(f"User token: {os.environ.get('USER_TOKEN')}")
|
79 |
if isinstance(params, dict):
|
80 |
params = EvalParams(**params)
|
81 |
|
|
|
75 |
@utils.monitor
|
76 |
def run(params):
|
77 |
logger.info(params)
|
|
|
78 |
if isinstance(params, dict):
|
79 |
params = EvalParams(**params)
|
80 |
|
competitions/leaderboard.py
CHANGED
@@ -6,10 +6,9 @@ from dataclasses import dataclass
|
|
6 |
from datetime import datetime
|
7 |
|
8 |
import pandas as pd
|
|
|
9 |
from loguru import logger
|
10 |
|
11 |
-
from .download import snapshot_download
|
12 |
-
|
13 |
|
14 |
@dataclass
|
15 |
class Leaderboard:
|
@@ -17,7 +16,7 @@ class Leaderboard:
|
|
17 |
eval_higher_is_better: bool
|
18 |
max_selected_submissions: int
|
19 |
competition_id: str
|
20 |
-
|
21 |
|
22 |
def __post_init__(self):
|
23 |
self._refresh_columns()
|
@@ -42,7 +41,7 @@ class Leaderboard:
|
|
42 |
submissions_folder = snapshot_download(
|
43 |
repo_id=self.competition_id,
|
44 |
allow_patterns="submission_info/*.json",
|
45 |
-
use_auth_token=self.
|
46 |
repo_type="dataset",
|
47 |
)
|
48 |
logger.info(f"Downloaded submissions in {time.time() - start_time} seconds")
|
@@ -77,10 +76,7 @@ class Leaderboard:
|
|
77 |
_sub[f"public_score_{skey}"] = _sub["public_score"][skey]
|
78 |
_sub["public_score"] = _sub["public_score"][score_key]
|
79 |
|
80 |
-
submission_info["submissions"].sort(
|
81 |
-
key=lambda x: x["public_score"],
|
82 |
-
reverse=True if self.eval_higher_is_better else False,
|
83 |
-
)
|
84 |
# select only the best submission
|
85 |
submission_info["submissions"] = submission_info["submissions"][0]
|
86 |
temp_info = {
|
@@ -105,7 +101,7 @@ class Leaderboard:
|
|
105 |
submissions_folder = snapshot_download(
|
106 |
repo_id=self.competition_id,
|
107 |
allow_patterns="submission_info/*.json",
|
108 |
-
use_auth_token=self.
|
109 |
repo_type="dataset",
|
110 |
)
|
111 |
logger.info(f"Downloaded submissions in {time.time() - start_time} seconds")
|
@@ -253,4 +249,17 @@ class Leaderboard:
|
|
253 |
# send submission_datetime to the end
|
254 |
columns.remove("submission_datetime")
|
255 |
columns.append("submission_datetime")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
return df[columns]
|
|
|
6 |
from datetime import datetime
|
7 |
|
8 |
import pandas as pd
|
9 |
+
from huggingface_hub import hf_hub_download, snapshot_download
|
10 |
from loguru import logger
|
11 |
|
|
|
|
|
12 |
|
13 |
@dataclass
|
14 |
class Leaderboard:
|
|
|
16 |
eval_higher_is_better: bool
|
17 |
max_selected_submissions: int
|
18 |
competition_id: str
|
19 |
+
token: str
|
20 |
|
21 |
def __post_init__(self):
|
22 |
self._refresh_columns()
|
|
|
41 |
submissions_folder = snapshot_download(
|
42 |
repo_id=self.competition_id,
|
43 |
allow_patterns="submission_info/*.json",
|
44 |
+
use_auth_token=self.token,
|
45 |
repo_type="dataset",
|
46 |
)
|
47 |
logger.info(f"Downloaded submissions in {time.time() - start_time} seconds")
|
|
|
76 |
_sub[f"public_score_{skey}"] = _sub["public_score"][skey]
|
77 |
_sub["public_score"] = _sub["public_score"][score_key]
|
78 |
|
79 |
+
submission_info["submissions"].sort(key=lambda x: x["public_score"], reverse=self.eval_higher_is_better)
|
|
|
|
|
|
|
80 |
# select only the best submission
|
81 |
submission_info["submissions"] = submission_info["submissions"][0]
|
82 |
temp_info = {
|
|
|
101 |
submissions_folder = snapshot_download(
|
102 |
repo_id=self.competition_id,
|
103 |
allow_patterns="submission_info/*.json",
|
104 |
+
use_auth_token=self.token,
|
105 |
repo_type="dataset",
|
106 |
)
|
107 |
logger.info(f"Downloaded submissions in {time.time() - start_time} seconds")
|
|
|
249 |
# send submission_datetime to the end
|
250 |
columns.remove("submission_datetime")
|
251 |
columns.append("submission_datetime")
|
252 |
+
|
253 |
+
team_metadata = hf_hub_download(
|
254 |
+
repo_id=self.competition_id,
|
255 |
+
filename="teams.json",
|
256 |
+
token=self.token,
|
257 |
+
repo_type="dataset",
|
258 |
+
)
|
259 |
+
|
260 |
+
with open(team_metadata, "r", encoding="utf-8") as f:
|
261 |
+
team_metadata = json.load(f)
|
262 |
+
|
263 |
+
df["id"] = df["id"].apply(lambda x: team_metadata[x]["name"])
|
264 |
+
|
265 |
return df[columns]
|
competitions/runner.py
CHANGED
@@ -87,6 +87,7 @@ class JobRunner:
|
|
87 |
"submission_rows": self.submission_rows,
|
88 |
"output_path": self.output_path,
|
89 |
"submission_repo": row["submission_repo"],
|
|
|
90 |
}
|
91 |
eval_params = json.dumps(eval_params)
|
92 |
eval_pid = run_evaluation(eval_params, local=True, wait=True)
|
|
|
87 |
"submission_rows": self.submission_rows,
|
88 |
"output_path": self.output_path,
|
89 |
"submission_repo": row["submission_repo"],
|
90 |
+
"time_limit": self.time_limit,
|
91 |
}
|
92 |
eval_params = json.dumps(eval_params)
|
93 |
eval_pid = run_evaluation(eval_params, local=True, wait=True)
|
competitions/submissions.py
CHANGED
@@ -82,7 +82,7 @@ class Submissions:
|
|
82 |
with open(team_fname, "r", encoding="utf-8") as f:
|
83 |
team_submission_info = json.load(f)
|
84 |
|
85 |
-
todays_date = datetime.
|
86 |
if len(team_submission_info["submissions"]) == 0:
|
87 |
team_submission_info["submissions"] = []
|
88 |
|
@@ -120,7 +120,7 @@ class Submissions:
|
|
120 |
with open(team_fname, "r", encoding="utf-8") as f:
|
121 |
team_submission_info = json.load(f)
|
122 |
|
123 |
-
todays_date = datetime.
|
124 |
if len(team_submission_info["submissions"]) == 0:
|
125 |
team_submission_info["submissions"] = []
|
126 |
|
@@ -155,7 +155,7 @@ class Submissions:
|
|
155 |
)
|
156 |
with open(team_fname, "r", encoding="utf-8") as f:
|
157 |
team_submission_info = json.load(f)
|
158 |
-
datetime_now = datetime.
|
159 |
|
160 |
# here goes all the default stuff for submission
|
161 |
team_submission_info["submissions"].append(
|
@@ -175,7 +175,7 @@ class Submissions:
|
|
175 |
)
|
176 |
# count the number of times user has submitted today
|
177 |
todays_submissions = 0
|
178 |
-
todays_date = datetime.
|
179 |
for sub in team_submission_info["submissions"]:
|
180 |
submission_datetime = sub["datetime"]
|
181 |
submission_date = submission_datetime.split(" ")[0]
|
@@ -206,13 +206,12 @@ class Submissions:
|
|
206 |
return team_submission_info["submissions"]
|
207 |
|
208 |
def update_selected_submissions(self, user_token, selected_submission_ids):
|
209 |
-
current_datetime = datetime.
|
210 |
if current_datetime > self.end_date:
|
211 |
raise PastDeadlineError("Competition has ended.")
|
212 |
|
213 |
user_info = self._get_user_info(user_token)
|
214 |
-
|
215 |
-
team_id = self._get_team_id(user_id)
|
216 |
|
217 |
team_fname = hf_hub_download(
|
218 |
repo_id=self.competition_id,
|
@@ -326,15 +325,17 @@ class Submissions:
|
|
326 |
|
327 |
def my_submissions(self, user_token):
|
328 |
user_info = self._get_user_info(user_token)
|
329 |
-
current_date_time = datetime.
|
330 |
private = False
|
331 |
if current_date_time >= self.end_date:
|
332 |
private = True
|
333 |
-
team_id = self._get_team_id(user_info
|
334 |
success_subs, failed_subs = self._get_team_subs(team_id, private=private)
|
335 |
return success_subs, failed_subs
|
336 |
|
337 |
-
def _get_team_id(self,
|
|
|
|
|
338 |
user_team = hf_hub_download(
|
339 |
repo_id=self.competition_id,
|
340 |
filename="user_team.json",
|
@@ -347,12 +348,35 @@ class Submissions:
|
|
347 |
if user_id in user_team:
|
348 |
return user_team[user_id]
|
349 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
# create a new team, if user is not in any team
|
351 |
team_id = str(uuid.uuid4())
|
352 |
user_team[user_id] = team_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
user_team_json = json.dumps(user_team, indent=4)
|
354 |
user_team_json_bytes = user_team_json.encode("utf-8")
|
355 |
user_team_json_buffer = io.BytesIO(user_team_json_bytes)
|
|
|
|
|
|
|
|
|
|
|
356 |
api = HfApi(token=self.token)
|
357 |
api.upload_file(
|
358 |
path_or_fileobj=user_team_json_buffer,
|
@@ -360,6 +384,13 @@ class Submissions:
|
|
360 |
repo_id=self.competition_id,
|
361 |
repo_type="dataset",
|
362 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
return team_id
|
364 |
|
365 |
def new_submission(self, user_token, uploaded_file, submission_comment):
|
@@ -367,7 +398,7 @@ class Submissions:
|
|
367 |
user_info = self._get_user_info(user_token)
|
368 |
submission_id = str(uuid.uuid4())
|
369 |
user_id = user_info["id"]
|
370 |
-
team_id = self._get_team_id(
|
371 |
|
372 |
# check if team can submit to the competition
|
373 |
if self._check_team_submission_limit(team_id) is False:
|
|
|
82 |
with open(team_fname, "r", encoding="utf-8") as f:
|
83 |
team_submission_info = json.load(f)
|
84 |
|
85 |
+
todays_date = datetime.utcnow().strftime("%Y-%m-%d")
|
86 |
if len(team_submission_info["submissions"]) == 0:
|
87 |
team_submission_info["submissions"] = []
|
88 |
|
|
|
120 |
with open(team_fname, "r", encoding="utf-8") as f:
|
121 |
team_submission_info = json.load(f)
|
122 |
|
123 |
+
todays_date = datetime.utcnow().strftime("%Y-%m-%d")
|
124 |
if len(team_submission_info["submissions"]) == 0:
|
125 |
team_submission_info["submissions"] = []
|
126 |
|
|
|
155 |
)
|
156 |
with open(team_fname, "r", encoding="utf-8") as f:
|
157 |
team_submission_info = json.load(f)
|
158 |
+
datetime_now = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")
|
159 |
|
160 |
# here goes all the default stuff for submission
|
161 |
team_submission_info["submissions"].append(
|
|
|
175 |
)
|
176 |
# count the number of times user has submitted today
|
177 |
todays_submissions = 0
|
178 |
+
todays_date = datetime.utcnow().strftime("%Y-%m-%d")
|
179 |
for sub in team_submission_info["submissions"]:
|
180 |
submission_datetime = sub["datetime"]
|
181 |
submission_date = submission_datetime.split(" ")[0]
|
|
|
206 |
return team_submission_info["submissions"]
|
207 |
|
208 |
def update_selected_submissions(self, user_token, selected_submission_ids):
|
209 |
+
current_datetime = datetime.utcnow()
|
210 |
if current_datetime > self.end_date:
|
211 |
raise PastDeadlineError("Competition has ended.")
|
212 |
|
213 |
user_info = self._get_user_info(user_token)
|
214 |
+
team_id = self._get_team_id(user_info)
|
|
|
215 |
|
216 |
team_fname = hf_hub_download(
|
217 |
repo_id=self.competition_id,
|
|
|
325 |
|
326 |
def my_submissions(self, user_token):
|
327 |
user_info = self._get_user_info(user_token)
|
328 |
+
current_date_time = datetime.utcnow()
|
329 |
private = False
|
330 |
if current_date_time >= self.end_date:
|
331 |
private = True
|
332 |
+
team_id = self._get_team_id(user_info)
|
333 |
success_subs, failed_subs = self._get_team_subs(team_id, private=private)
|
334 |
return success_subs, failed_subs
|
335 |
|
336 |
+
def _get_team_id(self, user_info):
|
337 |
+
user_id = user_info["id"]
|
338 |
+
user_name = user_info["name"]
|
339 |
user_team = hf_hub_download(
|
340 |
repo_id=self.competition_id,
|
341 |
filename="user_team.json",
|
|
|
348 |
if user_id in user_team:
|
349 |
return user_team[user_id]
|
350 |
|
351 |
+
team_metadata = hf_hub_download(
|
352 |
+
repo_id=self.competition_id,
|
353 |
+
filename="teams.json",
|
354 |
+
token=self.token,
|
355 |
+
repo_type="dataset",
|
356 |
+
)
|
357 |
+
|
358 |
+
with open(team_metadata, "r", encoding="utf-8") as f:
|
359 |
+
team_metadata = json.load(f)
|
360 |
+
|
361 |
# create a new team, if user is not in any team
|
362 |
team_id = str(uuid.uuid4())
|
363 |
user_team[user_id] = team_id
|
364 |
+
|
365 |
+
team_metadata[team_id] = {
|
366 |
+
"id": team_id,
|
367 |
+
"name": user_name,
|
368 |
+
"members": [user_id],
|
369 |
+
"leader": user_id,
|
370 |
+
}
|
371 |
+
|
372 |
user_team_json = json.dumps(user_team, indent=4)
|
373 |
user_team_json_bytes = user_team_json.encode("utf-8")
|
374 |
user_team_json_buffer = io.BytesIO(user_team_json_bytes)
|
375 |
+
|
376 |
+
team_metadata_json = json.dumps(team_metadata, indent=4)
|
377 |
+
team_metadata_json_bytes = team_metadata_json.encode("utf-8")
|
378 |
+
team_metadata_json_buffer = io.BytesIO(team_metadata_json_bytes)
|
379 |
+
|
380 |
api = HfApi(token=self.token)
|
381 |
api.upload_file(
|
382 |
path_or_fileobj=user_team_json_buffer,
|
|
|
384 |
repo_id=self.competition_id,
|
385 |
repo_type="dataset",
|
386 |
)
|
387 |
+
api.upload_file(
|
388 |
+
path_or_fileobj=team_metadata_json_buffer,
|
389 |
+
path_in_repo="teams.json",
|
390 |
+
repo_id=self.competition_id,
|
391 |
+
repo_type="dataset",
|
392 |
+
)
|
393 |
+
|
394 |
return team_id
|
395 |
|
396 |
def new_submission(self, user_token, uploaded_file, submission_comment):
|
|
|
398 |
user_info = self._get_user_info(user_token)
|
399 |
submission_id = str(uuid.uuid4())
|
400 |
user_id = user_info["id"]
|
401 |
+
team_id = self._get_team_id(user_info)
|
402 |
|
403 |
# check if team can submit to the competition
|
404 |
if self._check_team_submission_limit(team_id) is False:
|
competitions/templates/index.html
CHANGED
@@ -23,6 +23,8 @@
|
|
23 |
}
|
24 |
|
25 |
function fetchAndDisplayCompetitionInfo() {
|
|
|
|
|
26 |
fetch('/competition_info')
|
27 |
.then(response => {
|
28 |
if (!response.ok) {
|
@@ -35,13 +37,17 @@
|
|
35 |
const contentDiv = document.getElementById('content');
|
36 |
contentDiv.style.display = 'block';
|
37 |
contentDiv.innerHTML = marked.parse(data.response);
|
|
|
38 |
})
|
39 |
.catch(error => {
|
40 |
console.error('There has been a problem with your fetch operation:', error);
|
|
|
41 |
});
|
42 |
}
|
43 |
|
44 |
function fetchAndDisplayDatasetInfo() {
|
|
|
|
|
45 |
fetch('/dataset_info')
|
46 |
.then(response => {
|
47 |
if (!response.ok) {
|
@@ -53,13 +59,17 @@
|
|
53 |
// Populate the 'content' div with the HTML from the response
|
54 |
const contentDiv = document.getElementById('content');
|
55 |
contentDiv.innerHTML = marked.parse(data.response);
|
|
|
56 |
})
|
57 |
.catch(error => {
|
58 |
console.error('There has been a problem with your fetch operation:', error);
|
|
|
59 |
});
|
60 |
}
|
61 |
|
62 |
function fetchAndDisplayPublicLeaderboard() {
|
|
|
|
|
63 |
fetch('/leaderboard/public')
|
64 |
.then(response => {
|
65 |
if (!response.ok) {
|
@@ -71,13 +81,17 @@
|
|
71 |
// Populate the 'content' div with the HTML from the response
|
72 |
const contentDiv = document.getElementById('content');
|
73 |
contentDiv.innerHTML = marked.parse(data.response);
|
|
|
74 |
})
|
75 |
.catch(error => {
|
76 |
console.error('There has been a problem with your fetch operation:', error);
|
|
|
77 |
});
|
78 |
}
|
79 |
|
80 |
function fetchAndDisplayPrivateLeaderboard() {
|
|
|
|
|
81 |
fetch('/leaderboard/private')
|
82 |
.then(response => {
|
83 |
if (!response.ok) {
|
@@ -89,14 +103,18 @@
|
|
89 |
// Populate the 'content' div with the HTML from the response
|
90 |
const contentDiv = document.getElementById('content');
|
91 |
contentDiv.innerHTML = marked.parse(data.response);
|
|
|
92 |
})
|
93 |
.catch(error => {
|
94 |
console.error('There has been a problem with your fetch operation:', error);
|
|
|
95 |
});
|
96 |
}
|
97 |
function fetchAndDisplaySubmissions() {
|
98 |
const userToken = document.getElementById('user_token').value;
|
99 |
const apiEndpoint = '/my_submissions';
|
|
|
|
|
100 |
|
101 |
const requestOptions = {
|
102 |
method: 'POST',
|
@@ -116,13 +134,17 @@
|
|
116 |
.then(data => {
|
117 |
const contentDiv = document.getElementById('content');
|
118 |
contentDiv.innerHTML = marked.parse(data.response.submission_text) + marked.parse(data.response.submissions);
|
|
|
119 |
})
|
120 |
.catch(error => {
|
121 |
console.error('There was a problem with the fetch operation:', error);
|
|
|
122 |
});
|
123 |
}
|
124 |
|
125 |
function fetchAndDisplaySubmissionInfo() {
|
|
|
|
|
126 |
fetch('/submission_info')
|
127 |
.then(response => {
|
128 |
if (!response.ok) {
|
@@ -134,9 +156,11 @@
|
|
134 |
// Populate the 'content' div with the HTML from the response
|
135 |
const contentDiv = document.getElementById('content');
|
136 |
contentDiv.innerHTML = marked.parse(data.response);
|
|
|
137 |
})
|
138 |
.catch(error => {
|
139 |
console.error('There has been a problem with your fetch operation:', error);
|
|
|
140 |
});
|
141 |
}
|
142 |
|
@@ -194,17 +218,17 @@
|
|
194 |
</script>
|
195 |
</head>
|
196 |
|
197 |
-
<body class="flex h-screen
|
198 |
<!-- Sidebar -->
|
199 |
<aside id="sidebar-multi-level-sidebar"
|
200 |
class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0"
|
201 |
aria-label="Sidebar">
|
202 |
-
<div class="h-full px-3 py-4 overflow-y-auto
|
203 |
<ul class="space-y-2 font-medium">
|
204 |
<li>
|
205 |
<a href="#" id="home"
|
206 |
-
class="flex items-center p-2 text-gray-900 rounded-lg
|
207 |
-
<svg class="w-5 h-5 text-gray-500 transition duration-75
|
208 |
viewBox="0 0 22 21" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
209 |
<path d="M1,10 L11,1 L21,10 L21,20 L1,20 Z" /> <!-- House structure -->
|
210 |
<path d="M6,20 L6,14 L16,14 L16,20" /> <!-- Door -->
|
@@ -215,8 +239,8 @@
|
|
215 |
</li>
|
216 |
<li>
|
217 |
<a href="#" id="dataset"
|
218 |
-
class="flex items-center p-2 text-gray-900 rounded-lg
|
219 |
-
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75
|
220 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
221 |
viewBox="0 0 18 18">
|
222 |
<path
|
@@ -227,9 +251,9 @@
|
|
227 |
</li>
|
228 |
<li>
|
229 |
<button type="button"
|
230 |
-
class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100
|
231 |
aria-controls="lb-dropdown" data-collapse-toggle="lb-dropdown">
|
232 |
-
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900
|
233 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
234 |
viewBox="0 0 18 21">
|
235 |
<path d="M2,4 L20,4 L20,16 L2,16 Z" />
|
@@ -242,22 +266,22 @@
|
|
242 |
d="m1 1 4 4 4-4" />
|
243 |
</svg>
|
244 |
</button>
|
245 |
-
<ul id="lb-dropdown" class="
|
246 |
<li>
|
247 |
<a href="#" id="public_lb"
|
248 |
-
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100
|
249 |
</li>
|
250 |
<li>
|
251 |
<a href="#" id="private_lb"
|
252 |
-
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100
|
253 |
</li>
|
254 |
</ul>
|
255 |
</li>
|
256 |
<li>
|
257 |
<button type="button"
|
258 |
-
class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100
|
259 |
aria-controls="submissions-dropdown" data-collapse-toggle="submissions-dropdown">
|
260 |
-
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75
|
261 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
262 |
viewBox="0 0 20 20">
|
263 |
<path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.96 2.96 0 0 0 .13 5H5Z" />
|
@@ -273,28 +297,28 @@
|
|
273 |
d="m1 1 4 4 4-4" />
|
274 |
</svg>
|
275 |
</button>
|
276 |
-
<ul id="submissions-dropdown" class="
|
277 |
<li>
|
278 |
<a href="#" id="submission_info"
|
279 |
-
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100
|
280 |
information</a>
|
281 |
</li>
|
282 |
<li>
|
283 |
<a href="#" id="my_submissions"
|
284 |
-
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100
|
285 |
submissions</a>
|
286 |
</li>
|
287 |
<li>
|
288 |
<a href="#" id="new_submission"
|
289 |
-
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100
|
290 |
submission</a>
|
291 |
</li>
|
292 |
</ul>
|
293 |
</li>
|
294 |
-
<li>
|
295 |
<a href="#"
|
296 |
-
class="flex items-center p-2 text-gray-900 rounded-lg
|
297 |
-
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75
|
298 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
299 |
viewBox="0 0 20 18">
|
300 |
<path
|
@@ -302,20 +326,34 @@
|
|
302 |
</svg>
|
303 |
<span class="flex-1 ms-3 whitespace-nowrap">Team</span>
|
304 |
</a>
|
305 |
-
</li>
|
306 |
<li>
|
307 |
-
<label for="user_token" class="text-xs font-medium
|
308 |
</label>
|
309 |
<input type="password" name="user_token" id="user_token"
|
310 |
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">
|
311 |
</li>
|
312 |
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
</div>
|
314 |
</aside>
|
315 |
<div class="p-1 sm:ml-64">
|
316 |
-
<img src={{logo}} alt="Competition logo"
|
317 |
<hr class="mt-3 mb-2">
|
318 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
</article>
|
320 |
</div>
|
321 |
<div id="submission-modal" tabindex="-1"
|
@@ -330,8 +368,7 @@
|
|
330 |
<form action="#" method="post" class="gap-2" enctype="multipart/form-data">
|
331 |
{% if competition_type == 'generic' %}
|
332 |
<div class="form-group">
|
333 |
-
<label class="block mb-2 text-sm font-medium text-gray-900
|
334 |
-
for="submission_file">Upload
|
335 |
file</label>
|
336 |
<input
|
337 |
class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none "
|
|
|
23 |
}
|
24 |
|
25 |
function fetchAndDisplayCompetitionInfo() {
|
26 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
27 |
+
articleLoadingSpinner.classList.remove('hidden');
|
28 |
fetch('/competition_info')
|
29 |
.then(response => {
|
30 |
if (!response.ok) {
|
|
|
37 |
const contentDiv = document.getElementById('content');
|
38 |
contentDiv.style.display = 'block';
|
39 |
contentDiv.innerHTML = marked.parse(data.response);
|
40 |
+
articleLoadingSpinner.classList.add('hidden');
|
41 |
})
|
42 |
.catch(error => {
|
43 |
console.error('There has been a problem with your fetch operation:', error);
|
44 |
+
articleLoadingSpinner.classList.add('hidden');
|
45 |
});
|
46 |
}
|
47 |
|
48 |
function fetchAndDisplayDatasetInfo() {
|
49 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
50 |
+
articleLoadingSpinner.classList.remove('hidden');
|
51 |
fetch('/dataset_info')
|
52 |
.then(response => {
|
53 |
if (!response.ok) {
|
|
|
59 |
// Populate the 'content' div with the HTML from the response
|
60 |
const contentDiv = document.getElementById('content');
|
61 |
contentDiv.innerHTML = marked.parse(data.response);
|
62 |
+
articleLoadingSpinner.classList.add('hidden');
|
63 |
})
|
64 |
.catch(error => {
|
65 |
console.error('There has been a problem with your fetch operation:', error);
|
66 |
+
articleLoadingSpinner.classList.add('hidden');
|
67 |
});
|
68 |
}
|
69 |
|
70 |
function fetchAndDisplayPublicLeaderboard() {
|
71 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
72 |
+
articleLoadingSpinner.classList.remove('hidden');
|
73 |
fetch('/leaderboard/public')
|
74 |
.then(response => {
|
75 |
if (!response.ok) {
|
|
|
81 |
// Populate the 'content' div with the HTML from the response
|
82 |
const contentDiv = document.getElementById('content');
|
83 |
contentDiv.innerHTML = marked.parse(data.response);
|
84 |
+
articleLoadingSpinner.classList.add('hidden');
|
85 |
})
|
86 |
.catch(error => {
|
87 |
console.error('There has been a problem with your fetch operation:', error);
|
88 |
+
articleLoadingSpinner.classList.add('hidden');
|
89 |
});
|
90 |
}
|
91 |
|
92 |
function fetchAndDisplayPrivateLeaderboard() {
|
93 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
94 |
+
articleLoadingSpinner.classList.remove('hidden');
|
95 |
fetch('/leaderboard/private')
|
96 |
.then(response => {
|
97 |
if (!response.ok) {
|
|
|
103 |
// Populate the 'content' div with the HTML from the response
|
104 |
const contentDiv = document.getElementById('content');
|
105 |
contentDiv.innerHTML = marked.parse(data.response);
|
106 |
+
articleLoadingSpinner.classList.add('hidden');
|
107 |
})
|
108 |
.catch(error => {
|
109 |
console.error('There has been a problem with your fetch operation:', error);
|
110 |
+
articleLoadingSpinner.classList.add('hidden');
|
111 |
});
|
112 |
}
|
113 |
function fetchAndDisplaySubmissions() {
|
114 |
const userToken = document.getElementById('user_token').value;
|
115 |
const apiEndpoint = '/my_submissions';
|
116 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
117 |
+
articleLoadingSpinner.classList.remove('hidden');
|
118 |
|
119 |
const requestOptions = {
|
120 |
method: 'POST',
|
|
|
134 |
.then(data => {
|
135 |
const contentDiv = document.getElementById('content');
|
136 |
contentDiv.innerHTML = marked.parse(data.response.submission_text) + marked.parse(data.response.submissions);
|
137 |
+
articleLoadingSpinner.classList.add('hidden');
|
138 |
})
|
139 |
.catch(error => {
|
140 |
console.error('There was a problem with the fetch operation:', error);
|
141 |
+
articleLoadingSpinner.classList.add('hidden');
|
142 |
});
|
143 |
}
|
144 |
|
145 |
function fetchAndDisplaySubmissionInfo() {
|
146 |
+
const articleLoadingSpinner = document.getElementById('articleLoadingSpinner');
|
147 |
+
articleLoadingSpinner.classList.remove('hidden');
|
148 |
fetch('/submission_info')
|
149 |
.then(response => {
|
150 |
if (!response.ok) {
|
|
|
156 |
// Populate the 'content' div with the HTML from the response
|
157 |
const contentDiv = document.getElementById('content');
|
158 |
contentDiv.innerHTML = marked.parse(data.response);
|
159 |
+
articleLoadingSpinner.classList.add('hidden');
|
160 |
})
|
161 |
.catch(error => {
|
162 |
console.error('There has been a problem with your fetch operation:', error);
|
163 |
+
articleLoadingSpinner.classList.add('hidden');
|
164 |
});
|
165 |
}
|
166 |
|
|
|
218 |
</script>
|
219 |
</head>
|
220 |
|
221 |
+
<body class="flex h-screen">
|
222 |
<!-- Sidebar -->
|
223 |
<aside id="sidebar-multi-level-sidebar"
|
224 |
class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0"
|
225 |
aria-label="Sidebar">
|
226 |
+
<div class="h-full px-3 py-4 overflow-y-auto">
|
227 |
<ul class="space-y-2 font-medium">
|
228 |
<li>
|
229 |
<a href="#" id="home"
|
230 |
+
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group">
|
231 |
+
<svg class="w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900"
|
232 |
viewBox="0 0 22 21" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
233 |
<path d="M1,10 L11,1 L21,10 L21,20 L1,20 Z" /> <!-- House structure -->
|
234 |
<path d="M6,20 L6,14 L16,14 L16,20" /> <!-- Door -->
|
|
|
239 |
</li>
|
240 |
<li>
|
241 |
<a href="#" id="dataset"
|
242 |
+
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100 group">
|
243 |
+
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900"
|
244 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
245 |
viewBox="0 0 18 18">
|
246 |
<path
|
|
|
251 |
</li>
|
252 |
<li>
|
253 |
<button type="button"
|
254 |
+
class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100"
|
255 |
aria-controls="lb-dropdown" data-collapse-toggle="lb-dropdown">
|
256 |
+
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900"
|
257 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
258 |
viewBox="0 0 18 21">
|
259 |
<path d="M2,4 L20,4 L20,16 L2,16 Z" />
|
|
|
266 |
d="m1 1 4 4 4-4" />
|
267 |
</svg>
|
268 |
</button>
|
269 |
+
<ul id="lb-dropdown" class="py-2 space-y-2">
|
270 |
<li>
|
271 |
<a href="#" id="public_lb"
|
272 |
+
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100">Public</a>
|
273 |
</li>
|
274 |
<li>
|
275 |
<a href="#" id="private_lb"
|
276 |
+
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100">Private</a>
|
277 |
</li>
|
278 |
</ul>
|
279 |
</li>
|
280 |
<li>
|
281 |
<button type="button"
|
282 |
+
class="flex items-center w-full p-2 text-base text-gray-900 transition duration-75 rounded-lg group hover:bg-gray-100"
|
283 |
aria-controls="submissions-dropdown" data-collapse-toggle="submissions-dropdown">
|
284 |
+
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900"
|
285 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
286 |
viewBox="0 0 20 20">
|
287 |
<path d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.96 2.96 0 0 0 .13 5H5Z" />
|
|
|
297 |
d="m1 1 4 4 4-4" />
|
298 |
</svg>
|
299 |
</button>
|
300 |
+
<ul id="submissions-dropdown" class="py-2 space-y-2">
|
301 |
<li>
|
302 |
<a href="#" id="submission_info"
|
303 |
+
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100">Submission
|
304 |
information</a>
|
305 |
</li>
|
306 |
<li>
|
307 |
<a href="#" id="my_submissions"
|
308 |
+
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100">My
|
309 |
submissions</a>
|
310 |
</li>
|
311 |
<li>
|
312 |
<a href="#" id="new_submission"
|
313 |
+
class="flex items-center w-full p-2 text-gray-900 transition duration-75 rounded-lg pl-11 group hover:bg-gray-100">New
|
314 |
submission</a>
|
315 |
</li>
|
316 |
</ul>
|
317 |
</li>
|
318 |
+
<!-- <li>
|
319 |
<a href="#"
|
320 |
+
class="flex items-center p-2 text-gray-900 rounded-lg hover:bg-gray-100">
|
321 |
+
<svg class="flex-shrink-0 w-5 h-5 text-gray-500 transition duration-75 group-hover:text-gray-900"
|
322 |
aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor"
|
323 |
viewBox="0 0 20 18">
|
324 |
<path
|
|
|
326 |
</svg>
|
327 |
<span class="flex-1 ms-3 whitespace-nowrap">Team</span>
|
328 |
</a>
|
329 |
+
</li> -->
|
330 |
<li>
|
331 |
+
<label for="user_token" class="text-xs font-medium">Hugging Face Token (read-only)
|
332 |
</label>
|
333 |
<input type="password" name="user_token" id="user_token"
|
334 |
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">
|
335 |
</li>
|
336 |
</ul>
|
337 |
+
<footer>
|
338 |
+
<div class="w-full mx-auto max-w-screen-xl p-4 md:flex md:items-center md:justify-between">
|
339 |
+
<span class="text-sm text-gray-500 sm:text-center">Powered by <a
|
340 |
+
href="https://github.com/huggingface/competitions" class="hover:underline">Hugging Face
|
341 |
+
Competitions</a>
|
342 |
+
</span>
|
343 |
+
</div>
|
344 |
+
</footer>
|
345 |
</div>
|
346 |
</aside>
|
347 |
<div class="p-1 sm:ml-64">
|
348 |
+
<img src={{logo}} alt="Competition logo">
|
349 |
<hr class="mt-3 mb-2">
|
350 |
+
<div id="articleLoadingSpinner" role="status"
|
351 |
+
class="hidden absolute -translate-x-1/2 -translate-y-1/2 top-2/4 left-1/2">
|
352 |
+
<div class="animate-spin rounded-full h-32 w-32 border-b-2 border-gray-900"></div>
|
353 |
+
<span class="sr-only">Loading...</span>
|
354 |
+
</div>
|
355 |
+
<article class="prose w-full mx-auto max-w-screen-xl p-4 md:flex md:items-center md:justify-between"
|
356 |
+
id="content">
|
357 |
</article>
|
358 |
</div>
|
359 |
<div id="submission-modal" tabindex="-1"
|
|
|
368 |
<form action="#" method="post" class="gap-2" enctype="multipart/form-data">
|
369 |
{% if competition_type == 'generic' %}
|
370 |
<div class="form-group">
|
371 |
+
<label class="block mb-2 text-sm font-medium text-gray-900" for="submission_file">Upload
|
|
|
372 |
file</label>
|
373 |
<input
|
374 |
class="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 focus:outline-none "
|
competitions/utils.py
CHANGED
@@ -65,9 +65,10 @@ def run_evaluation(params, local=False, wait=False):
|
|
65 |
|
66 |
def pause_space(params):
|
67 |
if "SPACE_ID" in os.environ:
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
71 |
|
72 |
|
73 |
def download_submission_info(params):
|
|
|
65 |
|
66 |
def pause_space(params):
|
67 |
if "SPACE_ID" in os.environ:
|
68 |
+
if os.environ["SPACE_ID"].split("/")[-1].startswith("comp-"):
|
69 |
+
logger.info("Pausing space...")
|
70 |
+
api = HfApi(token=params.token)
|
71 |
+
api.pause_space(repo_id=os.environ["SPACE_ID"])
|
72 |
|
73 |
|
74 |
def download_submission_info(params):
|