import gradio as gr import json from datetime import datetime from datasets import Dataset from huggingface_hub import login, HfApi import pandas as pd import os import time import tempfile import logging # Setup logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Authenticate with Hugging Face HF_TOKEN = os.environ.get("HF_TOKEN") if HF_TOKEN: login(token=HF_TOKEN) logger.info("✅ Authenticated with Hugging Face") else: logger.warning("⚠️ HF_TOKEN not found - running without authentication") # Replace with your actual dataset name for Winter 2025 DATASET_NAME = "ysharma/gradio-hackathon-registrations-winter-2025" COUNTER = """ Hackathon Countdown

Countdown to the Global Event Has Begun. Registrations are now open!

00
Days
00
Hours
00
Minutes
00
Seconds
""" def safe_add_to_dataset(registration_data, max_retries=5, retry_delay=3): """ Safely add new registration data with bulletproof error handling NEVER creates new datasets - only adds to existing ones """ try: logger.info("Starting new registration process") # Create new row with updated fields new_row = { "timestamp": registration_data["timestamp"], "full_name": registration_data["personal_info"]["full_name"], "email": registration_data["personal_info"]["email"], "hf_username": registration_data["personal_info"]["hf_username"], "gradio_usage": registration_data["personal_info"]["gradio_usage"], "track_interest": str(registration_data["participation"]["track_interest"]), "previous_participation": registration_data["participation"]["previous_participation"], "experience_level": registration_data["participation"]["experience_level"], "how_heard": registration_data["participation"]["how_heard"], "project_description": registration_data["additional"]["project_description"] or "", } logger.info("Created new row data") # Multi-attempt loading with different strategies existing_df = None load_successful = False for attempt in range(max_retries): logger.info(f"Loading attempt {attempt + 1}/{max_retries}") try: # Strategy 1: Direct parquet file access (most reliable) api = HfApi() files = api.list_repo_files(DATASET_NAME, repo_type="dataset") parquet_files = [f for f in files if f.endswith('.parquet') and 'train' in f] if parquet_files: logger.info(f"Found parquet file: {parquet_files[0]}") # Download to temporary location with tempfile.TemporaryDirectory() as temp_dir: parquet_file = api.hf_hub_download( repo_id=DATASET_NAME, filename=parquet_files[0], repo_type="dataset", cache_dir=temp_dir, force_download=True ) existing_df = pd.read_parquet(parquet_file) logger.info(f"Successfully loaded {len(existing_df)} existing rows") load_successful = True break else: logger.warning("No parquet files found") except Exception as load_error: logger.warning(f"Attempt {attempt + 1} failed: {str(load_error)[:100]}") if attempt < max_retries - 1: logger.info(f"Waiting {retry_delay} seconds before retry...") time.sleep(retry_delay) continue # CRITICAL SAFETY CHECK: Never proceed without existing data if not load_successful or existing_df is None: error_msg = "🚨 CRITICAL SAFETY ERROR: Could not load existing dataset after multiple attempts." logger.error(error_msg) logger.error("🚨 REFUSING to proceed to prevent data loss!") logger.error("🚨 Please check dataset manually or contact administrators.") return False, ( "❌ Registration temporarily unavailable due to technical issues. " "Please try again in a few minutes. If the problem persists, contact support." ) # Check for duplicates duplicate_check = existing_df[ (existing_df['email'].str.lower() == new_row['email'].lower()) | (existing_df['hf_username'].str.lower() == new_row['hf_username'].lower()) ] if len(duplicate_check) > 0: logger.warning("Duplicate registration attempt detected") return False, "❌ Error: This email or Hugging Face username is already registered." # Add new row safely combined_df = pd.concat([existing_df, pd.DataFrame([new_row])], ignore_index=True) logger.info(f"Combined data now has {len(combined_df)} rows (was {len(existing_df)})") # Create timestamped backup before upload backup_timestamp = int(time.time()) try: # Convert to Dataset and upload logger.info("Converting to HuggingFace Dataset format...") updated_dataset = Dataset.from_pandas(combined_df) # Create backup first backup_name = f"{DATASET_NAME}-auto-backup-{backup_timestamp}" logger.info(f"Creating backup: {backup_name}") updated_dataset.push_to_hub(backup_name, private=True) logger.info("Pushing to main dataset...") updated_dataset.push_to_hub(DATASET_NAME, private=True) logger.info("✅ Successfully saved new registration") logger.info(f"Total rows in dataset: {len(combined_df)}") # Quick verification time.sleep(2) try: verify_files = api.list_repo_files(DATASET_NAME, repo_type="dataset") logger.info("✅ Upload verification: Files updated successfully") except: logger.warning("⚠️ Could not verify upload (this may be normal)") return True, "Registration successful!" except Exception as upload_error: error_msg = str(upload_error).lower() if any(indicator in error_msg for indicator in ['rate limit', '429', 'too many requests']): logger.warning("🚨 Rate limit hit - registration system temporarily busy") return False, "⏳ Registration temporarily unavailable due to high server load. Please try again in 10-15 minutes." else: logger.error(f"Upload failed: {upload_error}") return False, f"❌ Registration failed during upload: {str(upload_error)}" except Exception as e: logger.error(f"❌ Unexpected error in registration: {e}") import traceback traceback.print_exc() return False, f"❌ Registration failed: {str(e)}" def submit_registration(full_name, email, hf_username, gradio_usage, track_interest, previous_participation, experience_level, how_heard, acknowledgment, project_description): """Process the registration form submission with enhanced validation""" # Enhanced validation if not full_name or not full_name.strip(): return "❌ Error: Please enter your full name" if not email or not email.strip(): return "❌ Error: Please enter your email address" if not hf_username or not hf_username.strip(): return "❌ Error: Please enter your Hugging Face username" if not gradio_usage: return "❌ Error: Please select how you're currently using Gradio" if not track_interest: return "❌ Error: Please select at least one track of interest" if not previous_participation: return "❌ Error: Please select your hackathon experience" if not experience_level: return "❌ Error: Please select your experience level" if not how_heard: return "❌ Error: Please select how you heard about this hackathon" if not acknowledgment: return "❌ Error: Please confirm your acknowledgment to participate" # Email format validation import re email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' if not re.match(email_pattern, email.strip()): return "❌ Error: Please enter a valid email address" # Process the registration data registration_data = { "timestamp": datetime.now().isoformat(), "personal_info": { "full_name": full_name.strip(), "email": email.strip().lower(), "hf_username": hf_username.strip(), "gradio_usage": gradio_usage, }, "participation": { "track_interest": track_interest, "previous_participation": previous_participation, "experience_level": experience_level, "how_heard": how_heard, }, "additional": { "project_description": project_description.strip() if project_description else None, } } # Save to Hugging Face dataset with bulletproof error handling success, message = safe_add_to_dataset(registration_data) if not success: return f"❌ Registration failed: {message}" return f"""✅ Registration Successful! Thank you, {full_name}! Your registration has been received and saved.
📧 You will receive information about API credits as we finalize sponsor partnerships.
🔑 API and Compute credits will be distributed before or during the Hackathon starting date.
💬 Be sure to **join the Huggingface organization** for regular updates on the hackathon and **to submit your entries**. Join our Discord community channel `agents-mcp-hackathon-winter25🏆` for updates and support during the event: https://discord.gg/YgswRqxQ **See you at the hackathon! 🚀**""" # Health check function def check_dataset_health(): """Check if the dataset is accessible and healthy""" try: api = HfApi() files = api.list_repo_files(DATASET_NAME, repo_type="dataset") parquet_files = [f for f in files if f.endswith('.parquet')] if parquet_files: logger.info(f"✅ Dataset health check passed - found {len(parquet_files)} parquet files") return True else: logger.warning("⚠️ Dataset health check: No parquet files found") return False except Exception as e: logger.error(f"❌ Dataset health check failed: {e}") return False # Initialize with health check logger.info("🚀 Starting Gradio Hackathon Registration System - Winter 2025") logger.info(f"📊 Dataset: {DATASET_NAME}") if check_dataset_health(): logger.info("✅ System ready - dataset is healthy") else: logger.warning("⚠️ System starting with dataset health warnings") # Custom CSS for gradient theme custom_css = """ .gradio-container { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } .header-gradient { background: linear-gradient(135deg, #0a0a0a 0%, #FF7A00 35%, #4A90E2 70%, #ffffff 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* Gradient Submit Button Styling */ #gradient-submit-btn { background: linear-gradient(135deg, #0a0a0a 0%, #FF7A00 35%, #4A90E2 70%, #ffffff 100%) !important; border: none !important; color: white !important; font-weight: 600 !important; font-size: 18px !important; padding: 16px 32px !important; border-radius: 12px !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important; transition: all 0.3s ease !important; text-transform: none !important; } #gradient-submit-btn:hover { transform: translateY(-2px) !important; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25) !important; } #gradient-submit-btn:active { transform: translateY(0px) !important; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2) !important; } /* Disabled state for the button */ #gradient-submit-btn:disabled { opacity: 0.6 !important; cursor: not-allowed !important; transform: none !important; } """ # Create the Gradio interface with gr.Blocks(title="Gradio Agents & MCP Hackathon - Winter 2025", css=custom_css, theme="ocean") as demo: # Header gr.Markdown(""" # 🤖 Gradio Agents & MCP Hackathon - Winter 2025 Registration 🚀 **Join our [Discord Community](https://discord.gg/YgswRqxQ) channel `agents-mcp-hackathon-winter25🏆` for active support during the hackathon.** **📅 Event Dates:** November 14-30, 2025 (17 days, 3 weekends) | **🏆 Prizes: $15,000+ USD in cash prizes** | **💻 Location:** Online & Global **🎁 FREE API & Compute Credits** (Details announced soon): - API credits from major AI providers - Access to latest and strongest LLMs - Compute resources for building your projects **The definitive Agents & MCP event is back!** OpenAI, Microsoft, Google DeepMind, and numerous startups have already adopted MCP. Join the community that launched the MCP developer movement. Participate and stand a chance to learn the latest AI technologies and also Win BIG! """) gr.HTML(COUNTER) gr.Markdown("---") with gr.Row(): with gr.Column(): # Personal Information Section gr.Markdown("## 1. Personal Information") full_name = gr.Textbox( label="Full Name *", placeholder="Your full name as you'd like it on certificates", max_lines=1 ) email = gr.Textbox( label="Email Address *", placeholder="Primary contact email (we'll send important updates here)", max_lines=1 ) hf_username = gr.Textbox( label="Hugging Face Username *", placeholder="Required for organization access and submissions", max_lines=1 ) # NEW: Gradio Usage Question gradio_usage = gr.Radio( label="How are you currently using Gradio? *", choices=[ "Professional work - My company uses Gradio", "Personal projects - Building side projects", "Academic/Research - University or research work", "Learning - New to Gradio, want to learn", "Not using yet - Interested to start" ], info="Helps us understand our community better" ) with gr.Column(): # Hackathon Participation Section gr.Markdown("## 2. Hackathon Participation") track_interest = gr.CheckboxGroup( label="Which track interests you most? *", choices=[ "Track 1: MCP Tools & Servers", "Track 2: Agentic Applications", ] ) # NEW: Previous participation previous_participation = gr.Radio( label="Hackathon experience *", choices=[ "I participated in June 2025 Agents & MCP Hackathon", "I've done other AI hackathons before", "This is my first AI hackathon" ] ) # NEW: Experience level experience_level = gr.Radio( label="Your experience with AI/Agents development *", choices=[ "Beginner - New to AI development", "Intermediate - Some AI projects", "Advanced - Regular AI developer", "Expert - Professional AI engineer" ] ) # NEW: How they heard about it how_heard = gr.Dropdown( label="How did you hear about this hackathon? *", choices=[ "Hugging Face email/newsletter", "Twitter/X", "LinkedIn", "Discord", "From a colleague/friend", "YouTube", "Reddit", "Sponsor announcement", "I participated in June 2025", "Other" ] ) with gr.Row(): with gr.Column(): # Additional Information Section gr.Markdown("## 3. Additional Information") project_description = gr.Textbox( label="What type of project are you most excited to build?", placeholder="Brief description of your project idea or what interests you most", lines=3 ) with gr.Column(): # Acknowledgment Section gr.Markdown("## 4. Acknowledgment") acknowledgment = gr.Checkbox( label="Acknowledgment *", info="""I commit to actively participate and submit a project by November 30, 2025. I understand that API/compute credits are provided to support hackathon participation and should be used for building my hackathon project. I commit to using these credits responsibly during the event period.""", ) # Submit button submit_btn = gr.Button("🚀 Register for Hackathon", variant="primary", size="lg", elem_id="gradient-submit-btn") # Output output = gr.Markdown() # Enhanced submit function def handle_registration_with_state(*args): try: result = submit_registration(*args) return result, gr.Button("🚀 Register for Hackathon", interactive=True, variant="primary") except Exception as e: logger.error(f"Registration handling error: {e}") return f"❌ An unexpected error occurred: {str(e)}", gr.Button("🚀 Register for Hackathon", interactive=True, variant="primary") # Click event with updated inputs submit_btn.click( fn=lambda *args: (gr.Button("⏳ Processing Registration...", interactive=False, variant="secondary"), ""), inputs=[ full_name, email, hf_username, gradio_usage, track_interest, previous_participation, experience_level, how_heard, acknowledgment, project_description, ], outputs=[submit_btn, output], queue=False ).then( fn=handle_registration_with_state, inputs=[ full_name, email, hf_username, gradio_usage, track_interest, previous_participation, experience_level, how_heard, acknowledgment, project_description, ], outputs=[output, submit_btn], queue=True ) # Footer gr.Markdown(""" **Questions?** Join Huggingface [Discord](https://discord.gg/DVzRsYXy) or email: gradio-team@huggingface.co """) if __name__ == "__main__": demo.launch(allowed_paths=["."])