hysts HF staff commited on
Commit
85576c8
1 Parent(s): 27e829e

Migrate from yapf to black

Browse files
.pre-commit-config.yaml CHANGED
@@ -1,6 +1,6 @@
1
  repos:
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
- rev: v4.2.0
4
  hooks:
5
  - id: check-executables-have-shebangs
6
  - id: check-json
@@ -8,14 +8,13 @@ repos:
8
  - id: check-shebang-scripts-are-executable
9
  - id: check-toml
10
  - id: check-yaml
11
- - id: double-quote-string-fixer
12
  - id: end-of-file-fixer
13
  - id: mixed-line-ending
14
  args: ['--fix=lf']
15
  - id: requirements-txt-fixer
16
  - id: trailing-whitespace
17
  - repo: https://github.com/myint/docformatter
18
- rev: v1.4
19
  hooks:
20
  - id: docformatter
21
  args: ['--in-place']
@@ -23,14 +22,29 @@ repos:
23
  rev: 5.12.0
24
  hooks:
25
  - id: isort
 
26
  - repo: https://github.com/pre-commit/mirrors-mypy
27
- rev: v0.991
28
  hooks:
29
  - id: mypy
30
  args: ['--ignore-missing-imports']
31
- additional_dependencies: ['types-python-slugify', 'types-PyYAML']
32
- - repo: https://github.com/google/yapf
33
- rev: v0.32.0
34
  hooks:
35
- - id: yapf
36
- args: ['--parallel', '--in-place']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  repos:
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.4.0
4
  hooks:
5
  - id: check-executables-have-shebangs
6
  - id: check-json
 
8
  - id: check-shebang-scripts-are-executable
9
  - id: check-toml
10
  - id: check-yaml
 
11
  - id: end-of-file-fixer
12
  - id: mixed-line-ending
13
  args: ['--fix=lf']
14
  - id: requirements-txt-fixer
15
  - id: trailing-whitespace
16
  - repo: https://github.com/myint/docformatter
17
+ rev: v1.7.5
18
  hooks:
19
  - id: docformatter
20
  args: ['--in-place']
 
22
  rev: 5.12.0
23
  hooks:
24
  - id: isort
25
+ args: ["--profile=black"]
26
  - repo: https://github.com/pre-commit/mirrors-mypy
27
+ rev: v1.5.1
28
  hooks:
29
  - id: mypy
30
  args: ['--ignore-missing-imports']
31
+ additional_dependencies: ['types-python-slugify', 'types-requests', 'types-PyYAML']
32
+ - repo: https://github.com/psf/black
33
+ rev: 23.7.0
34
  hooks:
35
+ - id: black
36
+ language_version: python3.10
37
+ args: ['--line-length=119']
38
+ - repo: https://github.com/kynan/nbstripout
39
+ rev: 0.6.1
40
+ hooks:
41
+ - id: nbstripout
42
+ args: ['--extra-keys', 'metadata.interpreter metadata.kernelspec cell.metadata.pycharm']
43
+ - repo: https://github.com/nbQA-dev/nbQA
44
+ rev: 1.7.0
45
+ hooks:
46
+ - id: nbqa-black
47
+ - id: nbqa-pyupgrade
48
+ args: ["--py37-plus"]
49
+ - id: nbqa-isort
50
+ args: ["--float-to-top"]
.vscode/settings.json CHANGED
@@ -1,18 +1,21 @@
1
  {
2
- "python.linting.enabled": true,
3
- "python.linting.flake8Enabled": true,
4
- "python.linting.pylintEnabled": false,
5
- "python.linting.lintOnSave": true,
6
- "python.formatting.provider": "yapf",
7
- "python.formatting.yapfArgs": [
8
- "--style={based_on_style: pep8, indent_width: 4, blank_line_before_nested_class_or_def: false, spaces_before_comment: 2, split_before_logical_operator: true}"
9
- ],
10
  "[python]": {
 
11
  "editor.formatOnType": true,
12
  "editor.codeActionsOnSave": {
13
  "source.organizeImports": true
14
  }
15
  },
 
 
 
 
 
 
 
 
 
 
16
  "editor.formatOnSave": true,
17
  "files.insertFinalNewline": true
18
  }
 
1
  {
 
 
 
 
 
 
 
 
2
  "[python]": {
3
+ "editor.defaultFormatter": "ms-python.black-formatter",
4
  "editor.formatOnType": true,
5
  "editor.codeActionsOnSave": {
6
  "source.organizeImports": true
7
  }
8
  },
9
+ "black-formatter.args": [
10
+ "--line-length=119"
11
+ ],
12
+ "isort.args": ["--profile", "black"],
13
+ "flake8.args": [
14
+ "--max-line-length=119"
15
+ ],
16
+ "ruff.args": [
17
+ "--line-length=119"
18
+ ],
19
  "editor.formatOnSave": true,
20
  "files.insertFinalNewline": true
21
  }
