RichardErkhov commited on
Commit
9e2b8ba
·
verified ·
1 Parent(s): 0a9545b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -73
app.py CHANGED
@@ -1,15 +1,20 @@
1
  import gradio as gr
2
  import pandas as pd
3
- from huggingface_hub import HfApi
4
 
5
- # Initialize Hugging Face API
6
- api = HfApi()
7
-
8
- # Constants
9
- GGUF_TAG = "gguf"
10
  CHUNK_SIZE = 1000
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- # Clickable links function
13
  def clickable(x, which_one):
14
  if x in ["Not Found", "Unknown"]:
15
  return "Not Found"
@@ -18,55 +23,40 @@ def clickable(x, which_one):
18
  else:
19
  return f'<a target="_blank" href="https://huggingface.co/{which_one}/{x}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;">{x}</a>'
20
 
21
- # Fetch models and return a DataFrame with clickable links
22
- def fetch_models():
23
- models = api.list_models(filter=GGUF_TAG, full=True)
24
- data = []
25
- for model in models:
26
- model_id = model.id if model.id else "Not Found"
27
- author = model.author if model.author else "Unknown"
28
- data.append({
29
- "Model ID": model_id,
30
- "Author Name": author,
31
- "Downloads (30d)": model.downloads or 0,
32
- "Likes": model.likes or 0,
33
- "Created At": model.created_at.isoformat() if model.created_at else "N/A",
34
- "Last Modified": model.last_modified.isoformat() if model.last_modified else "N/A",
35
- })
36
- df = pd.DataFrame(data)
37
- # Apply clickable links to models and authors
38
- df["Model ID"] = df["Model ID"].apply(lambda x: clickable(x, "models"))
39
- df["Author Name"] = df["Author Name"].apply(lambda x: clickable(x, "models"))
40
- return df
41
-
42
- # Prepare authors DataFrame
43
- def prepare_authors_df(models_df):
44
- authors_df = models_df.copy()
45
- # Extract the author name from the href in the clickable link
46
- authors_df["Clean Author Name"] = authors_df["Author Name"].str.extract(r'href="https://huggingface\.co/(.*?)"')
47
-
48
- grouped = authors_df.groupby("Clean Author Name").agg(
49
- Models_Count=("Model ID", "count"),
50
- Total_Downloads=("Downloads (30d)", "sum"),
51
- Total_Likes=("Likes", "sum")
52
- ).reset_index()
53
-
54
- grouped.rename(columns={"Clean Author Name": "Author Name"}, inplace=True)
55
- grouped["Author Name"] = grouped["Author Name"].apply(lambda x: clickable(x, "models"))
56
- return grouped.sort_values(by="Models_Count", ascending=False)
57
-
58
- all_models_df = fetch_models().sort_values(by="Downloads (30d)", ascending=False)
59
- authors_df = prepare_authors_df(all_models_df)
60
-
61
- # Calculate totals
62
- total_models_count = len(all_models_df)
63
- total_downloads = all_models_df["Downloads (30d)"].sum()
64
- total_likes = all_models_df["Likes"].sum()
65
-
66
- def apply_model_filters(search_query, min_downloads, min_likes):
67
- df = all_models_df.copy()
68
-
69
- # Extract visible text for filtering purposes:
70
  visible_model_id = df["Model ID"].str.extract(r'>(.*?)<')[0]
71
  visible_author_name = df["Author Name"].str.extract(r'>(.*?)<')[0]
72
 
@@ -86,8 +76,8 @@ def apply_model_filters(search_query, min_downloads, min_likes):
86
 
87
  return df
88
 
89
- def filter_models(search_query, min_downloads, min_likes):
90
- filtered = apply_model_filters(search_query, min_downloads, min_likes)
91
  return filtered.iloc[:CHUNK_SIZE], CHUNK_SIZE, filtered
92
 
93
  def update_model_table(start_idx, filtered_df):
@@ -95,7 +85,7 @@ def update_model_table(start_idx, filtered_df):
95
  combined_df = filtered_df.iloc[:new_end].copy()
96
  return combined_df, new_end
97
 
98
- def apply_author_filters(search_query, min_author_downloads, min_author_likes):
99
  df = authors_df.copy()
100
 
101
  # Extract visible text for author filtering:
@@ -116,22 +106,62 @@ def apply_author_filters(search_query, min_author_downloads, min_author_likes):
116
 
117
  return df
118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  with gr.Blocks() as demo:
121
  gr.Markdown(f"""
122
  # 🚀GGUF Tracker🚀
123
  Welcome to 🚀**GGUF Tracker**🚀, a live-updating leaderboard for all things GGUF on 🚀Hugging Face.
124
- Stats refresh every hour, giving you the latest numbers.
125
 
126
  By the way, I’m 🚀Richard Erkhov, and you can check out more of what I’m working on at my [🌟**github**](https://github.com/RichardErkhov),
127
  [🌟**huggingface**](https://huggingface.co/RichardErkhov) or [🌟**erkhov.com**](https://erkhov.com). Go take a look—I think you’ll like what you find.
128
  """)
