|  | 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 | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logging.basicConfig(level=logging.INFO) | 
					
						
						|  | logger = logging.getLogger(__name__) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | DATASET_NAME = "ysharma/gradio-hackathon-registrations-winter-2025" | 
					
						
						|  |  | 
					
						
						|  | COUNTER = """ | 
					
						
						|  | <!DOCTYPE html> | 
					
						
						|  | <html lang="en"> | 
					
						
						|  | <head> | 
					
						
						|  | <meta charset="UTF-8"> | 
					
						
						|  | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 
					
						
						|  | <title>Hackathon Countdown</title> | 
					
						
						|  | <style> | 
					
						
						|  | * { | 
					
						
						|  | margin: 0; | 
					
						
						|  | padding: 0; | 
					
						
						|  | box-sizing: border-box; | 
					
						
						|  | } | 
					
						
						|  | body { | 
					
						
						|  | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | 
					
						
						|  | margin: 0; | 
					
						
						|  | padding: 20px; | 
					
						
						|  | } | 
					
						
						|  | .countdown-container { | 
					
						
						|  | background: linear-gradient(135deg, #0a0a0a 0%, #FF7A00 35%, #4A90E2 70%, #ffffff 100%); | 
					
						
						|  | border-radius: 20px; | 
					
						
						|  | padding: 40px; | 
					
						
						|  | box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); | 
					
						
						|  | text-align: center; | 
					
						
						|  | max-width: 600px; | 
					
						
						|  | width: 100%; | 
					
						
						|  | margin: 0 auto; | 
					
						
						|  | display: block; | 
					
						
						|  | } | 
					
						
						|  | .title { | 
					
						
						|  | font-size: 28px; | 
					
						
						|  | font-weight: 600; | 
					
						
						|  | color: white; | 
					
						
						|  | margin-bottom: 40px; | 
					
						
						|  | } | 
					
						
						|  | .countdown { | 
					
						
						|  | display: flex; | 
					
						
						|  | justify-content: space-around; | 
					
						
						|  | align-items: center; | 
					
						
						|  | gap: 20px; | 
					
						
						|  | flex-wrap: wrap; | 
					
						
						|  | } | 
					
						
						|  | .time-unit { | 
					
						
						|  | display: flex; | 
					
						
						|  | flex-direction: column; | 
					
						
						|  | align-items: center; | 
					
						
						|  | min-width: 100px; | 
					
						
						|  | } | 
					
						
						|  | .circle { | 
					
						
						|  | position: relative; | 
					
						
						|  | width: 100px; | 
					
						
						|  | height: 100px; | 
					
						
						|  | margin-bottom: 15px; | 
					
						
						|  | } | 
					
						
						|  | .circle svg { | 
					
						
						|  | width: 100%; | 
					
						
						|  | height: 100%; | 
					
						
						|  | transform: rotate(-90deg); | 
					
						
						|  | } | 
					
						
						|  | .circle-bg { | 
					
						
						|  | fill: none; | 
					
						
						|  | stroke: rgba(0, 0, 0, 0.3); | 
					
						
						|  | stroke-width: 6; | 
					
						
						|  | } | 
					
						
						|  | .circle-progress { | 
					
						
						|  | fill: none; | 
					
						
						|  | stroke: black; | 
					
						
						|  | stroke-width: 6; | 
					
						
						|  | stroke-linecap: round; | 
					
						
						|  | stroke-dasharray: 283; | 
					
						
						|  | stroke-dashoffset: 283; | 
					
						
						|  | transition: stroke-dashoffset 0.3s ease; | 
					
						
						|  | } | 
					
						
						|  | .number { | 
					
						
						|  | position: absolute; | 
					
						
						|  | top: 50%; | 
					
						
						|  | left: 50%; | 
					
						
						|  | transform: translate(-50%, -50%); | 
					
						
						|  | font-size: 32px; | 
					
						
						|  | font-weight: 700; | 
					
						
						|  | color: white; | 
					
						
						|  | font-family: 'Courier New', monospace; | 
					
						
						|  | } | 
					
						
						|  | .label { | 
					
						
						|  | font-size: 16px; | 
					
						
						|  | font-weight: 500; | 
					
						
						|  | color: white; | 
					
						
						|  | text-transform: uppercase; | 
					
						
						|  | letter-spacing: 1px; | 
					
						
						|  | } | 
					
						
						|  | @media (max-width: 480px) { | 
					
						
						|  | .countdown { | 
					
						
						|  | gap: 15px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .circle { | 
					
						
						|  | width: 80px; | 
					
						
						|  | height: 80px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .number { | 
					
						
						|  | font-size: 24px; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | .title { | 
					
						
						|  | font-size: 22px; | 
					
						
						|  | margin-bottom: 30px; | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  | </style> | 
					
						
						|  | </head> | 
					
						
						|  | <body> | 
					
						
						|  | <div class="countdown-container"> | 
					
						
						|  | <h1 class="title">Countdown to the Global Event Has Begun. Registrations are now open!</h1> | 
					
						
						|  | <div class="countdown"> | 
					
						
						|  | <div class="time-unit"> | 
					
						
						|  | <div class="circle"> | 
					
						
						|  | <svg> | 
					
						
						|  | <circle class="circle-bg" cx="50" cy="50" r="45"></circle> | 
					
						
						|  | <circle class="circle-progress" cx="50" cy="50" r="45" id="days-progress"></circle> | 
					
						
						|  | </svg> | 
					
						
						|  | <div class="number" id="days">00</div> | 
					
						
						|  | </div> | 
					
						
						|  | <div class="label">Days</div> | 
					
						
						|  | </div> | 
					
						
						|  |  | 
					
						
						|  | <div class="time-unit"> | 
					
						
						|  | <div class="circle"> | 
					
						
						|  | <svg> | 
					
						
						|  | <circle class="circle-bg" cx="50" cy="50" r="45"></circle> | 
					
						
						|  | <circle class="circle-progress" cx="50" cy="50" r="45" id="hours-progress"></circle> | 
					
						
						|  | </svg> | 
					
						
						|  | <div class="number" id="hours">00</div> | 
					
						
						|  | </div> | 
					
						
						|  | <div class="label">Hours</div> | 
					
						
						|  | </div> | 
					
						
						|  |  | 
					
						
						|  | <div class="time-unit"> | 
					
						
						|  | <div class="circle"> | 
					
						
						|  | <svg> | 
					
						
						|  | <circle class="circle-bg" cx="50" cy="50" r="45"></circle> | 
					
						
						|  | <circle class="circle-progress" cx="50" cy="50" r="45" id="minutes-progress"></circle> | 
					
						
						|  | </svg> | 
					
						
						|  | <div class="number" id="minutes">00</div> | 
					
						
						|  | </div> | 
					
						
						|  | <div class="label">Minutes</div> | 
					
						
						|  | </div> | 
					
						
						|  |  | 
					
						
						|  | <div class="time-unit"> | 
					
						
						|  | <div class="circle"> | 
					
						
						|  | <svg> | 
					
						
						|  | <circle class="circle-bg" cx="50" cy="50" r="45"></circle> | 
					
						
						|  | <circle class="circle-progress" cx="50" cy="50" r="45" id="seconds-progress"></circle> | 
					
						
						|  | </svg> | 
					
						
						|  | <div class="number" id="seconds">00</div> | 
					
						
						|  | </div> | 
					
						
						|  | <div class="label">Seconds</div> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | </div> | 
					
						
						|  | <script> | 
					
						
						|  | // Set target date to November 30, 2025, 11:59 PM UTC | 
					
						
						|  | const targetDate = new Date(Date.UTC(2025, 10, 13, 23, 59, 59)); // Month is 0-indexed (10 = November) | 
					
						
						|  |  | 
					
						
						|  | function updateCountdown() { | 
					
						
						|  | const now = new Date(); | 
					
						
						|  | const difference = targetDate.getTime() - now.getTime(); | 
					
						
						|  |  | 
					
						
						|  | if (difference > 0) { | 
					
						
						|  | const days = Math.floor(difference / (1000 * 60 * 60 * 24)); | 
					
						
						|  | const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); | 
					
						
						|  | const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60)); | 
					
						
						|  | const seconds = Math.floor((difference % (1000 * 60)) / 1000); | 
					
						
						|  |  | 
					
						
						|  | // Update numbers | 
					
						
						|  | document.getElementById('days').textContent = days.toString().padStart(2, '0'); | 
					
						
						|  | document.getElementById('hours').textContent = hours.toString().padStart(2, '0'); | 
					
						
						|  | document.getElementById('minutes').textContent = minutes.toString().padStart(2, '0'); | 
					
						
						|  | document.getElementById('seconds').textContent = seconds.toString().padStart(2, '0'); | 
					
						
						|  |  | 
					
						
						|  | // Update progress circles | 
					
						
						|  | updateProgress('days-progress', days, 365); | 
					
						
						|  | updateProgress('hours-progress', hours, 24); | 
					
						
						|  | updateProgress('minutes-progress', minutes, 60); | 
					
						
						|  | updateProgress('seconds-progress', seconds, 60); | 
					
						
						|  | } else { | 
					
						
						|  | // Countdown has ended | 
					
						
						|  | document.getElementById('days').textContent = '00'; | 
					
						
						|  | document.getElementById('hours').textContent = '00'; | 
					
						
						|  | document.getElementById('minutes').textContent = '00'; | 
					
						
						|  | document.getElementById('seconds').textContent = '00'; | 
					
						
						|  |  | 
					
						
						|  | // Reset all progress circles | 
					
						
						|  | updateProgress('days-progress', 0, 365); | 
					
						
						|  | updateProgress('hours-progress', 0, 24); | 
					
						
						|  | updateProgress('minutes-progress', 0, 60); | 
					
						
						|  | updateProgress('seconds-progress', 0, 60); | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | function updateProgress(elementId, current, max) { | 
					
						
						|  | const circle = document.getElementById(elementId); | 
					
						
						|  | const circumference = 283; | 
					
						
						|  | const progress = (current / max) * circumference; | 
					
						
						|  | const offset = circumference - progress; | 
					
						
						|  | circle.style.strokeDashoffset = offset; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | // Update countdown immediately and then every second | 
					
						
						|  | updateCountdown(); | 
					
						
						|  | setInterval(updateCountdown, 1000); | 
					
						
						|  | </script> | 
					
						
						|  | </body> | 
					
						
						|  | </html> | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | 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") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | existing_df = None | 
					
						
						|  | load_successful = False | 
					
						
						|  |  | 
					
						
						|  | for attempt in range(max_retries): | 
					
						
						|  | logger.info(f"Loading attempt {attempt + 1}/{max_retries}") | 
					
						
						|  |  | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | 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]}") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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 | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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." | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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." | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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)})") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | backup_timestamp = int(time.time()) | 
					
						
						|  |  | 
					
						
						|  | try: | 
					
						
						|  |  | 
					
						
						|  | logger.info("Converting to HuggingFace Dataset format...") | 
					
						
						|  | updated_dataset = Dataset.from_pandas(combined_df) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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)}") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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""" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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, | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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.<br> | 
					
						
						|  | π§ You will receive information about API credits as we finalize sponsor partnerships.<br> | 
					
						
						|  | π API and Compute credits will be distributed before or during the Hackathon starting date.<br> | 
					
						
						|  | π¬ 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! π**""" | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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 | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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 = """ | 
					
						
						|  | .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; | 
					
						
						|  | } | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | with gr.Blocks(title="Gradio Agents & MCP Hackathon - Winter 2025", css=custom_css, theme="ocean") as demo: | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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.** | 
					
						
						|  | **NOTE: If the registration app says you are registered, then that information is correct and you don't need to send us anything else. NO CONFIRMATION EMAILS ARE SENT FROM OUR SIDE.** | 
					
						
						|  |  | 
					
						
						|  | **π
 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(): | 
					
						
						|  |  | 
					
						
						|  | 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 | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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(): | 
					
						
						|  |  | 
					
						
						|  | 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", | 
					
						
						|  | ] | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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" | 
					
						
						|  | ] | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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" | 
					
						
						|  | ] | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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(): | 
					
						
						|  |  | 
					
						
						|  | 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(): | 
					
						
						|  |  | 
					
						
						|  | 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_btn = gr.Button("π Register for Hackathon", variant="primary", size="lg", elem_id="gradient-submit-btn") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | output = gr.Markdown() | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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") | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | 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 | 
					
						
						|  | ) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | gr.Markdown(""" | 
					
						
						|  | **Questions?** Join Huggingface [Discord](https://discord.gg/fveShqytyh) or email: gradio-team@huggingface.co | 
					
						
						|  | """) | 
					
						
						|  |  | 
					
						
						|  | if __name__ == "__main__": | 
					
						
						|  | demo.launch(allowed_paths=["."]) |