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__) # Replace with your actual dataset name DATASET_NAME = "ysharma/gradio-hackathon-registrations-2025" COUNTER = """ Hackathon Countdown

Registrations and Submissions are available until June 10 UTC EOD

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 new_row = { "timestamp": registration_data["timestamp"], "full_name": registration_data["personal_info"]["full_name"], "email": registration_data["personal_info"]["email"], "github_username": registration_data["personal_info"]["github_username"] or "", "hf_username": registration_data["personal_info"]["hf_username"], "track_interest": str(registration_data["participation"]["track_interest"]), "participation_type": registration_data["participation"]["participation_type"], "teammates": registration_data["teammates"] or "", "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, github_username, hf_username, track_interest, participation_type, teammates, commitment, api_credits_ack, 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 track_interest: return "❌ Error: Please select at least one track of interest" if not participation_type: return "❌ Error: Please select your participation type" if not commitment: return "❌ Error: Please confirm your commitment to participate" if not api_credits_ack: return "❌ Error: Please acknowledge the API credits terms" # 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(), # Normalize email "github_username": github_username.strip() if github_username else "", "hf_username": hf_username.strip() }, "participation": { "track_interest": track_interest, "participation_type": participation_type, }, "teammates": teammates.strip() if teammates else None, "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 an email prior to the Hackathon start dates containing information about the API credits, provided you meet the required criteria. 🔑 API and Compute credits will be distributed well before the Hackathon starting date and time. 💬 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` for updates and support during the event: https://discord.gg/Qe3jMKVczR 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") 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") # Create the Gradio interface (same as before, but using safe functions) with gr.Blocks(title="Gradio Agents & MCP Hackathon 2025",) as demo: # Header gr.Markdown(""" # 🤖 Gradio Agents & MCP Hackathon 2025 Registration 🚀 **Updates: TOTAL SIGNUPS: 4K+. Signups are available all week till June 8. Emails containing credits are being sent regularly. You won't receive any email on successful registrations.**
**Join our [Discord Community](https://discord.gg/Qe3jMKVczR) channel `agents-mcp-hackathon` for active support during the hackathon.** **📅 Event Dates:** June 2-10, 2025 | **🏆 Prizes: $16,500 in cash prizes** **💻 Location:** Online & Global |
**🎁 Bonus: FREE Credits** for participants* from our sponsors worth **$1 MILLION++** - $250 of GPU/CPU Compute credits **TO EVERY PARTICIPANT** in the Hackathon from [Modal Labs](https://modal.com/) - $25 of API credits **TO EVERY PARTICIPANT** in the Hackathon from [Huggingface](https://huggingface.co/) - $25 of API credits to each of the first 3300 participants from [Nebius](https://nebius.com/) - $25 of API credits to each of the first 1000 participants from [Anthropic](https://www.anthropic.com/) - $25 of API credits to each of the first 1000 participants from [OpenAI](https://openai.com/) - $15 of API credits to each of the first 1000 participants from [Hyperbolic Labs](https://hyperbolic.xyz/) - $25 of API credits to each of the first 500 participants from [MistralAI](https://mistral.ai/) - $25 of API credits to each of the first 250 participants from [Sambanova.AI](https://sambanova.ai/) *API and GPU/CPU Compute credits are provided to support hackathon participation and will be distributed based on registration verification. """) gr.HTML(COUNTER) gr.Markdown("---") 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 ) github_username = gr.Textbox( label="GitHub Username", placeholder="Your GitHub username (helps us verify your developer status)", max_lines=1 ) hf_username = gr.Textbox( label="Hugging Face Username *", placeholder="Required for organization access and submissions", max_lines=1 ) # Hackathon Participation Section gr.Markdown("## 2. Hackathon Participation") track_interest = gr.CheckboxGroup( label="Which track interests you most? *", choices=[ "Track 1: MCP Server Implementation", "Track 2: Custom Agent Components", "Track 3: Agentic Demo Showcase", ] ) participation_type = gr.Radio( label="Participation Type *", choices=[ "Individual participant", "Joining as a team", ] ) teammates = gr.Textbox( label="If you have a team, list your teammates' emails separated by commas", placeholder="List names and emails of your team members (optional)", lines=3 ) # Commitment & Verification Section gr.Markdown("## 3. Commitment & Verification") commitment = gr.Checkbox( label="Hackathon Commitment *", info="I commit to actively participate and submit a project by June 8, 2025", ) api_credits_ack = gr.Checkbox( label="API Credits Acknowledgment *", info="I understand that API 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." ) # Additional Information Section gr.Markdown("## 4. 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 ) # Submit button submit_btn = gr.Button("🚀 Register for Hackathon", variant="primary", size="lg") # 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 submit_btn.click( fn=lambda *args: (gr.Button("⏳ Processing Registration...", interactive=False, variant="secondary"), ""), inputs=[ full_name, email, github_username, hf_username, track_interest, participation_type, teammates, commitment, api_credits_ack, project_description, ], outputs=[submit_btn, output], queue=False ).then( fn=handle_registration_with_state, inputs=[ full_name, email, github_username, hf_username, track_interest, participation_type, teammates, commitment, api_credits_ack, project_description, ], outputs=[output, submit_btn], queue=True ) if __name__ == "__main__": demo.launch(allowed_paths=["."])