Abhishek Thakur commited on
Commit
62f77e4
·
1 Parent(s): 486015d

update docs

Browse files
README.md CHANGED
@@ -26,4 +26,4 @@ You can choose to make your competition public or private. Public competitions a
26
 
27
  ## How to create a competition?
28
 
29
- Coming very soon! Till then star and watch this repo to stay updated.
 
26
 
27
  ## How to create a competition?
28
 
29
+ Please read the [docs](https://huggingface.co/docs/competitions) to learn how to create a competition.
competitions/cli/create.py CHANGED
@@ -1,9 +1,72 @@
 
 
1
  from argparse import ArgumentParser
2
 
3
- from . import BaseCompetitionsCommand
4
  import click
 
5
  from loguru import logger
6
- from huggingface_hub import HfApi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
 
9
  def create_command_factory(args):
@@ -16,6 +79,19 @@ class CreateCompetitionAppCommand(BaseCompetitionsCommand):
16
  create_project_parser = parser.add_parser("create", description="✨ Create a new competition")
17
  create_project_parser.set_defaults(func=create_command_factory)
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def run(self):
20
  competition_name_text = "Competition name. Must be unqiue and contain only letters, numbers & hypens."
21
  competition_name = click.prompt(competition_name_text, type=str)
@@ -35,13 +111,9 @@ class CreateCompetitionAppCommand(BaseCompetitionsCommand):
35
  competition_name = competition_name.replace("~", "-")
36
  competition_name = competition_name.replace("@", "-")
37
  competition_name = competition_name.replace("#", "-")
38
- logger.info(f"Creating competition: {competition_name}")
39
 
40
- org_choices = HfApi().organization_list()
41
- competition_org_text = "Competition organization. Choose one of {org_choices}"
42
  competition_org = click.prompt(competition_org_text, type=str)
43
- if competition_org not in org_choices:
44
- raise ValueError(f"Organization {competition_org} not found in {org_choices}")
45
 
46
  competition_type_text = "Competition type. Choose one of 'generic', 'script'"
47
  competition_type = click.prompt(competition_type_text, type=str)
@@ -51,6 +123,141 @@ class CreateCompetitionAppCommand(BaseCompetitionsCommand):
51
  time_limit = click.prompt("Time limit in seconds", type=int)
52
  else:
53
  time_limit = 10
54
-
55
- hardware_choices = ["cpu-free", "gpu-free", "tpu-free"]
56
- hardware_text = "Hardware. Choose one of {hardware_choices}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import json
3
  from argparse import ArgumentParser
4
 
 
5
  import click
6
+ from huggingface_hub import HfApi, get_token
7
  from loguru import logger
8
+ from sklearn.metrics import get_scorer_names
9
+
10
+ from . import BaseCompetitionsCommand
11
+
12
+
13
+ COMPETITION_DESC = """Sample competition description"""
14
+ DATASET_DESC = """Sample dataset description"""
15
+ SUBMISSION_DESC = """Sample submission description"""
16
+ SOLUTION_CSV = """
17
+ id,pred,split
18
+ 0,1,public
19
+ 1,0,private
20
+ 2,0,private
21
+ 3,1,private
22
+ 4,0,public
23
+ 5,1,private
24
+ 6,1,public
25
+ 7,1,private
26
+ 8,0,public
27
+ 9,0,private
28
+ 10,0,private
29
+ 11,0,private
30
+ 12,1,private
31
+ 13,0,private
32
+ 14,1,public
33
+ 15,1,private
34
+ 16,1,private
35
+ 17,0,private
36
+ 18,0,private
37
+ 19,0,public
38
+ 20,0,private
39
+ 21,0,private
40
+ 22,1,private
41
+ 23,1,public
42
+ 24,0,private
43
+ 25,0,private
44
+ 26,0,public
45
+ 27,1,private
46
+ 28,1,private
47
+ 29,0,private
48
+ 30,0,public
49
+ """
50
+ SOLUTION_CSV = SOLUTION_CSV.strip()
51
+
52
+ DOCKERFILE = """
53
+ FROM huggingface/competitions:latest
54
+
55
+ CMD uvicorn competitions.app:app --host 0.0.0.0 --port 7860 --workers 1
56
+ """
57
+ DOCKERFILE = DOCKERFILE.replace("\n", " ").replace(" ", "\n").strip()
58
+
59
+ README = """
60
+ ---
61
+ title: My Competition
62
+ emoji: 🤗
63
+ colorFrom: indigo
64
+ colorTo: gray
65
+ sdk: docker
66
+ pinned: false
67
+ ---
68
+ """
69
+ README = README.strip()
70
 
71
 
72
  def create_command_factory(args):
 
79
  create_project_parser = parser.add_parser("create", description="✨ Create a new competition")
80
  create_project_parser.set_defaults(func=create_command_factory)
81
 
82
+ def _create_readme(self, competition_name):
83
+ _readme = "---\n"
84
+ _readme += f"title: {competition_name}\n"
85
+ _readme += "emoji: 🚀\n"
86
+ _readme += "colorFrom: green\n"
87
+ _readme += "colorTo: indigo\n"
88
+ _readme += "sdk: docker\n"
89
+ _readme += "pinned: false\n"
90
+ _readme += "duplicated_from: autotrain-projects/autotrain-advanced\n"
91
+ _readme += "---\n"
92
+ _readme = io.BytesIO(_readme.encode())
93
+ return _readme
94
+
95
  def run(self):
96
  competition_name_text = "Competition name. Must be unqiue and contain only letters, numbers & hypens."
97
  competition_name = click.prompt(competition_name_text, type=str)
 
111
  competition_name = competition_name.replace("~", "-")
112
  competition_name = competition_name.replace("@", "-")
113
  competition_name = competition_name.replace("#", "-")
 
114
 
115
+ competition_org_text = "Competition organization. Choose one of the organizations you are a part of."
 
116
  competition_org = click.prompt(competition_org_text, type=str)
 
 
117
 
118
  competition_type_text = "Competition type. Choose one of 'generic', 'script'"
119
  competition_type = click.prompt(competition_type_text, type=str)
 
123
  time_limit = click.prompt("Time limit in seconds", type=int)
124
  else:
125
  time_limit = 10
126
+
127
+ hardware_choices = [
128
+ "cpu-basic",
129
+ "cpu-upgrade",
130
+ "t4-small",
131
+ "t4-medium",
132
+ "zero-a10g",
133
+ "a10g-small",
134
+ "a10g-large",
135
+ "a10g-largex2",
136
+ "a10g-largex4",
137
+ "a100-large",
138
+ ]
139
+ hardware_text = f"Hardware. Choose one of {hardware_choices}"
140
+ hardware = click.prompt(hardware_text, type=str)
141
+ if hardware not in hardware_choices:
142
+ raise ValueError(f"Hardware {hardware} not found in {hardware_choices}")
143
+
144
+ metric_choices = get_scorer_names()
145
+ metric_text = f"Metric. Choose one of {metric_choices}"
146
+ metric = click.prompt(metric_text, type=str)
147
+ if metric not in metric_choices:
148
+ raise ValueError(f"Metric {metric} not found in {metric_choices}")
149
+
150
+ eval_higher_text = "Is higher metric better? Enter 1, if yes"
151
+ eval_higher = click.prompt(eval_higher_text, type=int)
152
+ if eval_higher not in [0, 1]:
153
+ raise ValueError("Invalid value for eval_higher. Must be 0 or 1")
154
+
155
+ submission_limit_text = "Daily submission limit"
156
+ submission_limit = click.prompt(submission_limit_text, type=int)
157
+ if submission_limit < 1:
158
+ raise ValueError("Submission limit must be positive integer, greater than 0")
159
+
160
+ end_date_text = "End date. Format: YYYY-MM-DD. Private leaderboard will be available on this date."
161
+ end_date = click.prompt(end_date_text, type=str)
162
+
163
+ submission_id_col_text = "Submission ID column name. This column will be used to identify submissions."
164
+ submission_id_col = click.prompt(submission_id_col_text, type=str)
165
+
166
+ submission_cols_text = "Submission columns. Enter comma separated column names, including id column."
167
+ submission_cols = click.prompt(submission_cols_text, type=str)
168
+
169
+ submission_rows_text = "Submission rows. How many rows are allowed in a submission, exluding header?"
170
+ submission_rows = click.prompt(submission_rows_text, type=int)
171
+
172
+ competition_logo_text = "Competition logo. Enter URL to logo."
173
+ competition_logo = click.prompt(competition_logo_text, type=str)
174
+
175
+ conf_json = {
176
+ "COMPETITION_TYPE": competition_type,
177
+ "SUBMISSION_LIMIT": submission_limit,
178
+ "TIME_LIMIT": time_limit,
179
+ "SELECTION_LIMIT": 2,
180
+ "END_DATE": end_date,
181
+ "EVAL_HIGHER_IS_BETTER": eval_higher,
182
+ "SUBMISSION_ID_COLUMN": submission_id_col,
183
+ "SUBMISSION_COLUMNS": submission_cols,
184
+ "SUBMISSION_ROWS": submission_rows,
185
+ "EVAL_METRIC": metric,
186
+ "LOGO": competition_logo,
187
+ }
188
+
189
+ teams_json = {}
190
+ user_team_json = {}
191
+
192
+ logger.info(f"Creating competition: {competition_name}")
193
+
194
+ api = HfApi()
195
+ api.create_repo(
196
+ repo_id=f"{competition_org}/{competition_name}",
197
+ repo_type="dataset",
198
+ private=True,
199
+ )
200
+
201
+ conf_json = json.dumps(conf_json, indent=4)
202
+ conf_json_bytes = conf_json.encode("utf-8")
203
+ conf_json_buffer = io.BytesIO(conf_json_bytes)
204
+ api.upload_file(
205
+ path_or_fileobj=conf_json_buffer,
206
+ path_in_repo="conf.json",
207
+ repo_id=f"{competition_org}/{competition_name}",
208
+ repo_type="dataset",
209
+ )
210
+
211
+ teams_json = json.dumps(teams_json, indent=4)
212
+ teams_json_bytes = teams_json.encode("utf-8")
213
+ teams_json_buffer = io.BytesIO(teams_json_bytes)
214
+ api.upload_file(
215
+ path_or_fileobj=teams_json_buffer,
216
+ path_in_repo="teams.json",
217
+ repo_id=f"{competition_org}/{competition_name}",
218
+ repo_type="dataset",
219
+ )
220
+
221
+ user_team_json = json.dumps(user_team_json, indent=4)
222
+ user_team_json_bytes = user_team_json.encode("utf-8")
223
+ user_team_json_buffer = io.BytesIO(user_team_json_bytes)
224
+ api.upload_file(
225
+ path_or_fileobj=user_team_json_buffer,
226
+ path_in_repo="user_team.json",
227
+ repo_id=f"{competition_org}/{competition_name}",
228
+ repo_type="dataset",
229
+ )
230
+
231
+ # create competition space
232
+ api.create_repo(
233
+ repo_id=f"{competition_org}/{competition_name}",
234
+ repo_type="space",
235
+ space_sdk="docker",
236
+ space_hardware="cpu-basic" if competition_type == "generic" else hardware,
237
+ private=True,
238
+ )
239
+ api.add_space_secret(repo_id=f"{competition_org}/{competition_name}", key="HF_TOKEN", value=get_token())
240
+ api.add_space_secret(
241
+ repo_id=f"{competition_org}/{competition_name}",
242
+ key="COMPETITION_ID",
243
+ value=f"{competition_org}/{competition_name}",
244
+ )
245
+ readme = self._create_readme(competition_name)
246
+ api.upload_file(
247
+ path_or_fileobj=readme,
248
+ path_in_repo="README.md",
249
+ repo_id=f"{competition_org}/{competition_name}",
250
+ repo_type="space",
251
+ )
252
+
253
+ _dockerfile = io.BytesIO(DOCKERFILE.encode())
254
+ api.upload_file(
255
+ path_or_fileobj=_dockerfile,
256
+ path_in_repo="Dockerfile",
257
+ repo_id=f"{competition_org}/{competition_name}",
258
+ repo_type="space",
259
+ )
260
+
261
+ logger.info(
262
+ "Created private dataset and competition space. To make competition public, you should make the space private. Please note that the dataset should always be kept private."
263
+ )
competitions/submissions.py CHANGED
@@ -453,7 +453,7 @@ class Submissions:
453
  repo_id=space_id,
454
  repo_type="space",
455
  space_sdk="docker",
456
- space_hardware="cpu-basic",
457
  private=True,
458
  )
459
 
 
453
  repo_id=space_id,
454
  repo_type="space",
455
  space_sdk="docker",
456
+ space_hardware=self.hardware,
457
  private=True,
458
  )
459
 
docs/source/getting_started.mdx CHANGED
@@ -13,3 +13,7 @@ competitions create
13
  ```
14
 
15
  Then follow the prompts.
 
 
 
 
 
13
  ```
14
 
15
  Then follow the prompts.
16
+
17
+ To report a bug or request a feature, please open an [issue](https://github.com/huggingface/competitions/issues)
18
+
19
+ If you want to organize a competition on hf.co/competitions, please contact us at: [email protected]