Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import random | |
| def get_random_dataset(min_likes=None, max_likes=None, task=None, language=None): | |
| try: | |
| url = "https://huggingface.co/api/datasets" | |
| params = {"full": "true"} | |
| if task and task.strip(): | |
| params["filter"] = task.strip() | |
| response = requests.get(url, params=params, timeout=30) | |
| response.raise_for_status() | |
| datasets = response.json() | |
| if not datasets: | |
| return """ | |
| <div class='result-container empty-state'> | |
| <div class='empty-icon'> | |
| <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> | |
| <circle cx="12" cy="12" r="10"/> | |
| <path d="M12 6v6l4 2"/> | |
| </svg> | |
| </div> | |
| <h3>No Datasets Found</h3> | |
| <p>Unable to fetch datasets. Please try again.</p> | |
| </div> | |
| """ | |
| filtered = [] | |
| for ds in datasets: | |
| likes = ds.get("likes", 0) | |
| if min_likes is not None and min_likes > 0 and likes < min_likes: | |
| continue | |
| if max_likes is not None and max_likes > 0 and likes > max_likes: | |
| continue | |
| if language and language.strip(): | |
| langs = ds.get("cardData", {}).get("language", []) | |
| if isinstance(langs, str): | |
| langs = [langs] | |
| if language.strip() not in langs: | |
| continue | |
| filtered.append(ds) | |
| if not filtered: | |
| return """ | |
| <div class='result-container empty-state'> | |
| <div class='empty-icon'> | |
| <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> | |
| <circle cx="12" cy="12" r="10"/> | |
| <line x1="12" y1="8" x2="12" y2="12"/> | |
| <line x1="12" y1="16" x2="12.01" y2="16"/> | |
| </svg> | |
| </div> | |
| <h3>No Results Found</h3> | |
| <p>Try adjusting your filters or leave them empty for any dataset</p> | |
| </div> | |
| """ | |
| dataset = random.choice(filtered) | |
| dataset_id = dataset.get('id', 'Unknown') | |
| likes = dataset.get('likes', 0) | |
| downloads = dataset.get('downloads', 0) | |
| author = dataset.get('author', 'Unknown') | |
| description = dataset.get('cardData', {}).get('description', 'No description available') | |
| tags = dataset.get('tags', [])[:6] | |
| tags_html = ''.join([f"<span class='tag'>{tag}</span>" for tag in tags]) | |
| result = f""" | |
| <div class='result-container success-state' id='result-card'> | |
| <div class='result-header'> | |
| <h2 class='dataset-title'>{dataset_id}</h2> | |
| <p class='dataset-author'>by {author}</p> | |
| </div> | |
| <div class='stats-grid'> | |
| <div class='stat-card stat-likes'> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class='stat-icon'> | |
| <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/> | |
| </svg> | |
| <div class='stat-content'> | |
| <div class='stat-label'>Likes</div> | |
| <div class='stat-value'>{likes:,}</div> | |
| </div> | |
| </div> | |
| <div class='stat-card stat-downloads'> | |
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class='stat-icon'> | |
| <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/> | |
| <polyline points="7 10 12 15 17 10"/> | |
| <line x1="12" y1="15" x2="12" y2="3"/> | |
| </svg> | |
| <div class='stat-content'> | |
| <div class='stat-label'>Downloads</div> | |
| <div class='stat-value'>{downloads:,}</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class='info-section'> | |
| <div class='section-header'> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> | |
| <polyline points="14 2 14 8 20 8"/> | |
| <line x1="16" y1="13" x2="8" y2="13"/> | |
| <line x1="16" y1="17" x2="8" y2="17"/> | |
| <polyline points="10 9 9 9 8 9"/> | |
| </svg> | |
| <h3>Description</h3> | |
| </div> | |
| <p class='description-text'>{description[:450]}{'...' if len(description) > 450 else ''}</p> | |
| </div> | |
| {f'''<div class='info-section'> | |
| <div class='section-header'> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> | |
| <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"/> | |
| <line x1="7" y1="7" x2="7.01" y2="7"/> | |
| </svg> | |
| <h3>Tags</h3> | |
| </div> | |
| <div class='tags-container'>{tags_html}</div> | |
| </div>''' if tags else ''} | |
| <a href='https://huggingface.co/datasets/{dataset_id}' target='_blank' class='view-button'> | |
| <span>View on HuggingFace</span> | |
| <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"> | |
| <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/> | |
| <polyline points="15 3 21 3 21 9"/> | |
| <line x1="10" y1="14" x2="21" y2="3"/> | |
| </svg> | |
| </a> | |
| </div> | |
| """ | |
| return result | |
| except Exception as e: | |
| return f""" | |
| <div class='result-container error-state'> | |
| <div class='error-icon'> | |
| <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> | |
| <circle cx="12" cy="12" r="10"/> | |
| <line x1="15" y1="9" x2="9" y2="15"/> | |
| <line x1="9" y1="9" x2="15" y2="15"/> | |
| </svg> | |
| </div> | |
| <h3>Error</h3> | |
| <p>{str(e)}</p> | |
| </div> | |
| """ | |
| custom_css = """ | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); | |
| * { | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; | |
| } | |
| .gradio-container { | |
| max-width: 980px !important; | |
| margin: 0 auto !important; | |
| padding: 0 20px !important; | |
| } | |
| body { | |
| background: linear-gradient(180deg, #F8FAFC 0%, #F1F5F9 100%); | |
| } | |
| .header-section { | |
| text-align: center; | |
| padding: 72px 32px 56px; | |
| background: linear-gradient(135deg, #0F172A 0%, #1E293B 50%, #334155 100%); | |
| border-radius: 24px; | |
| margin: 40px 0; | |
| position: relative; | |
| overflow: hidden; | |
| box-shadow: 0 20px 60px rgba(15, 23, 42, 0.4); | |
| } | |
| .header-section::before { | |
| content: ''; | |
| position: absolute; | |
| top: -50%; | |
| left: -50%; | |
| width: 200%; | |
| height: 200%; | |
| background: radial-gradient(circle, rgba(59, 130, 246, 0.15) 0%, transparent 70%); | |
| animation: pulse 8s ease-in-out infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { transform: translate(0, 0) scale(1); } | |
| 50% { transform: translate(10px, 10px) scale(1.1); } | |
| } | |
| .main-title { | |
| color: white; | |
| font-size: 52px; | |
| font-weight: 800; | |
| margin: 0 0 16px 0; | |
| letter-spacing: -1.5px; | |
| position: relative; | |
| z-index: 1; | |
| text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3); | |
| } | |
| .main-subtitle { | |
| color: rgba(255, 255, 255, 0.9); | |
| font-size: 18px; | |
| margin: 0; | |
| font-weight: 500; | |
| position: relative; | |
| z-index: 1; | |
| letter-spacing: 0.2px; | |
| } | |
| .filter-container { | |
| background: white; | |
| padding: 40px; | |
| border-radius: 20px; | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.02); | |
| margin-bottom: 28px; | |
| border: 1px solid #E2E8F0; | |
| } | |
| .filter-label { | |
| color: #0F172A; | |
| font-size: 18px; | |
| font-weight: 700; | |
| margin-bottom: 28px; | |
| display: block; | |
| letter-spacing: -0.3px; | |
| } | |
| label { | |
| color: #334155 !important; | |
| font-size: 14px !important; | |
| font-weight: 600 !important; | |
| margin-bottom: 10px !important; | |
| letter-spacing: 0.2px !important; | |
| } | |
| input[type="number"], input[type="text"] { | |
| border: 2px solid #E2E8F0 !important; | |
| border-radius: 12px !important; | |
| padding: 14px 16px !important; | |
| font-size: 15px !important; | |
| transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1) !important; | |
| background: #F8FAFC !important; | |
| font-weight: 500 !important; | |
| } | |
| input[type="number"]:hover, input[type="text"]:hover { | |
| background: white !important; | |
| border-color: #CBD5E1 !important; | |
| } | |
| input[type="number"]:focus, input[type="text"]:focus { | |
| border-color: #3B82F6 !important; | |
| box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1) !important; | |
| outline: none !important; | |
| background: white !important; | |
| } | |
| button.primary { | |
| background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%) !important; | |
| border: none !important; | |
| color: white !important; | |
| font-size: 17px !important; | |
| font-weight: 700 !important; | |
| padding: 18px 48px !important; | |
| border-radius: 14px !important; | |
| cursor: pointer !important; | |
| transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important; | |
| box-shadow: 0 8px 24px rgba(15, 23, 42, 0.35) !important; | |
| width: 100% !important; | |
| margin-top: 12px !important; | |
| letter-spacing: 0.3px !important; | |
| } | |
| button.primary:hover { | |
| transform: translateY(-3px) !important; | |
| box-shadow: 0 12px 32px rgba(15, 23, 42, 0.45) !important; | |
| background: linear-gradient(135deg, #1E293B 0%, #334155 100%) !important; | |
| } | |
| button.primary:active { | |
| transform: translateY(-1px) !important; | |
| } | |
| .result-container { | |
| background: white; | |
| border-radius: 20px; | |
| padding: 48px; | |
| margin-top: 28px; | |
| border: 1px solid #E2E8F0; | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04), 0 1px 3px rgba(0, 0, 0, 0.02); | |
| } | |
| .empty-state, .error-state { | |
| text-align: center; | |
| padding: 80px 40px; | |
| } | |
| .empty-icon, .error-icon { | |
| color: #94A3B8; | |
| margin-bottom: 24px; | |
| display: flex; | |
| justify-content: center; | |
| opacity: 0.7; | |
| } | |
| .empty-state h3, .error-state h3 { | |
| color: #0F172A; | |
| font-size: 24px; | |
| font-weight: 700; | |
| margin: 0 0 12px 0; | |
| letter-spacing: -0.5px; | |
| } | |
| .empty-state p, .error-state p { | |
| color: #64748B; | |
| font-size: 16px; | |
| margin: 0; | |
| font-weight: 500; | |
| } | |
| .success-state { | |
| animation: slideIn 0.5s cubic-bezier(0.16, 1, 0.3, 1); | |
| } | |
| @keyframes slideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(30px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .result-header { | |
| border-bottom: 2px solid #F1F5F9; | |
| padding-bottom: 28px; | |
| margin-bottom: 36px; | |
| } | |
| .dataset-title { | |
| color: #0F172A; | |
| margin: 0 0 10px 0; | |
| font-size: 32px; | |
| font-weight: 800; | |
| letter-spacing: -1px; | |
| line-height: 1.2; | |
| } | |
| .dataset-author { | |
| color: #64748B; | |
| margin: 0; | |
| font-size: 16px; | |
| font-weight: 600; | |
| } | |
| .stats-grid { | |
| display: grid; | |
| grid-template-columns: repeat(2, 1fr); | |
| gap: 20px; | |
| margin-bottom: 40px; | |
| } | |
| .stat-card { | |
| padding: 28px; | |
| border-radius: 16px; | |
| display: flex; | |
| align-items: center; | |
| gap: 20px; | |
| transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| border: 2px solid transparent; | |
| } | |
| .stat-card:hover { | |
| transform: translateY(-4px); | |
| box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); | |
| } | |
| .stat-likes { | |
| background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%); | |
| color: white; | |
| } | |
| .stat-likes:hover { | |
| border-color: #FCA5A5; | |
| } | |
| .stat-downloads { | |
| background: linear-gradient(135deg, #06B6D4 0%, #0891B2 100%); | |
| color: white; | |
| } | |
| .stat-downloads:hover { | |
| border-color: #67E8F9; | |
| } | |
| .stat-icon { | |
| flex-shrink: 0; | |
| opacity: 0.9; | |
| } | |
| .stat-content { | |
| flex: 1; | |
| } | |
| .stat-label { | |
| font-size: 13px; | |
| margin-bottom: 6px; | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 1px; | |
| opacity: 0.9; | |
| } | |
| .stat-value { | |
| font-size: 32px; | |
| font-weight: 800; | |
| letter-spacing: -1px; | |
| } | |
| .info-section { | |
| margin-bottom: 36px; | |
| } | |
| .section-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 16px; | |
| } | |
| .section-header svg { | |
| color: #3B82F6; | |
| flex-shrink: 0; | |
| } | |
| .section-header h3 { | |
| color: #0F172A; | |
| font-size: 18px; | |
| font-weight: 700; | |
| margin: 0; | |
| letter-spacing: -0.3px; | |
| } | |
| .description-text { | |
| color: #475569; | |
| line-height: 1.8; | |
| font-size: 15px; | |
| margin: 0; | |
| font-weight: 500; | |
| } | |
| .tags-container { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| } | |
| .tag { | |
| display: inline-block; | |
| background: linear-gradient(135deg, #DBEAFE 0%, #BFDBFE 100%); | |
| color: #1E40AF; | |
| padding: 8px 18px; | |
| border-radius: 24px; | |
| font-size: 13px; | |
| font-weight: 600; | |
| border: 2px solid #93C5FD; | |
| transition: all 0.2s ease; | |
| } | |
| .tag:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2); | |
| } | |
| .view-button { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 12px; | |
| background: linear-gradient(135deg, #0F172A 0%, #1E293B 100%); | |
| color: white; | |
| padding: 16px 36px; | |
| border-radius: 12px; | |
| text-decoration: none; | |
| font-weight: 700; | |
| font-size: 16px; | |
| transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| box-shadow: 0 6px 20px rgba(15, 23, 42, 0.3); | |
| letter-spacing: 0.2px; | |
| } | |
| .view-button:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 28px rgba(15, 23, 42, 0.4); | |
| text-decoration: none; | |
| background: linear-gradient(135deg, #1E293B 0%, #334155 100%); | |
| } | |
| .view-button svg { | |
| transition: transform 0.3s ease; | |
| } | |
| .view-button:hover svg { | |
| transform: translateX(3px); | |
| } | |
| .footer-note { | |
| text-align: center; | |
| color: #64748B; | |
| font-size: 15px; | |
| margin-top: 36px; | |
| padding: 24px; | |
| font-weight: 500; | |
| } | |
| """ | |
| js_code = """ | |
| function playSound(url) { | |
| const audio = new Audio(url); | |
| audio.volume = 0.3; | |
| audio.play().catch(e => console.log('Audio play failed:', e)); | |
| } | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const observer = new MutationObserver(function(mutations) { | |
| mutations.forEach(function(mutation) { | |
| if (mutation.addedNodes.length) { | |
| mutation.addedNodes.forEach(function(node) { | |
| if (node.classList && node.classList.contains('success-state')) { | |
| playSound('https://assets.mixkit.co/active_storage/sfx/2568/2568-preview.mp3'); | |
| } | |
| }); | |
| } | |
| }); | |
| }); | |
| setTimeout(() => { | |
| const outputDiv = document.querySelector('.gradio-html'); | |
| if (outputDiv) { | |
| observer.observe(outputDiv, { childList: true, subtree: true }); | |
| } | |
| }, 1000); | |
| }); | |
| """ | |
| with gr.Blocks(css=custom_css, title="Random Dataset Picker", theme=gr.themes.Soft(), js=js_code) as app: | |
| gr.HTML(""" | |
| <div class='header-section'> | |
| <h1 class='main-title'>Random Dataset Picker</h1> | |
| <p class='main-subtitle'>Discover datasets from HuggingFace with customisable filters</p> | |
| </div> | |
| """) | |
| with gr.Group(): | |
| gr.HTML("<div class='filter-container'><span class='filter-label'>Optional Filters</span></div>") | |
| with gr.Row(): | |
| min_likes = gr.Number( | |
| label="Minimum Likes", | |
| precision=0, | |
| container=True, | |
| scale=1, | |
| value=None | |
| ) | |
| max_likes = gr.Number( | |
| label="Maximum Likes", | |
| precision=0, | |
| container=True, | |
| scale=1, | |
| value=None | |
| ) | |
| with gr.Row(): | |
| task = gr.Textbox( | |
| label="Task Category", | |
| placeholder="e.g., text-classification, image-classification", | |
| container=True, | |
| scale=1, | |
| value="" | |
| ) | |
| language = gr.Textbox( | |
| label="Language Code", | |
| placeholder="e.g., en, fr, de, zh", | |
| container=True, | |
| scale=1, | |
| value="" | |
| ) | |
| btn = gr.Button("Generate Random Dataset", variant="primary", size="lg") | |
| output = gr.HTML( | |
| value="""<div class='result-container empty-state'> | |
| <div class='empty-icon'> | |
| <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"> | |
| <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/> | |
| <polyline points="3.27 6.96 12 12.01 20.73 6.96"/> | |
| <line x1="12" y1="22.08" x2="12" y2="12"/> | |
| </svg> | |
| </div> | |
| <h3>Ready to Explore</h3> | |
| <p>Click the button above to discover a genuinely random dataset</p> | |
| </div>""" | |
| ) | |
| btn.click( | |
| fn=get_random_dataset, | |
| inputs=[min_likes, max_likes, task, language], | |
| outputs=output | |
| ) | |
| gr.HTML("<div class='footer-note'>All filters are optional — Leave empty for genuinely random selection from all datasets</div>") | |
| app.launch() |