129
 
130
- gr.Markdown(f"""
131
- # GGUF Models and Authors Leaderboard
132
- **Total Models:** {total_models_count} | **Total Downloads (30d):** {total_downloads} | **Total Likes:** {total_likes}
133
- """)
134
-
135
  with gr.Tabs():
136
  with gr.TabItem("Models"):
137
  with gr.Row():
@@ -149,13 +179,13 @@ with gr.Blocks() as demo:
149
  )
150
  load_more_button = gr.Button("Load More Models")
151
 
152
- # States
153
  start_idx = gr.State(value=CHUNK_SIZE)
154
- filtered_df_state = gr.State(value=all_models_df) # holds the currently filtered df
155
 
156
  filter_button.click(
157
  fn=filter_models,
158
- inputs=[search_query, min_downloads, min_likes],
159
  outputs=[model_table, start_idx, filtered_df_state]
160
  )
161
  load_more_button.click(fn=update_model_table, inputs=[start_idx, filtered_df_state], outputs=[model_table, start_idx])
@@ -175,14 +205,32 @@ with gr.Blocks() as demo:
175
  datatype=["markdown", "number", "number", "number"]
176
  )
177
 
178
- def filter_authors(author_search_query, min_author_downloads, min_author_likes):
179
- filtered_authors = apply_author_filters(author_search_query, min_author_downloads, min_author_likes)
180
- return filtered_authors
181
-
182
  author_filter_button.click(
183
  fn=filter_authors,
184
- inputs=[author_search_query, min_author_downloads, min_author_likes],
185
  outputs=author_table
186
  )
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  demo.launch()
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import requests
4
 
 
 
 
 
 
5
  CHUNK_SIZE = 1000
6
+ DATA_URL = "https://erkhov.com/huggingspace_data"
7
+ TIME_URL = "https://erkhov.com/huggingspace_time"
8
+
9
+ def fetch_time():
10
+ response = requests.get(TIME_URL)
11
+ return response.text.strip() # assume the endpoint returns a raw timestamp or numeric value as string
12
+
13
+ def fetch_data():
14
+ response = requests.get(DATA_URL)
15
+ data = response.json()
16
+ return data
17
 
 
18
  def clickable(x, which_one):
19
  if x in ["Not Found", "Unknown"]:
20
  return "Not Found"
 
23
  else:
24
  return f'<a target="_blank" href="https://huggingface.co/{which_one}/{x}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;">{x}</a>'
25
 
26
+ def create_dataframes(data):
27
+ models_data = data["models"]
28
+ authors_data = data["authors"]
29
+
30
+ # Create DataFrame for models
31
+ models_df = pd.DataFrame(models_data)
32
+ models_df.rename(columns={
33
+ "id": "Model ID",
34
+ "author": "Author Name",
35
+ "downloads": "Downloads (30d)",
36
+ "likes": "Likes",
37
+ "created_at": "Created At",
38
+ "last_modified": "Last Modified"
39
+ }, inplace=True)
40
+ models_df["Model ID"] = models_df["Model ID"].apply(lambda x: clickable(x, "models"))
41
+ models_df["Author Name"] = models_df["Author Name"].apply(lambda x: clickable(x, "models"))
42
+ models_df = models_df.sort_values(by="Downloads (30d)", ascending=False)
43
+
44
+ # Create DataFrame for authors
45
+ authors_df = pd.DataFrame(authors_data)
46
+ authors_df.rename(columns={
47
+ "author": "Author Name",
48
+ "models_count": "Models_Count",
49
+ "downloads": "Total_Downloads",
50
+ "likes": "Total_Likes"
51
+ }, inplace=True)
52
+ authors_df["Author Name"] = authors_df["Author Name"].apply(lambda x: clickable(x, "models"))
53
+ authors_df = authors_df.sort_values(by="Models_Count", ascending=False)
54
+
55
+ return models_df, authors_df
56
+
57
+ def apply_model_filters(models_df, search_query, min_downloads, min_likes):
58
+ df = models_df.copy()
59
+ # Extract visible text for filtering
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  visible_model_id = df["Model ID"].str.extract(r'>(.*?)<')[0]
61
  visible_author_name = df["Author Name"].str.extract(r'>(.*?)<')[0]
62
 
 
76
 
77
  return df
78
 
79
+ def filter_models(models_df, search_query, min_downloads, min_likes):
80
+ filtered = apply_model_filters(models_df, search_query, min_downloads, min_likes)
81
  return filtered.iloc[:CHUNK_SIZE], CHUNK_SIZE, filtered
82
 
83
  def update_model_table(start_idx, filtered_df):
 
85
  combined_df = filtered_df.iloc[:new_end].copy()
86
  return combined_df, new_end
87
 
88
+ def apply_author_filters(authors_df, search_query, min_author_downloads, min_author_likes):
89
  df = authors_df.copy()
