ReallyFloppyPenguin commited on
Commit
04c7efc
·
verified ·
1 Parent(s): 92b6995

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +375 -0
app.py ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import os
4
+ import pandas as pd
5
+ import json
6
+ from typing import List, Dict, Optional
7
+ import time
8
+ from datetime import datetime
9
+
10
+ class HuggingFaceModelExplorer:
11
+ def __init__(self):
12
+ self.hf_token = os.getenv("HF_TOKEN")
13
+ if not self.hf_token:
14
+ raise ValueError("HF_TOKEN environment variable is required")
15
+
16
+ self.headers = {"Authorization": f"Bearer {self.hf_token}"}
17
+ self.base_url = "https://huggingface.co/api"
18
+
19
+ def get_inference_endpoints(self) -> List[Dict]:
20
+ """Fetch all available inference endpoints"""
21
+ try:
22
+ # Get serverless inference API models
23
+ url = f"{self.base_url}/models"
24
+ params = {
25
+ "pipeline_tag": None,
26
+ "library": None,
27
+ "sort": "downloads",
28
+ "direction": -1,
29
+ "limit": 100,
30
+ "full": True,
31
+ "config": True
32
+ }
33
+
34
+ response = requests.get(url, headers=self.headers, params=params)
35
+ response.raise_for_status()
36
+
37
+ models = response.json()
38
+
39
+ # Filter models that support inference API
40
+ inference_models = []
41
+ for model in models:
42
+ if self._supports_inference_api(model):
43
+ inference_models.append({
44
+ "id": model.get("id", "Unknown"),
45
+ "pipeline_tag": model.get("pipeline_tag", "Unknown"),
46
+ "library_name": model.get("library_name", "Unknown"),
47
+ "downloads": model.get("downloads", 0),
48
+ "likes": model.get("likes", 0),
49
+ "created_at": model.get("createdAt", "Unknown"),
50
+ "updated_at": model.get("lastModified", "Unknown"),
51
+ "tags": model.get("tags", []),
52
+ "inference_status": self._check_inference_status(model.get("id"))
53
+ })
54
+
55
+ return inference_models
56
+
57
+ except Exception as e:
58
+ print(f"Error fetching inference endpoints: {e}")
59
+ return []
60
+
61
+ def _supports_inference_api(self, model: Dict) -> bool:
62
+ """Check if a model supports the inference API"""
63
+ # Models with these pipeline tags typically support inference API
64
+ supported_pipelines = {
65
+ "text-generation", "text2text-generation", "fill-mask",
66
+ "token-classification", "question-answering", "summarization",
67
+ "translation", "text-classification", "conversational",
68
+ "image-classification", "object-detection", "image-segmentation",
69
+ "text-to-image", "image-to-text", "automatic-speech-recognition",
70
+ "audio-classification", "voice-activity-detection",
71
+ "depth-estimation", "feature-extraction"
72
+ }
73
+
74
+ pipeline_tag = model.get("pipeline_tag")
75
+ return pipeline_tag in supported_pipelines
76
+
77
+ def _check_inference_status(self, model_id: str) -> str:
78
+ """Check if inference API is currently available for a model"""
79
+ try:
80
+ url = f"https://api-inference.huggingface.co/models/{model_id}"
81
+ response = requests.get(url, headers=self.headers, timeout=5)
82
+
83
+ if response.status_code == 200:
84
+ return "✅ Available"
85
+ elif response.status_code == 503:
86
+ return "🔄 Loading"
87
+ else:
88
+ return "❌ Unavailable"
89
+ except:
90
+ return "❓ Unknown"
91
+
92
+ def get_dedicated_endpoints(self) -> List[Dict]:
93
+ """Fetch dedicated inference endpoints (requires paid plan)"""
94
+ try:
95
+ url = f"{self.base_url}/inference-endpoints"
96
+ response = requests.get(url, headers=self.headers)
97
+
98
+ if response.status_code == 200:
99
+ endpoints = response.json()
100
+ return [{
101
+ "name": ep.get("name", "Unknown"),
102
+ "model_id": ep.get("model", {}).get("repository", "Unknown"),
103
+ "status": ep.get("status", "Unknown"),
104
+ "created_at": ep.get("created_at", "Unknown"),
105
+ "updated_at": ep.get("updated_at", "Unknown"),
106
+ "compute": ep.get("compute", {}),
107
+ "url": ep.get("url", "")
108
+ } for ep in endpoints]
109
+ else:
110
+ return []
111
+ except Exception as e:
112
+ print(f"Error fetching dedicated endpoints: {e}")
113
+ return []
114
+
115
+ def test_model_inference(self, model_id: str, input_text: str = "Hello, how are you?") -> Dict:
116
+ """Test inference on a specific model"""
117
+ try:
118
+ url = f"https://api-inference.huggingface.co/models/{model_id}"
119
+
120
+ # Determine appropriate payload based on model type
121
+ payload = {"inputs": input_text}
122
+
123
+ response = requests.post(url, headers=self.headers, json=payload, timeout=30)
124
+
125
+ if response.status_code == 200:
126
+ result = response.json()
127
+ return {
128
+ "status": "success",
129
+ "result": result,
130
+ "response_time": response.elapsed.total_seconds()
131
+ }
132
+ else:
133
+ return {
134
+ "status": "error",
135
+ "error": f"HTTP {response.status_code}: {response.text}",
136
+ "response_time": response.elapsed.total_seconds()
137
+ }
138
+
139
+ except Exception as e:
140
+ return {
141
+ "status": "error",
142
+ "error": str(e),
143
+ "response_time": None
144
+ }
145
+
146
+ def create_interface():
147
+ explorer = HuggingFaceModelExplorer()
148
+
149
+ def refresh_serverless_models():
150
+ """Refresh the list of serverless inference models"""
151
+ models = explorer.get_inference_endpoints()
152
+ if not models:
153
+ return "No models found or error occurred"
154
+
155
+ df = pd.DataFrame(models)
156
+ return df
157
+
158
+ def refresh_dedicated_endpoints():
159
+ """Refresh the list of dedicated inference endpoints"""
160
+ endpoints = explorer.get_dedicated_endpoints()
161
+ if not endpoints:
162
+ return "No dedicated endpoints found (requires paid plan) or error occurred"
163
+
164
+ df = pd.DataFrame(endpoints)
165
+ return df
166
+
167
+ def test_model(model_id: str, test_input: str):
168
+ """Test inference on a selected model"""
169
+ if not model_id.strip():
170
+ return "Please enter a model ID"
171
+
172
+ if not test_input.strip():
173
+ test_input = "Hello, how are you today?"
174
+
175
+ result = explorer.test_model_inference(model_id, test_input)
176
+
177
+ if result["status"] == "success":
178
+ return f"""
179
+ **Model:** {model_id}
180
+ **Status:** ✅ Success
181
+ **Response Time:** {result['response_time']:.2f}s
182
+
183
+ **Result:**
184
+ ```json
185
+ {json.dumps(result['result'], indent=2)}
186
+ ```
187
+ """
188
+ else:
189
+ return f"""
190
+ **Model:** {model_id}
191
+ **Status:** ❌ Error
192
+ **Response Time:** {result['response_time']:.2f}s if result['response_time'] else 'N/A'}
193
+
194
+ **Error:**
195
+ {result['error']}
196
+ """
197
+
198
+ def search_models(query: str, pipeline_filter: str = "All"):
199
+ """Search models by name or tags"""
200
+ models = explorer.get_inference_endpoints()
201
+
202
+ if query:
203
+ models = [m for m in models if query.lower() in m['id'].lower() or
204
+ any(query.lower() in tag.lower() for tag in m['tags'])]
205
+
206
+ if pipeline_filter != "All":
207
+ models = [m for m in models if m['pipeline_tag'] == pipeline_filter]
208
+
209
+ if not models:
210
+ return "No models found matching your criteria"
211
+
212
+ df = pd.DataFrame(models)
213
+ return df
214
+
215
+ # Create Gradio interface
216
+ with gr.Blocks(title="🤗 HuggingFace Inference API Explorer", theme=gr.themes.Soft()) as demo:
217
+ gr.Markdown("""
218
+ # 🤗 HuggingFace Inference API Explorer
219
+
220
+ Explore all available models on HuggingFace Inference API providers!
221
+
222
+ This space showcases:
223
+ - **Serverless Inference API**: Free tier models available through HF's inference API
224
+ - **Dedicated Inference Endpoints**: Private endpoints (requires paid plan)
225
+ - **Model Testing**: Test any model directly from the interface
226
+
227
+ ---
228
+ """)
229
+
230
+ with gr.Tabs():
231
+ # Serverless Models Tab
232
+ with gr.TabItem("🚀 Serverless Models"):
233
+ gr.Markdown("### Available Serverless Inference API Models")
234
+
235
+ with gr.Row():
236
+ search_query = gr.Textbox(
237
+ placeholder="Search models by name or tags...",
238
+ label="Search Query"
239
+ )
240
+ pipeline_filter = gr.Dropdown(
241
+ choices=["All", "text-generation", "text-classification", "question-answering",
242
+ "summarization", "translation", "image-classification", "text-to-image"],
243
+ value="All",
244
+ label="Pipeline Filter"
245
+ )
246
+ search_btn = gr.Button("🔍 Search Models")
247
+
248
+ refresh_serverless_btn = gr.Button("🔄 Refresh All Models", variant="primary")
249
+ serverless_output = gr.Dataframe(
250
+ headers=["Model ID", "Pipeline", "Library", "Downloads", "Likes", "Status"],
251
+ label="Serverless Models"
252
+ )
253
+
254
+ search_btn.click(
255
+ search_models,
256
+ inputs=[search_query, pipeline_filter],
257
+ outputs=serverless_output
258
+ )
259
+ refresh_serverless_btn.click(refresh_serverless_models, outputs=serverless_output)
260
+
261
+ # Dedicated Endpoints Tab
262
+ with gr.TabItem("🏢 Dedicated Endpoints"):
263
+ gr.Markdown("### Dedicated Inference Endpoints (Requires Paid Plan)")
264
+
265
+ refresh_dedicated_btn = gr.Button("🔄 Refresh Dedicated Endpoints", variant="primary")
266
+ dedicated_output = gr.Dataframe(
267
+ headers=["Name", "Model ID", "Status", "Created", "URL"],
268
+ label="Dedicated Endpoints"
269
+ )
270
+
271
+ refresh_dedicated_btn.click(refresh_dedicated_endpoints, outputs=dedicated_output)
272
+
273
+ # Model Testing Tab
274
+ with gr.TabItem("🧪 Test Models"):
275
+ gr.Markdown("### Test Model Inference")
276
+
277
+ with gr.Row():
278
+ model_id_input = gr.Textbox(
279
+ placeholder="e.g., microsoft/DialoGPT-medium",
280
+ label="Model ID",
281
+ info="Enter the full model ID from HuggingFace"
282
+ )
283
+ test_input = gr.Textbox(
284
+ placeholder="Hello, how are you today?",
285
+ label="Test Input",
286
+ info="Text to send to the model"
287
+ )
288
+
289
+ test_btn = gr.Button("🚀 Test Model", variant="primary")
290
+ test_output = gr.Markdown(label="Test Results")
291
+
292
+ test_btn.click(
293
+ test_model,
294
+ inputs=[model_id_input, test_input],
295
+ outputs=test_output
296
+ )
297
+
298
+ # Statistics Tab
299
+ with gr.TabItem("📊 Statistics"):
300
+ gr.Markdown("### Inference API Statistics")
301
+
302
+ stats_btn = gr.Button("📈 Generate Statistics", variant="primary")
303
+
304
+ def generate_stats():
305
+ models = explorer.get_inference_endpoints()
306
+ if not models:
307
+ return "No data available"
308
+
309
+ total_models = len(models)
310
+ pipelines = {}
311
+ libraries = {}
312
+ statuses = {}
313
+
314
+ for model in models:
315
+ # Count pipelines
316
+ pipeline = model['pipeline_tag']
317
+ pipelines[pipeline] = pipelines.get(pipeline, 0) + 1
318
+
319
+ # Count libraries
320
+ library = model['library_name']
321
+ libraries[library] = libraries.get(library, 0) + 1
322
+
323
+ # Count statuses
324
+ status = model['inference_status']
325
+ statuses[status] = statuses.get(status, 0) + 1
326
+
327
+ # Sort by count
328
+ top_pipelines = sorted(pipelines.items(), key=lambda x: x[1], reverse=True)[:10]
329
+ top_libraries = sorted(libraries.items(), key=lambda x: x[1], reverse=True)[:10]
330
+
331
+ stats_text = f"""
332
+ ## 📊 HuggingFace Inference API Statistics
333
+
334
+ **Total Models Available:** {total_models}
335
+
336
+ ### Top Pipeline Tags:
337
+ {chr(10).join([f"- **{pipeline}**: {count} models" for pipeline, count in top_pipelines])}
338
+
339
+ ### Top Libraries:
340
+ {chr(10).join([f"- **{library}**: {count} models" for library, count in top_libraries])}
341
+
342
+ ### Inference Status Distribution:
343
+ {chr(10).join([f"- **{status}**: {count} models" for status, count in statuses.items()])}
344
+
345
+ *Last updated: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}*
346
+ """
347
+ return stats_text
348
+
349
+ stats_output = gr.Markdown()
350
+ stats_btn.click(generate_stats, outputs=stats_output)
351
+
352
+ # Footer
353
+ gr.Markdown("""
354
+ ---
355
+
356
+ **Note:** This space requires a HuggingFace token set as the `HF_TOKEN` environment variable.
357
+
358
+ - 🌟 Star this space if you find it useful!
359
+ - 🐛 Report issues on the Community tab
360
+ - 📚 Learn more about [HuggingFace Inference API](https://huggingface.co/docs/api-inference/index)
361
+ """)
362
+
363
+ return demo
364
+
365
+ if __name__ == "__main__":
366
+ try:
367
+ demo = create_interface()
368
+ demo.launch(
369
+ server_name="0.0.0.0",
370
+ server_port=7860,
371
+ share=False
372
+ )
373
+ except ValueError as e:
374
+ print(f"Error: {e}")
375
+ print("Please set the HF_TOKEN environment variable with your HuggingFace token.")