Spaces:
Sleeping
Sleeping
| # GRADIO HF SPACE | |
| import gradio as gr | |
| import requests | |
| import pandas as pd | |
| from datetime import datetime, timedelta | |
| import urllib.parse | |
| def get_hf_models_by_category(): | |
| """ | |
| Fetch top 3 models from each Hugging Face category ranked by likes7d | |
| """ | |
| # Hugging Face API endpoint | |
| api_url = "https://huggingface.co/api/models" | |
| # Common model categories on Hugging Face | |
| categories = [ | |
| "text-generation", | |
| "text-classification", | |
| "token-classification", | |
| "question-answering", | |
| "fill-mask", | |
| "summarization", | |
| "translation", | |
| "text2text-generation", | |
| "image-classification", | |
| "object-detection", | |
| "image-segmentation", | |
| "text-to-image", | |
| "image-to-text", | |
| "automatic-speech-recognition", | |
| "audio-classification", | |
| "text-to-speech", | |
| "audio-to-audio", | |
| "voice-activity-detection", | |
| "depth-estimation", | |
| "image-feature-extraction", | |
| "other" | |
| ] | |
| results = {} | |
| for category in categories: | |
| try: | |
| # Fetch models for this category, sorted by likes in the last 7 days | |
| params = { | |
| "pipeline_tag": category, | |
| "sort": "likes7d", | |
| "direction": -1, | |
| "limit": 3, | |
| "full": True # Get full model info including downloads | |
| } | |
| response = requests.get(api_url, params=params, timeout=10) | |
| if response.status_code == 200: | |
| models = response.json() | |
| category_models = [] | |
| for model in models: | |
| # Try different field names for model ID | |
| model_id = model.get("id") or model.get("modelId") or model.get("_id", "Unknown") | |
| # Get likes (might be in different fields) | |
| likes = (model.get("likes") or | |
| model.get("likesRecent") or | |
| model.get("likes7d") or 0) | |
| # Get downloads (different possible field names) | |
| downloads = (model.get("downloads") or | |
| model.get("downloadsAllTime") or | |
| model.get("downloads_all_time") or | |
| model.get("downloads_last_month", 0)) | |
| # Get last modified date | |
| last_modified = (model.get("lastModified") or | |
| model.get("last_modified") or | |
| model.get("createdAt") or | |
| model.get("updatedAt") or "Unknown") | |
| model_info = { | |
| "name": model_id, | |
| "likes": likes, | |
| "downloads": downloads, | |
| "updated": last_modified, | |
| "url": f"https://huggingface.co/{model_id}" | |
| } | |
| category_models.append(model_info) | |
| if category_models: # Only add if we found models | |
| results[category] = category_models | |
| except Exception as e: | |
| print(f"Error fetching {category}: {str(e)}") | |
| continue | |
| return results | |
| def format_number(num): | |
| """Format large numbers in a readable way""" | |
| if num >= 1000000: | |
| return f"{num/1000000:.1f}M" | |
| elif num >= 1000: | |
| return f"{num/1000:.1f}k" | |
| else: | |
| return str(num) | |
| def format_date(date_str): | |
| """Format date string to be more readable""" | |
| if date_str == "Unknown" or not date_str: | |
| return "Unknown" | |
| try: | |
| # Parse the ISO date string and format it | |
| if "T" in date_str: | |
| date_obj = datetime.fromisoformat(date_str.replace("Z", "+00:00")) | |
| return date_obj.strftime("%Y-%m-%d") | |
| else: | |
| return date_str[:10] # Just take the date part | |
| except: | |
| return "Unknown" | |
| def format_model_display(models_data): | |
| """ | |
| Format the models data into a nice display format | |
| """ | |
| if not models_data: | |
| return "No models found or API unavailable." | |
| html_content = """ | |
| <div style="font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto;"> | |
| <h1 style="text-align: center; color: #ff6b6b; margin-bottom: 30px;"> | |
| π€ Top 3 Hugging Face Models by Category (Last 7 Days) | |
| </h1> | |
| """ | |
| for category, models in models_data.items(): | |
| if not models: | |
| continue | |
| # Format category name | |
| category_display = category.replace("-", " ").title() | |
| html_content += f""" | |
| <div style="margin-bottom: 40px; border: 2px solid #f0f0f0; border-radius: 10px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white;"> | |
| <h2 style="margin-top: 0; text-align: center; font-size: 24px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);"> | |
| π {category_display} | |
| </h2> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 20px; margin-top: 20px;"> | |
| """ | |
| for i, model in enumerate(models[:3], 1): | |
| medal = "π₯" if i == 1 else "π₯" if i == 2 else "π₯" | |
| # Format the numbers and date | |
| likes_formatted = format_number(model['likes']) | |
| downloads_formatted = format_number(model['downloads']) | |
| date_formatted = format_date(model['updated']) | |
| author = model['name'].split("/")[0] | |
| model_name = model['name'].split("/")[-1] | |
| model_normal_name = model_name.replace("-", " ").title() | |
| # Create YouTube search URL | |
| youtube_search_query = urllib.parse.quote(f"{model_normal_name} {author} AI") | |
| youtube_url = f"https://www.youtube.com/results?search_query={youtube_search_query}" | |
| html_content += f""" | |
| <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%;"> | |
| <div style="display: flex; align-items: center; margin-bottom: 15px;"> | |
| <span style="font-size: 24px; margin-right: 10px;">{medal}</span> | |
| <h3 style="margin: 0; font-size: 16px; color: #2d3748;">#{i}</h3> | |
| </div> | |
| <h4 style="margin: 0 0 15px 0; font-size: 18px; color: #2b6cb0; word-break: break-word; line-height: 1.3; flex-grow: 1;"> | |
| <a href="{model['url']}" target="_blank" style="text-decoration: none; color: #2b6cb0;"> | |
| {model['name']} | |
| </a> | |
| </h4> | |
| <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 15px;"> | |
| <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;"> | |
| <div style="font-size: 16px; margin-bottom: 2px;">β€οΈ</div> | |
| <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Likes</div> | |
| <div style="background: #e53e3e; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;"> | |
| {likes_formatted} | |
| </div> | |
| </div> | |
| <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;"> | |
| <div style="font-size: 16px; margin-bottom: 2px;">π₯</div> | |
| <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Downloads</div> | |
| <div style="background: #38a169; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;"> | |
| {downloads_formatted} | |
| </div> | |
| </div> | |
| <div style="text-align: center; padding: 8px; background: #f7fafc; border-radius: 6px;"> | |
| <div style="font-size: 16px; margin-bottom: 2px;">π</div> | |
| <div style="font-size: 12px; color: #4a5568; font-weight: bold;">Updated</div> | |
| <div style="background: #3182ce; color: white; padding: 2px 6px; border-radius: 12px; font-size: 11px; margin-top: 4px; display: inline-block;"> | |
| {date_formatted} | |
| </div> | |
| </div> | |
| </div> | |
| <div style="display: flex; gap: 8px; margin-top: auto;"> | |
| <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;"> | |
| π€ View Model | |
| </a> | |
| <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;"> | |
| πΊ Find on YouTube | |
| </a> | |
| </div> | |
| </div> | |
| """ | |
| html_content += """ | |
| </div> | |
| </div> | |
| """ | |
| html_content += f""" | |
| <div style="text-align: center; margin-top: 30px; padding: 20px; background-color: #f8f9fa; border-radius: 10px;"> | |
| <p style="color: #6c757d; font-style: italic; margin-bottom: 10px;"> | |
| π Data fetched from Hugging Face API β’ Updated: {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} UTC | |
| </p> | |
| <p style="color: #6c757d; font-size: 12px; margin: 0;"> | |
| Rankings based on likes received in the last 7 days β’ Found {len(models_data)} categories with active models | |
| </p> | |
| </div> | |
| </div> | |
| """ | |
| return html_content | |
| def refresh_models(): | |
| """ | |
| Refresh and get the latest model data | |
| """ | |
| models_data = get_hf_models_by_category() | |
| formatted_display = format_model_display(models_data) | |
| return formatted_display | |
| # Create Gradio interface | |
| def create_interface(): | |
| with gr.Blocks( | |
| title="π€ Top HF Models by Category", | |
| theme=gr.themes.Soft(), | |
| css=""" | |
| .gradio-container { | |
| max-width: 1400px !important; | |
| } | |
| .gr-button { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; | |
| border: none !important; | |
| color: white !important; | |
| } | |
| """ | |
| ) as demo: | |
| gr.Markdown(""" | |
| # π€ Hugging Face Model Explorer | |
| Discover the most popular models across different categories on Hugging Face! | |
| This space shows the **top 3 models** in each category ranked by **likes received in the last 7 days**. | |
| Click the refresh button to get the latest rankings! | |
| """) | |
| with gr.Row(): | |
| refresh_btn = gr.Button( | |
| "π Refresh Rankings", | |
| variant="primary", | |
| size="lg" | |
| ) | |
| with gr.Row(): | |
| gr.Markdown(""" | |
| **π― What you'll see:** | |
| - β€οΈ **Likes**: Community appreciation in the last 7 days | |
| - π₯ **Downloads**: Total download count (all-time) | |
| - π **Updated**: Last modification date | |
| - π€ **View Model**: Direct link to model page | |
| - πΊ **Find on YouTube**: Search for tutorials and demos | |
| """) | |
| output_html = gr.HTML( | |
| value=refresh_models(), # Load initial data | |
| label="Top Models by Category" | |
| ) | |
| refresh_btn.click( | |
| fn=refresh_models, | |
| outputs=output_html | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| ### βΉοΈ About This Space | |
| - **Data Source**: Hugging Face Models API (`/api/models`) | |
| - **Ranking Metric**: Likes received in the last 7 days (`sort=likes7d`) | |
| - **Categories**: All major model types (text, image, audio, multimodal, etc.) | |
| - **Update Frequency**: Real-time (when you click refresh) | |
| **Note**: Only categories with available models are displayed. Some specialized categories might not appear if no models are currently trending. | |
| π **Pro tip**: Use the YouTube button to find tutorials, demos, and implementation guides for each model! | |
| """) | |
| return demo | |
| # Launch the application | |
| if __name__ == "__main__": | |
| demo = create_interface() | |
| demo.launch( | |
| server_name="0.0.0.0", # For Hugging Face Spaces | |
| server_port=7860, # Standard port for HF Spaces | |
| share=False, | |
| debug=False | |
| ) |