ReallyFloppyPenguin commited on
Commit
01fb3ef
Β·
verified Β·
1 Parent(s): a8a6bae

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +318 -0
app.py ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GRADIO HF SPACE
2
+ import gradio as gr
3
+ import requests
4
+ import pandas as pd
5
+ from datetime import datetime, timedelta
6
+ import urllib.parse
7
+
8
+ def get_hf_models_by_category():
9
+ """
10
+ Fetch top 3 models from each Hugging Face category ranked by likes7d
11
+ """
12
+ # Hugging Face API endpoint
13
+ api_url = "https://huggingface.co/api/models"
14
+
15
+ # Common model categories on Hugging Face
16
+ categories = [
17
+ "text-generation",
18
+ "text-classification",
19
+ "token-classification",
20
+ "question-answering",
21
+ "fill-mask",
22
+ "summarization",
23
+ "translation",
24
+ "text2text-generation",
25
+ "image-classification",
26
+ "object-detection",
27
+ "image-segmentation",
28
+ "text-to-image",
29
+ "image-to-text",
30
+ "automatic-speech-recognition",
31
+ "audio-classification",
32
+ "text-to-speech",
33
+ "audio-to-audio",
34
+ "voice-activity-detection",
35
+ "depth-estimation",
36
+ "image-feature-extraction",
37
+ "other"
38
+ ]
39
+
40
+ results = {}
41
+
42
+ for category in categories:
43
+ try:
44
+ # Fetch models for this category, sorted by likes in the last 7 days
45
+ params = {
46
+ "pipeline_tag": category,
47
+ "sort": "likes7d",
48
+ "direction": -1,
49
+ "limit": 3,
50
+ "full": True # Get full model info including downloads
51
+ }
52
+
53
+ response = requests.get(api_url, params=params, timeout=10)
54
+
55
+ if response.status_code == 200:
56
+ models = response.json()
57
+ category_models = []
58
+
59
+ for model in models:
60
+ # Try different field names for model ID
61
+ model_id = model.get("id") or model.get("modelId") or model.get("_id", "Unknown")
62
+
63
+ # Get likes (might be in different fields)
64
+ likes = (model.get("likes") or
65
+ model.get("likesRecent") or
66
+ model.get("likes7d") or 0)
67
+
68
+ # Get downloads (different possible field names)
69
+ downloads = (model.get("downloads") or
70
+ model.get("downloadsAllTime") or
71
+ model.get("downloads_all_time") or
72
+ model.get("downloads_last_month", 0))
73
+
74
+ # Get last modified date
75
+ last_modified = (model.get("lastModified") or
76
+ model.get("last_modified") or
77
+ model.get("createdAt") or
78
+ model.get("updatedAt") or "Unknown")
79
+
80
+ model_info = {
81
+ "name": model_id,
82
+ "likes": likes,
83
+ "downloads": downloads,
84
+ "updated": last_modified,
85
+ "url": f"https://huggingface.co/{model_id}"
86
+ }
87
+ category_models.append(model_info)
88
+
89
+ if category_models: # Only add if we found models
90
+ results[category] = category_models
91
+
92
+ except Exception as e:
93
+ print(f"Error fetching {category}: {str(e)}")
94
+ continue
95
+
96
+ return results
97
+
98
+ def format_number(num):
99
+ """Format large numbers in a readable way"""
100
+ if num >= 1000000:
101
+ return f"{num/1000000:.1f}M"
102
+ elif num >= 1000:
103
+ return f"{num/1000:.1f}k"
104
+ else:
105
+ return str(num)
106
+
107
+ def format_date(date_str):
108
+ """Format date string to be more readable"""
109
+ if date_str == "Unknown" or not date_str:
110
+ return "Unknown"
111
+ try:
112
+ # Parse the ISO date string and format it
113
+ if "T" in date_str:
114
+ date_obj = datetime.fromisoformat(date_str.replace("Z", "+00:00"))
115
+ return date_obj.strftime("%Y-%m-%d")
116
+ else:
117
+ return date_str[:10] # Just take the date part
118
+ except:
119
+ return "Unknown"
120
+
121
+ def format_model_display(models_data):
122
+ """
123
+ Format the models data into a nice display format
124
+ """
125
+ if not models_data:
126
+ return "No models found or API unavailable."
127
+
128
+ html_content = """
129
+ <div style="font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto;">
130
+ <h1 style="text-align: center; color: #ff6b6b; margin-bottom: 30px;">
131
+ πŸ€— Top 3 Hugging Face Models by Category (Last 7 Days)
132
+ </h1>
133
+ """
134
+
135
+ for category, models in models_data.items():
136
+ if not models:
137
+ continue
138
+
139
+ # Format category name
140
+ category_display = category.replace("-", " ").title()
141
+
142
+ html_content += f"""
143
+ <div style="margin-bottom: 40px; border: 2px solid #f0f0f0; border-radius: 10px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white;">
144
+ <h2 style="margin-top: 0; text-align: center; font-size: 24px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">
145
+ πŸ† {category_display}
146
+ </h2>
147
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 20px; margin-top: 20px;">
148
+ """
149
+
150
+ for i, model in enumerate(models[:3], 1):
151
+ medal = "πŸ₯‡" if i == 1 else "πŸ₯ˆ" if i == 2 else "πŸ₯‰"
152
+
153
+ # Format the numbers and date
154
+ likes_formatted = format_number(model['likes'])
155
+ downloads_formatted = format_number(model['downloads'])
156
+ date_formatted = format_date(model['updated'])
157
+ author = model['name'].split("/")[0]
158
+ model_name = model['name'].split("/")[-1]
159
+ model_normal_name = model_name.replace("-", " ").title()
160
+ # Create YouTube search URL
161
+ youtube_search_query = urllib.parse.quote(f"{model_normal_name} {author} AI")
162
+ youtube_url = f"https://www.youtube.com/results?search_query={youtube_search_query}"
163
+
164
+ html_content += f"""
165
+ <div style="background: rgba(255,255,255,0.95); color: #333; padding: 20px; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); display: flex; flex-direction: column; height: 100%;">
166
+ <div style="display: flex; align-items: center; margin-bottom: 15px;">
167
+ <span style="font-size: 24px; margin-right: 10px;">{medal}</span>
168
+ <h3 style="margin: 0; font-size: 16px; color: #2d3748;">#{i}</h3>
169
+ </div>
170
+
171
+ <h4 style="margin: 0 0 15px 0; font-size: 18px; color: #2b6cb0; word-break: break-word; line-height: 1.3; flex-grow: 1;">
172
+ <a href="{model['url']}" target="_blank" style="text-decoration: none; color: #2b6cb0;">
173
+ {model['name']}
174
+ </a>
175
+ </h4>
176
+
177
+ <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 15px;">
178
+ <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;">
179
+ <div style="font-size: 16px; margin-bottom: 2px;">❀️</div>
180
+ <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Likes</div>
181
+ <div style="background: #e53e3e; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;">
182
+ {likes_formatted}
183
+ </div>
184
+ </div>
185
+
186
+ <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;">
187
+ <div style="font-size: 16px; margin-bottom: 2px;">πŸ“₯</div>
188
+ <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Downloads</div>
189
+ <div style="background: #38a169; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;">
190
+ {downloads_formatted}
191
+ </div>
192
+ </div>
193
+
194
+ <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;">
195
+ <div style="font-size: 16px; margin-bottom: 2px;">πŸ•’</div>
196
+ <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Updated</div>
197
+ <div style="background: #3182ce; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;">
198
+ {date_formatted}
199
+ </div>
200
+ </div>
201
+ </div>
202
+
203
+ <div style="display: flex; gap: 8px; margin-top: auto;">
204
+ <a href="{model['url']}" target="_blank" style="flex: 1; text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 8px 12px; border-radius: 6px; text-decoration: none; font-size: 12px; font-weight: bold; transition: all 0.2s;">
205
+ πŸ€— View Model
206
+ </a>
207
+ <a href="{youtube_url}" target="_blank" style="flex: 1; text-align: center; background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%); color: white; padding: 8px 12px; border-radius: 6px; text-decoration: none; font-size: 12px; font-weight: bold; transition: all 0.2s;">
208
+ πŸ“Ί Find on YouTube
209
+ </a>
210
+ </div>
211
+ </div>
212
+ """
213
+
214
+ html_content += """
215
+ </div>
216
+ </div>
217
+ """
218
+
219
+ html_content += f"""
220
+ <div style="text-align: center; margin-top: 30px; padding: 20px; background-color: #f8f9fa; border-radius: 10px;">
221
+ <p style="color: #6c757d; font-style: italic; margin-bottom: 10px;">
222
+ πŸ“Š Data fetched from Hugging Face API β€’ Updated: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} UTC
223
+ </p>
224
+ <p style="color: #6c757d; font-size: 12px; margin: 0;">
225
+ Rankings based on likes received in the last 7 days β€’ Found {len(models_data)} categories with active models
226
+ </p>
227
+ </div>
228
+ </div>
229
+ """
230
+
231
+ return html_content
232
+
233
+ def refresh_models():
234
+ """
235
+ Refresh and get the latest model data
236
+ """
237
+ models_data = get_hf_models_by_category()
238
+ formatted_display = format_model_display(models_data)
239
+ return formatted_display
240
+
241
+ # Create Gradio interface
242
+ def create_interface():
243
+ with gr.Blocks(
244
+ title="πŸ€— Top HF Models by Category",
245
+ theme=gr.themes.Soft(),
246
+ css="""
247
+ .gradio-container {
248
+ max-width: 1400px !important;
249
+ }
250
+ .gr-button {
251
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
252
+ border: none !important;
253
+ color: white !important;
254
+ }
255
+ """
256
+ ) as demo:
257
+
258
+ gr.Markdown("""
259
+ # πŸ€— Hugging Face Model Explorer
260
+
261
+ Discover the most popular models across different categories on Hugging Face!
262
+ This space shows the **top 3 models** in each category ranked by **likes received in the last 7 days**.
263
+
264
+ Click the refresh button to get the latest rankings!
265
+ """)
266
+
267
+ with gr.Row():
268
+ refresh_btn = gr.Button(
269
+ "πŸ”„ Refresh Rankings",
270
+ variant="primary",
271
+ size="lg"
272
+ )
273
+
274
+ with gr.Row():
275
+ gr.Markdown("""
276
+ **🎯 What you'll see:**
277
+ - ❀️ **Likes**: Community appreciation in the last 7 days
278
+ - πŸ“₯ **Downloads**: Total download count (all-time)
279
+ - πŸ•’ **Updated**: Last modification date
280
+ - πŸ€— **View Model**: Direct link to model page
281
+ - πŸ“Ί **Find on YouTube**: Search for tutorials and demos
282
+ """)
283
+
284
+ output_html = gr.HTML(
285
+ value=refresh_models(), # Load initial data
286
+ label="Top Models by Category"
287
+ )
288
+
289
+ refresh_btn.click(
290
+ fn=refresh_models,
291
+ outputs=output_html
292
+ )
293
+
294
+ gr.Markdown("""
295
+ ---
296
+ ### ℹ️ About This Space
297
+
298
+ - **Data Source**: Hugging Face Models API (`/api/models`)
299
+ - **Ranking Metric**: Likes received in the last 7 days (`sort=likes7d`)
300
+ - **Categories**: All major model types (text, image, audio, multimodal, etc.)
301
+ - **Update Frequency**: Real-time (when you click refresh)
302
+
303
+ **Note**: Only categories with available models are displayed. Some specialized categories might not appear if no models are currently trending.
304
+
305
+ πŸš€ **Pro tip**: Use the YouTube button to find tutorials, demos, and implementation guides for each model!
306
+ """)
307
+
308
+ return demo
309
+
310
+ # Launch the application
311
+ if __name__ == "__main__":
312
+ demo = create_interface()
313
+ demo.launch(
314
+ server_name="0.0.0.0", # For Hugging Face Spaces
315
+ server_port=7860, # Standard port for HF Spaces
316
+ share=False,
317
+ debug=False
318
+ )