app.py CHANGED
@@ -4,127 +4,153 @@ from __future__ import annotations
4
 
5
  import gradio as gr
6
 
7
- from constants import (HARDWARE_CHOICES, OWNER_CHOICES, SDK_CHOICES,
8
- SLEEP_TIME_CHOICES, STATUS_CHOICES, VISIBILITY_CHOICES)
 
 
 
 
 
 
9
  from demo_list import DemoList, get_df_from_yaml
10
  from restart_scheduler import RestartScheduler
11
  from settings import HF_TOKEN, INTERVAL_MINUTES, SPACE_ID
12
 
13
- demo_list = DemoList(get_df_from_yaml('list.yaml'))
14
 
15
  if SPACE_ID is not None and INTERVAL_MINUTES > 0:
16
- scheduler = RestartScheduler(space_id=SPACE_ID,
17
- interval_minutes=INTERVAL_MINUTES,
18
- hf_token=HF_TOKEN)
19
  scheduler.start()
20
 
21
 
22
  def update_status_checkboxes(choices: list[str]) -> list[str]:
23
- if '(ALL)' in choices:
24
  return STATUS_CHOICES
25
- elif '(NONE)' in choices:
26
  return []
27
  else:
28
  return choices
29
 
30
 
31
  def update_hardware_checkboxes(choices: list[str]) -> list[str]:
32
- if '(ALL)' in choices:
33
  return HARDWARE_CHOICES
34
- elif '(NONE)' in choices:
35
  return []
36
  else:
37
  return choices
38
 
39
 
40
  def update_sdk_checkboxes(choices: list[str]) -> list[str]:
41
- if '(ALL)' in choices:
42
  return SDK_CHOICES
43
- elif '(NONE)' in choices:
44
  return []
45
  else:
46
  return choices
47
 
48
 
49
  def update_sleep_time_checkboxes(choices: list[str]) -> list[str]:
50
- if '(ALL)' in choices:
51
  return SLEEP_TIME_CHOICES
52
- elif '(NONE)' in choices:
53
  return []
54
  else:
55
  return choices
56
 
57
 