90
 
91
  # Extract visible text for author filtering:
 
106
 
107
  return df
108
 
109
+ def filter_authors(authors_df, author_search_query, min_author_downloads, min_author_likes):
110
+ filtered_authors = apply_author_filters(authors_df, author_search_query, min_author_downloads, min_author_likes)
111
+ return filtered_authors
112
+
113
+ def refresh_data(last_time, models_df_state, authors_df_state, stats_markdown, model_table, author_table):
114
+ # Check if time changed
115
+ current_time = fetch_time()
116
+ if current_time != last_time and current_time != 0:
117
+ # Time changed, re-fetch data
118
+ data = fetch_data()
119
+ models_df, authors_df = create_dataframes(data)
120
+
121
+ total_models_count = data["total_models"]
122
+ total_downloads = data["total_downloads"]
123
+ total_likes = models_df["Likes"].sum() if "Likes" in models_df.columns else 0
124
+
125
+ # Update stats markdown
126
+ new_stats_markdown = f"""
127
+ # GGUF Models and Authors Leaderboard
128
+ **Total Models:** {total_models_count} | **Total Downloads (30d):** {total_downloads} | **Total Likes:** {total_likes}
129
+ **Last Updated:** {current_time}
130
+ """
131
+
132
+ # Update states
133
+ return current_time, models_df, authors_df, gr.update(value=new_stats_markdown), gr.update(value=models_df.iloc[:CHUNK_SIZE]), gr.update(value=authors_df)
134
+ else:
135
+ # No change
136
+ return last_time, models_df_state, authors_df_state, stats_markdown, model_table, author_table
137
+
138
+ # Initial fetch
139
+ initial_time = fetch_time()
140
+ data = fetch_data()
141
+ all_models_df, authors_df = create_dataframes(data)
142
+
143
+ total_models_count = data["total_models"]
144
+ total_downloads = data["total_downloads"]
145
+ total_likes = all_models_df["Likes"].sum() if "Likes" in all_models_df.columns else 0
146
+
147
+ initial_stats_markdown = f"""
148
+ # GGUF Models and Authors Leaderboard
149
+ **Total Models:** {total_models_count} | **Total Downloads (30d):** {total_downloads} | **Total Likes:** {total_likes}
150
+ **Last Updated:** {initial_time}
151
+ """
152
 
153
  with gr.Blocks() as demo:
154
  gr.Markdown(f"""
155
  # 🚀GGUF Tracker🚀
156
  Welcome to 🚀**GGUF Tracker**🚀, a live-updating leaderboard for all things GGUF on 🚀Hugging Face.
157
+ Stats refresh every hour on the backend, but this interface checks every 5 minutes for updates.
158
 
159
  By the way, I’m 🚀Richard Erkhov, and you can check out more of what I’m working on at my [🌟**github**](https://github.com/RichardErkhov),
160
  [🌟**huggingface**](https://huggingface.co/RichardErkhov) or [🌟**erkhov.com**](https://erkhov.com). Go take a look—I think you’ll like what you find.
161
  """)
162
 
163
+ stats_markdown = gr.Markdown(initial_stats_markdown)
164
+
 
 
 
165
  with gr.Tabs():
166
  with gr.TabItem("Models"):
167
  with gr.Row():
 
179
  )
180
  load_more_button = gr.Button("Load More Models")
181
 
182
+ # States for models
183
  start_idx = gr.State(value=CHUNK_SIZE)
184
+ filtered_df_state = gr.State(value=all_models_df)
185
 
186
  filter_button.click(
187
  fn=filter_models,
188
+ inputs=[filtered_df_state, search_query, min_downloads, min_likes],
189
  outputs=[model_table, start_idx, filtered_df_state]
190
  )
191
  load_more_button.click(fn=update_model_table, inputs=[start_idx, filtered_df_state], outputs=[model_table, start_idx])
 
205
  datatype=["markdown", "number", "number", "number"]
206
  )
207
 
 
 
 
 
208
  author_filter_button.click(
209
  fn=filter_authors,
210
+ inputs=[authors_df, author_search_query, min_author_downloads, min_author_likes],
211
  outputs=author_table
212
  )
213
 
214
+ # States for refresh
215
+ last_hf_time_state = gr.State(value=initial_time)
216
+ models_df_state = gr.State(value=all_models_df)
217
+ authors_df_state = gr.State(value=authors_df)
218
+
219
+ # Timer to check every 5 minutes = 300 seconds
220
+ timer = gr.Timer(interval=300, fn=refresh_data, inputs=[
221
+ last_hf_time_state,
222
+ models_df_state,
223
+ authors_df_state,
224
+ stats_markdown,
225
+ model_table,
226
+ author_table
227
+ ], outputs=[
228
+ last_hf_time_state,
229
+ models_df_state,
230
+ authors_df_state,
231
+ stats_markdown,
232
+ model_table,
233
+ author_table
234
+ ])
235
+
236
  demo.launch()