58
- with gr.Blocks(css='style.css') as demo:
59
- with gr.Accordion(label='Filter', open=False):
60
- status = gr.CheckboxGroup(label='Status',
61
- choices=['(ALL)', '(NONE)'] + STATUS_CHOICES,
62
- value=STATUS_CHOICES,
63
- type='value')
64
- hardware = gr.CheckboxGroup(label='Hardware',
65
- choices=['(ALL)', '(NONE)'] +
66
- HARDWARE_CHOICES,
67
- value=HARDWARE_CHOICES,
68
- type='value')
69
- sleep_time = gr.CheckboxGroup(label='Sleep time',
70
- choices=['(ALL)', '(NONE)'] +
71
- SLEEP_TIME_CHOICES,
72
- value=SLEEP_TIME_CHOICES,
73
- type='value')
74
- multiple_replicas = gr.Checkbox(label='Multiple replicas', value=False)
75
- sdk = gr.CheckboxGroup(label='SDK',
76
- choices=['(ALL)', '(NONE)'] + SDK_CHOICES,
77
- value=SDK_CHOICES,
78
- type='value')
79
- visibility = gr.CheckboxGroup(label='Visibility',
80
- choices=VISIBILITY_CHOICES,
81
- value=VISIBILITY_CHOICES,
82
- type='value')
83
- owner = gr.CheckboxGroup(label='Owner',
84
- choices=OWNER_CHOICES,
85
- value=OWNER_CHOICES,
86
- type='value')
87
- apply_button = gr.Button('Apply')
88
- df = gr.Dataframe(value=demo_list.df_prettified,
89
- datatype=demo_list.column_datatype,
90
- type='pandas',
91
- interactive=False,
92
- row_count=(0, 'dynamic'))
93
-
94
- status.change(fn=update_status_checkboxes,
95
- inputs=status,
96
- outputs=status,
97
- queue=False,
98
- show_progress=False,
99
- api_name=False)
100
- hardware.change(fn=update_hardware_checkboxes,
101
- inputs=hardware,
102
- outputs=hardware,
103
- queue=False,
104
- show_progress=False,
105
- api_name=False)
106
- sdk.change(fn=update_sdk_checkboxes,
107
- inputs=sdk,
108
- outputs=sdk,
109
- queue=False,
110
- show_progress=False,
111
- api_name=False)
112
- sleep_time.change(fn=update_sleep_time_checkboxes,
113
- inputs=sleep_time,
114
- outputs=sleep_time,
115
- queue=False,
116
- show_progress=False,
117
- api_name=False)
118
- apply_button.click(fn=demo_list.filter,
119
- inputs=[
120
- status,
121
- hardware,
122
- sleep_time,
123
- multiple_replicas,
124
- sdk,
125
- visibility,
126
- owner,
127
- ],
128
- outputs=df,
129
- api_name=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  demo.queue(api_open=False).launch()
 
4
 
5
  import gradio as gr
6
 
7
+ from constants import (
8
+ HARDWARE_CHOICES,
9
+ OWNER_CHOICES,
10
+ SDK_CHOICES,
11
+ SLEEP_TIME_CHOICES,
12
+ STATUS_CHOICES,
13
+ VISIBILITY_CHOICES,
14
+ )
15
  from demo_list import DemoList, get_df_from_yaml
16
  from restart_scheduler import RestartScheduler
17
  from settings import HF_TOKEN, INTERVAL_MINUTES, SPACE_ID
18
 
19
+ demo_list = DemoList(get_df_from_yaml("list.yaml"))
20
 
21
  if SPACE_ID is not None and INTERVAL_MINUTES > 0:
22
+ scheduler = RestartScheduler(space_id=SPACE_ID, interval_minutes=INTERVAL_MINUTES, hf_token=HF_TOKEN)
 
 
23
  scheduler.start()
24
 
25
 
26
  def update_status_checkboxes(choices: list[str]) -> list[str]:
27
+ if "(ALL)" in choices:
28
  return STATUS_CHOICES
29
+ elif "(NONE)" in choices:
30
  return []
31
  else:
32
  return choices
33
 
34
 
35
  def update_hardware_checkboxes(choices: list[str]) -> list[str]:
36
+ if "(ALL)" in choices:
37
  return HARDWARE_CHOICES
38
+ elif "(NONE)" in choices:
39
  return []
40
  else:
41
  return choices
42
 
43
 
44
  def update_sdk_checkboxes(choices: list[str]) -> list[str]:
45
+ if "(ALL)" in choices:
46
  return SDK_CHOICES
47
+ elif "(NONE)" in choices:
48
  return []
49
  else:
50
  return choices
51
 
52
 
53
  def update_sleep_time_checkboxes(choices: list[str]) -> list[str]:
54
+ if "(ALL)" in choices:
55
  return SLEEP_TIME_CHOICES
56
+ elif "(NONE)" in choices:
57
  return []
58
  else:
59
  return choices
60
 
61
 
62
+ with gr.Blocks(css="style.css") as demo:
63
+ with gr.Accordion(label="Filter", open=False):
64
+ status = gr.CheckboxGroup(
65
+ label="Status",
66
+ choices=["(ALL)", "(NONE)"] + STATUS_CHOICES,
67
+ value=STATUS_CHOICES,
68
+ type="value",
69
+ )
70
+ hardware = gr.CheckboxGroup(
71
+ label="Hardware",
72
+ choices=["(ALL)", "(NONE)"] + HARDWARE_CHOICES,
73
+ value=HARDWARE_CHOICES,
74
+ type="value",
75
+ )
76
+ sleep_time = gr.CheckboxGroup(
77
+ label="Sleep time",
78
+ choices=["(ALL)", "(NONE)"] + SLEEP_TIME_CHOICES,
79
+ value=SLEEP_TIME_CHOICES,
80
+ type="value",
81
+ )
82
+ multiple_replicas = gr.Checkbox(label="Multiple replicas", value=False)
83
+ sdk = gr.CheckboxGroup(
84
+ label="SDK",
85
+ choices=["(ALL)", "(NONE)"] + SDK_CHOICES,
86
+ value=SDK_CHOICES,
87
+ type="value",
88
+ )
89
+ visibility = gr.CheckboxGroup(
90
+ label="Visibility",
91
+ choices=VISIBILITY_CHOICES,
92
+ value=VISIBILITY_CHOICES,
93
+ type="value",
94
+ )
95
+ owner = gr.CheckboxGroup(
96
+ label="Owner",
97
+ choices=OWNER_CHOICES,
98
+ value=OWNER_CHOICES,
99
+ type="value",
100
+ )
101
+ apply_button = gr.Button("Apply")
102
+ df = gr.Dataframe(
103
+ value=demo_list.df_prettified,
104
+ datatype=demo_list.column_datatype,
105
+ type="pandas",
106
+ interactive=False,
107
+ row_count=(0, "dynamic"),
108
+ )
109
+
110
+ status.change(
111
+ fn=update_status_checkboxes,
112
+ inputs=status,
113
+ outputs=status,
114
+ queue=False,
115
+ show_progress=False,
116
+ api_name=False,
117
+ )
118
+ hardware.change(
119
+ fn=update_hardware_checkboxes,
120
+ inputs=hardware,
121
+ outputs=hardware,
122
+ queue=False,
123
+ show_progress=False,
124
+ api_name=False,
125
+ )
126
+ sdk.change(
127
+ fn=update_sdk_checkboxes,
128
+ inputs=sdk,
129
+ outputs=sdk,
130
+ queue=False,
131
+ show_progress=False,
132
+ api_name=False,
133
+ )
134
+ sleep_time.change(
135
+ fn=update_sleep_time_checkboxes,
136
+ inputs=sleep_time,
137
+ outputs=sleep_time,
138
+ queue=False,
139
+ show_progress=False,
140
+ api_name=False,
141
+ )
142
+ apply_button.click(
143
+ fn=demo_list.filter,
144
+ inputs=[
145
+ status,
146
+ hardware,
147
+ sleep_time,
148
+ multiple_replicas,
149
+ sdk,
150
+ visibility,
151
+ owner,
152
+ ],
153
+ outputs=df,
154
+ api_name=False,
155
+ )
156
  demo.queue(api_open=False).launch()
constants.py CHANGED
@@ -1,48 +1,48 @@
1
  from huggingface_hub import HfApi
2
 
3
  STATUS_CHOICES = [
4
- 'RUNNING',
5
- 'PAUSED',
6
- 'STOPPED',
7
- 'RUNTIME_ERROR',
8
- 'BUILD_ERROR',
9
- 'CONFIG_ERROR',
10
- 'BUILDING',
11
- 'RUNNING_BUILDING',
12
- 'NO_APP_FILE',
13
  ]
14
  HARDWARE_CHOICES = [
15
- 'cpu-basic',
16
- 'cpu-upgrade',
17
- 't4-small',
18
- 't4-medium',
19
- 'zero-a10g',
20
- 'a10g-small',
21
- 'a10g-large',
22
- 'a100-large',
23
  ]
24
  SDK_CHOICES = [
25
- 'gradio',
26
- 'streamlit',
27
- 'docker',
28
  ]
29
  SLEEP_TIME_INT_TO_STR = {
30
- 0: 'null',
31
- 300: '5 minutes',
32
- 900: '15 minutes',
33
- 1800: '30 minutes',
34
- 3600: '1 hour',
35
- 36000: '10 hours',
36
- 86400: '24 hours',
37
- 172800: '48 hours',
38
- 259200: '72 hours',
39
- 604800: '1 week',
40
  }
41
  SLEEP_TIME_CHOICES = list(SLEEP_TIME_INT_TO_STR.values())
42
  SLEEP_TIME_STR_TO_INT = {v: k for k, v in SLEEP_TIME_INT_TO_STR.items()}
43
 
44
- VISIBILITY_CHOICES = ['public', 'private']
45
 
46
  api = HfApi()
47
- WHOAMI = api.whoami()['name']
48
- OWNER_CHOICES = [WHOAMI, 'other organizations']
 
1
  from huggingface_hub import HfApi
2
 
3
  STATUS_CHOICES = [
4
+ "RUNNING",
5
+ "PAUSED",
6
+ "STOPPED",
7
+ "RUNTIME_ERROR",
8
+ "BUILD_ERROR",
9
+ "CONFIG_ERROR",
10
+ "BUILDING",
11
+ "RUNNING_BUILDING",
12
+ "NO_APP_FILE",
13
  ]
14
  HARDWARE_CHOICES = [
15
+ "cpu-basic",
16
+ "cpu-upgrade",
17
+ "t4-small",
18
+ "t4-medium",
19
+ "zero-a10g",
20
+ "a10g-small",
21
+ "a10g-large",
22
+ "a100-large",
23
  ]
24
  SDK_CHOICES = [
25
+ "gradio",
26
+ "streamlit",
27
+ "docker",
28
  ]
29
  SLEEP_TIME_INT_TO_STR = {
30
+ 0: "null",
31
+ 300: "5 minutes",
32
+ 900: "15 minutes",
33
+ 1800: "30 minutes",
34
+ 3600: "1 hour",
35
+ 36000: "10 hours",
36
+ 86400: "24 hours",
37
+ 172800: "48 hours",
38
+ 259200: "72 hours",
39
+ 604800: "1 week",
40
  }
41
  SLEEP_TIME_CHOICES = list(SLEEP_TIME_INT_TO_STR.values())
42
  SLEEP_TIME_STR_TO_INT = {v: k for k, v in SLEEP_TIME_INT_TO_STR.items()}
43
 
44
+ VISIBILITY_CHOICES = ["public", "private"]
45
 
46
  api = HfApi()
47
+ WHOAMI = api.whoami()["name"]
48
+ OWNER_CHOICES = [WHOAMI, "other organizations"]
demo_list.py CHANGED
@@ -8,8 +8,12 @@ import tqdm.auto
8
  import yaml
9
  from huggingface_hub import HfApi
10
 
11
- from constants import (OWNER_CHOICES, SLEEP_TIME_INT_TO_STR,
12
- SLEEP_TIME_STR_TO_INT, WHOAMI)
 
 
 
 
13
 
14
 
15
  @dataclasses.dataclass(frozen=True)
@@ -28,50 +32,45 @@ class DemoInfo:
28
  private: bool
29
  hardware: str
30
  suggested_hardware: str
31
- created: str = ''
32
  arxiv: list[str] = dataclasses.field(default_factory=list)
33
  github: list[str] = dataclasses.field(default_factory=list)
34
  tags: list[str] = dataclasses.field(default_factory=list)
35
 
36
  def __post_init__(self):
37
- object.__setattr__(self, 'last_modified',
38
- DemoInfo.convert_timestamp(self.last_modified))
39
- object.__setattr__(self, 'created',
40
- DemoInfo.convert_timestamp(self.created))
41
 
42
  @staticmethod
43
  def convert_timestamp(timestamp: str) -> str:
44
  try:
45
- return datetime.datetime.strptime(
46
- timestamp,
47
- '%Y-%m-%dT%H:%M:%S.%fZ').strftime('%Y/%m/%d %H:%M:%S')
48
  except ValueError:
49
  return timestamp
50
 
51
  @classmethod
52
- def from_space_id(cls, space_id: str) -> 'DemoInfo':
53
  api = HfApi()
54
  space_info = api.space_info(repo_id=space_id)
55
  card = space_info.cardData
56
  runtime = space_info.runtime
57
- resources = runtime['resources']
58
 
59
  return cls(
60
  space_id=space_id,
61
- url=f'https://huggingface.co/spaces/{space_id}',
62
- title=card['title'] if 'title' in card else '',
63
- owner=space_id.split('/')[0],
64
- sdk=card['sdk'],
65
- sdk_version=card.get('sdk_version', ''),
66
  likes=space_info.likes,
67
- status=runtime['stage'],
68
  last_modified=space_info.lastModified,
69
- sleep_time=runtime['gcTimeout'] or 0,
70
- replicas=resources['replicas'] if resources is not None else 0,
71
  private=space_info.private,
72
- hardware=runtime['hardware']['current']
73
- or runtime['hardware']['requested'],
74
- suggested_hardware=card.get('suggested_hardware', ''),
75
  )
76
 
77
 
@@ -89,19 +88,17 @@ def get_df_from_yaml(path: pathlib.Path | str) -> pd.DataFrame:
89
  class Prettifier:
90
  @staticmethod
91
  def get_arxiv_link(links: list[str]) -> str:
92
- links = [
93
- Prettifier.create_link(link.split('/')[-1], link) for link in links
94
- ]
95
- return '\n'.join(links)
96
 
97
  @staticmethod
98
  def get_github_link(links: list[str]) -> str:
99
- links = [Prettifier.create_link('github', link) for link in links]
100
- return '\n'.join(links)
101
 
102
  @staticmethod
103
  def get_tag_list(tags: list[str]) -> str:
104
- return ', '.join(tags)
105
 
106
  @staticmethod
107
  def create_link(text: str, url: str) -> str:
@@ -110,53 +107,40 @@ class Prettifier:
110
  @staticmethod
111
  def to_div(text: str | None, category_name: str) -> str:
112
  if text is None:
113
- text = ''
114
- class_name = f'{category_name}-{text.lower()}'
115
  return f'<div class="{class_name}">{text}</div>'
116
 
117
  @staticmethod
118
  def add_div_tag_to_replicas(replicas: int) -> str:
119
  if replicas == 0:
120
- return ''
121
  if replicas == 1:
122
- return '1'
123
  return f'<div class="multiple-replicas">{replicas}</div>'
124
 
125
  @staticmethod
126
  def add_div_tag_to_sleep_time(sleep_time_s: str, hardware: str) -> str:
127
- if hardware == 'cpu-basic':
128
  return f'<div class="sleep-time-cpu-basic">{sleep_time_s}</div>'
129
- s = sleep_time_s.replace(' ', '-')
130
  return f'<div class="sleep-time-{s}">{sleep_time_s}</div>'
131
 
132
  def __call__(self, df: pd.DataFrame) -> pd.DataFrame:
133
  new_rows = []
134
  for _, row in df.iterrows():
135
  new_row = dict(row) | {
136
- 'status':
137
- self.to_div(row.status, 'status'),
138
- 'hardware':
139
- self.to_div(row.hardware, 'hardware'),
140
- 'suggested_hardware':
141
- self.to_div(row.suggested_hardware, 'hardware'),
142
- 'title':
143
- self.create_link(row.title, row.url),
144
- 'owner':
145
- self.create_link(row.owner,
146
- f'https://huggingface.co/{row.owner}'),
147
- 'sdk':
148
- self.to_div(row.sdk, 'sdk'),
149
- 'sleep_time':
150
- self.add_div_tag_to_sleep_time(
151
- SLEEP_TIME_INT_TO_STR[row.sleep_time], row.hardware),
152
- 'replicas':
153
- self.add_div_tag_to_replicas(row.replicas),
154
- 'arxiv':
155
- self.get_arxiv_link(row.arxiv),
156
- 'github':
157
- self.get_github_link(row.github),
158
- 'tags':
159
- self.get_tag_list(row.tags),
160
  }
161
  new_rows.append(new_row)
162
  return pd.DataFrame(new_rows, columns=df.columns)
@@ -164,22 +148,22 @@ class Prettifier:
164
 
165
  class DemoList:
166
  COLUMN_INFO = [
167
- ['status', 'markdown'],
168
- ['hardware', 'markdown'],
169
- ['title', 'markdown'],
170
- ['owner', 'markdown'],
171
- ['arxiv', 'markdown'],
172
- ['github', 'markdown'],
173
- ['likes', 'number'],
174
- ['tags', 'str'],
175
- ['last_modified', 'str'],
176
- ['created', 'str'],
177
- ['sdk', 'markdown'],
178
- ['sdk_version', 'str'],
179
- ['suggested_hardware', 'markdown'],
180
- ['sleep_time', 'markdown'],
181
- ['replicas', 'markdown'],
182
- ['private', 'bool'],
183
  ]
184
 
185
  def __init__(self, df: pd.DataFrame):
@@ -210,14 +194,14 @@ class DemoList:
210
  if multiple_replicas:
211
  df = df[self.df_raw.replicas > 1]
212
 
213
- if visibility == ['public']:
214
  df = df[~self.df_raw.private]
215
- elif visibility == ['private']:
216
  df = df[self.df_raw.private]
217
 
218
- df = df[(self.df_raw.status.isin(status))
219
- & (self.df_raw.hardware.isin(hardware))
220
- & (self.df_raw.sdk.isin(sdk))]
221
 
222
  sleep_time_int = [SLEEP_TIME_STR_TO_INT[s] for s in sleep_time]
223
  df = df[self.df_raw.sleep_time.isin(sleep_time_int)]
 
8
  import yaml
9
  from huggingface_hub import HfApi
10
 
11
+ from constants import (
12
+ OWNER_CHOICES,
13
+ SLEEP_TIME_INT_TO_STR,
14
+ SLEEP_TIME_STR_TO_INT,
15
+ WHOAMI,
16
+ )
17
 
18
 
19
  @dataclasses.dataclass(frozen=True)
 
32
  private: bool
33
  hardware: str
34
  suggested_hardware: str
35
+ created: str = ""
36
  arxiv: list[str] = dataclasses.field(default_factory=list)
37
  github: list[str] = dataclasses.field(default_factory=list)
38
  tags: list[str] = dataclasses.field(default_factory=list)
39
 
40
  def __post_init__(self):
41
+ object.__setattr__(self, "last_modified", DemoInfo.convert_timestamp(self.last_modified))
42
+ object.__setattr__(self, "created", DemoInfo.convert_timestamp(self.created))
 
 
43
 
44
  @staticmethod
45
  def convert_timestamp(timestamp: str) -> str:
46
  try:
47
+ return datetime.datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%fZ").strftime("%Y/%m/%d %H:%M:%S")
 
 
48
  except ValueError:
49
  return timestamp
50
 
51
  @classmethod
52
+ def from_space_id(cls, space_id: str) -> "DemoInfo":
53
  api = HfApi()
54
  space_info = api.space_info(repo_id=space_id)
55
  card = space_info.cardData
56
  runtime = space_info.runtime
57
+ resources = runtime["resources"]
58
 
59
  return cls(
60
  space_id=space_id,
61
+ url=f"https://huggingface.co/spaces/{space_id}",
62
+ title=card["title"] if "title" in card else "",
63
+ owner=space_id.split("/")[0],
64
+ sdk=card["sdk"],
65
+ sdk_version=card.get("sdk_version", ""),
66
  likes=space_info.likes,
67
+ status=runtime["stage"],
68
  last_modified=space_info.lastModified,
69
+ sleep_time=runtime["gcTimeout"] or 0,
70
+ replicas=resources["replicas"] if resources is not None else 0,
71
  private=space_info.private,
72
+ hardware=runtime["hardware"]["current"] or runtime["hardware"]["requested"],
73
+ suggested_hardware=card.get("suggested_hardware", ""),
 
74
  )
75
 
76
 
 
88
  class Prettifier:
89
  @staticmethod
90
  def get_arxiv_link(links: list[str]) -> str:
91
+ links = [Prettifier.create_link(link.split("/")[-1], link) for link in links]
92
+ return "\n".join(links)
 
 
93
 
94
  @staticmethod
95
  def get_github_link(links: list[str]) -> str:
96
+ links = [Prettifier.create_link("github", link) for link in links]
97
+ return "\n".join(links)
98
 
99
  @staticmethod
100
  def get_tag_list(tags: list[str]) -> str:
101
+ return ", ".join(tags)
102
 
103
  @staticmethod
104
  def create_link(text: str, url: str) -> str:
 
107
  @staticmethod
108
  def to_div(text: str | None, category_name: str) -> str:
109
  if text is None:
110
+ text = ""
111
+ class_name = f"{category_name}-{text.lower()}"
112
  return f'<div class="{class_name}">{text}</div>'
113
 
114
  @staticmethod
115
  def add_div_tag_to_replicas(replicas: int) -> str:
116
  if replicas == 0:
117
+ return ""
118
  if replicas == 1:
119
+ return "1"
120
  return f'<div class="multiple-replicas">{replicas}</div>'
121
 
122
  @staticmethod
123
  def add_div_tag_to_sleep_time(sleep_time_s: str, hardware: str) -> str:
124
+ if hardware == "cpu-basic":
125
  return f'<div class="sleep-time-cpu-basic">{sleep_time_s}</div>'
126
+ s = sleep_time_s.replace(" ", "-")
127
  return f'<div class="sleep-time-{s}">{sleep_time_s}</div>'
128
 
129
  def __call__(self, df: pd.DataFrame) -> pd.DataFrame:
130
  new_rows = []
131
  for _, row in df.iterrows():
132
  new_row = dict(row) | {
133
+ "status": self.to_div(row.status, "status"),
134
+ "hardware": self.to_div(row.hardware, "hardware"),
135
+ "suggested_hardware": self.to_div(row.suggested_hardware, "hardware"),
136
+ "title": self.create_link(row.title, row.url),
137
+ "owner": self.create_link(row.owner, f"https://huggingface.co/{row.owner}"),
138
+ "sdk": self.to_div(row.sdk, "sdk"),
139
+ "sleep_time": self.add_div_tag_to_sleep_time(SLEEP_TIME_INT_TO_STR[row.sleep_time], row.hardware),
140
+ "replicas": self.add_div_tag_to_replicas(row.replicas),
141
+ "arxiv": self.get_arxiv_link(row.arxiv),
142
+ "github": self.get_github_link(row.github),
143
+ "tags": self.get_tag_list(row.tags),
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  }
145
  new_rows.append(new_row)
146
  return pd.DataFrame(new_rows, columns=df.columns)
 
148
 
149
  class DemoList:
150
  COLUMN_INFO = [
151
+ ["status", "markdown"],
152
+ ["hardware", "markdown"],
153
+ ["title", "markdown"],
154
+ ["owner", "markdown"],
155
+ ["arxiv", "markdown"],
156
+ ["github", "markdown"],
157
+ ["likes", "number"],
158
+ ["tags", "str"],
159
+ ["last_modified", "str"],
160
+ ["created", "str"],
161
+ ["sdk", "markdown"],
162
+ ["sdk_version", "str"],
163
+ ["suggested_hardware", "markdown"],
164
+ ["sleep_time", "markdown"],
165
+ ["replicas", "markdown"],
166
+ ["private", "bool"],
167
  ]
168
 
169
  def __init__(self, df: pd.DataFrame):
 
194
  if multiple_replicas:
195
  df = df[self.df_raw.replicas > 1]
196
 
197
+ if visibility == ["public"]:
198
  df = df[~self.df_raw.private]
199
+ elif visibility == ["private"]:
200
  df = df[self.df_raw.private]
201
 
202
+ df = df[
203
+ (self.df_raw.status.isin(status)) & (self.df_raw.hardware.isin(hardware)) & (self.df_raw.sdk.isin(sdk))
204
+ ]
205
 
206
  sleep_time_int = [SLEEP_TIME_STR_TO_INT[s] for s in sleep_time]
207
  df = df[self.df_raw.sleep_time.isin(sleep_time_int)]
restart_scheduler.py CHANGED
@@ -4,22 +4,21 @@ from huggingface_hub.utils import RepositoryNotFoundError
4
 
5
 
6
  class RestartScheduler:
7
- def __init__(self, space_id: str, interval_minutes: int,
8
- hf_token: str | None):
9
  api = HfApi(token=hf_token)
10
- if api.get_token_permission() != 'write':
11
- raise ValueError('The HF token must have write permission.')
12
  try:
13
  api.space_info(repo_id=space_id)
14
  except RepositoryNotFoundError:
15
- raise ValueError('The Space ID does not exist.')
16
  if interval_minutes <= 0:
17
- raise ValueError('The interval must be positive.')
18
 
19
  self.scheduler = BackgroundScheduler()
20
- self.scheduler.add_job(func=lambda: api.restart_space(space_id),
21
- trigger='interval',
22
- seconds=60 * interval_minutes)
23
 
24
  def start(self):
25
  self.scheduler.start()
 
4
 
5
 
6
  class RestartScheduler:
7
+ def __init__(self, space_id: str, interval_minutes: int, hf_token: str | None):
 
8
  api = HfApi(token=hf_token)
9
+ if api.get_token_permission() != "write":
10
+ raise ValueError("The HF token must have write permission.")
11
  try:
12
  api.space_info(repo_id=space_id)
13
  except RepositoryNotFoundError:
14
+ raise ValueError("The Space ID does not exist.")
15
  if interval_minutes <= 0:
16
+ raise ValueError("The interval must be positive.")
17
 
18
  self.scheduler = BackgroundScheduler()
19
+ self.scheduler.add_job(
20
+ func=lambda: api.restart_space(space_id), trigger="interval", seconds=60 * interval_minutes
21
+ )
22
 
23
  def start(self):
24
  self.scheduler.start()
settings.py CHANGED
@@ -1,5 +1,5 @@
1
  import os
2
 
3
- HF_TOKEN = os.getenv('HUGGING_FACE_HUB_TOKEN')
4
- SPACE_ID = os.getenv('SPACE_ID')
5
- INTERVAL_MINUTES = int(os.getenv('INTERVAL_MINUTES', '30'))
 
1
  import os
2
 
3
+ HF_TOKEN = os.getenv("HUGGING_FACE_HUB_TOKEN")
4
+ SPACE_ID = os.getenv("SPACE_ID")
5
+ INTERVAL_MINUTES = int(os.getenv("INTERVAL_MINUTES", "30"))
tools/add_creation_timestamps.py CHANGED
@@ -10,7 +10,7 @@ import tqdm.auto
10
  import yaml
11
 
12
  repo_dir = pathlib.Path(__file__).parents[1]
13
- yaml_path = repo_dir / 'list.yaml'
14
 
15
 
16
  def add_creation_timestamps() -> None:
@@ -20,18 +20,18 @@ def add_creation_timestamps() -> None:
20
  space_ids = list(data.keys())
21
  for space_id in tqdm.auto.tqdm(space_ids):
22
  info = data[space_id]
23
- if 'created' in info:
24
  continue
25
  with tempfile.TemporaryDirectory() as temp_dir:
26
- url = f'https://huggingface.co/spaces/{space_id}'
27
  repo = git.Repo.clone_from(url, temp_dir)
28
  commits = list(repo.iter_commits())
29
  initial_commit = commits[-1]
30
  date = initial_commit.authored_datetime
31
- date_str = date.strftime('%Y-%m-%dT%H:%M:%S.000Z')
32
- info['created'] = date_str
33
 
34
- with open(yaml_path, 'w') as f:
35
  yaml.dump(data, f)
36
 
37
 
@@ -39,15 +39,15 @@ def sort_by_creation_date() -> None:
39
  with open(yaml_path) as f:
40
  data = yaml.safe_load(f)
41
 
42
- keys = sorted(data.keys(), key=lambda x: data[x]['created'])
43
  sorted_data = dict()
44
  for key in keys[::-1]:
45
  sorted_data[key] = data[key]
46
 
47
- with open(yaml_path, 'w') as f:
48
  yaml.dump(sorted_data, f, sort_keys=False)
49
 
50
 
51
- if __name__ == '__main__':
52
  add_creation_timestamps()
53
  sort_by_creation_date()
 
10
  import yaml
11
 
12
  repo_dir = pathlib.Path(__file__).parents[1]
13
+ yaml_path = repo_dir / "list.yaml"
14
 
15
 
16
  def add_creation_timestamps() -> None:
 
20
  space_ids = list(data.keys())
21
  for space_id in tqdm.auto.tqdm(space_ids):
22
  info = data[space_id]
23
+ if "created" in info:
24
  continue
25
  with tempfile.TemporaryDirectory() as temp_dir:
26
+ url = f"https://huggingface.co/spaces/{space_id}"
27
  repo = git.Repo.clone_from(url, temp_dir)
28
  commits = list(repo.iter_commits())
29
  initial_commit = commits[-1]
30
  date = initial_commit.authored_datetime
31
+ date_str = date.strftime("%Y-%m-%dT%H:%M:%S.000Z")
32
+ info["created"] = date_str
33
 
34
+ with open(yaml_path, "w") as f:
35
  yaml.dump(data, f)
36
 
37
 
 
39
  with open(yaml_path) as f:
40
  data = yaml.safe_load(f)
41
 
42
+ keys = sorted(data.keys(), key=lambda x: data[x]["created"])
43
  sorted_data = dict()
44
  for key in keys[::-1]:
45
  sorted_data[key] = data[key]
46
 
47
+ with open(yaml_path, "w") as f:
48
  yaml.dump(sorted_data, f, sort_keys=False)
49
 
50
 
51
+ if __name__ == "__main__":
52
  add_creation_timestamps()
53
  sort_by_creation_date()