Spaces:
Sleeping
Sleeping
| # ============================================================================ | |
| # 📦 INCLUSIVEEDU - FULL VERSION WITH GRADIO + INTEGRATED API | |
| # Compatible with Hugging Face Spaces + External API Access | |
| # ============================================================================ | |
| import os | |
| import re | |
| import time | |
| import random | |
| from datetime import datetime | |
| from typing import List, Optional, Dict, Any | |
| from dataclasses import dataclass | |
| from pydantic import BaseModel | |
| # FastAPI imports | |
| try: | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| FASTAPI_AVAILABLE = True | |
| except ImportError: | |
| print("⚠️ FastAPI not available - API mode disabled") | |
| FASTAPI_AVAILABLE = False | |
| # Gradio imports | |
| try: | |
| import gradio as gr | |
| GRADIO_AVAILABLE = True | |
| except ImportError: | |
| print("⚠️ Gradio not available - Interface mode disabled") | |
| GRADIO_AVAILABLE = False | |
| # PyTorch imports (optional) | |
| try: | |
| import torch | |
| TORCH_AVAILABLE = True | |
| except ImportError: | |
| print("⚠️ PyTorch not available - using CPU simulation") | |
| TORCH_AVAILABLE = False | |
| # ============================================================================ | |
| # 1. DATA MODELS | |
| # ============================================================================ | |
| class ProfileInfo: | |
| """Profile information structure""" | |
| name: str | |
| description: str | |
| characteristics: List[str] | |
| best_for: List[str] | |
| # Pydantic models for API | |
| if FASTAPI_AVAILABLE: | |
| class ContentRequest(BaseModel): | |
| content: str | |
| profile: str = "visual_structure" | |
| interests: List[str] = [] | |
| complexity: str = "intermediate" | |
| format: str = "html" | |
| class ContentResponse(BaseModel): | |
| adapted_content: str | |
| gamification: Dict[str, Any] | |
| processing_time: float | |
| profile_used: str | |
| interests: List[str] | |
| complexity: str | |
| success: bool | |
| format: str | |
| timestamp: str | |
| raw_html: Optional[str] = None | |
| class HealthResponse(BaseModel): | |
| status: str | |
| ai_mode: str | |
| profiles_available: int | |
| timestamp: str | |
| version: str | |
| # ============================================================================ | |
| # 2. AI CONFIGURATION | |
| # ============================================================================ | |
| class AIConfig: | |
| """AI configuration and model management""" | |
| def __init__(self, safe_mode=True): | |
| self.simulation_mode = True # Always use simulation for safety | |
| self.safe_mode = safe_mode | |
| self.gemma3_model = None | |
| self.gemma3_tokenizer = None | |
| print("🎭 AI Config initialized in simulation mode") | |
| def generate_with_gemma3(self, prompt, max_length=400): | |
| """Generate content using simulation""" | |
| # Simulate AI processing time | |
| time.sleep(random.uniform(0.1, 0.3)) | |
| # Generate realistic adaptive content based on prompt | |
| if "visual structure" in prompt.lower(): | |
| return self._generate_visual_content(prompt) | |
| elif "hyperfocus" in prompt.lower() or "technical" in prompt.lower(): | |
| return self._generate_technical_content(prompt) | |
| elif "sensory" in prompt.lower() or "calm" in prompt.lower(): | |
| return self._generate_sensory_content(prompt) | |
| elif "interests" in prompt.lower() or "gamif" in prompt.lower(): | |
| return self._generate_interest_content(prompt) | |
| else: | |
| return self._generate_default_content(prompt) | |
| def _generate_visual_content(self, prompt): | |
| return """ | |
| ## 📚 Structured Learning Overview | |
| **Key Concepts** organized for clarity: | |
| ### 🎯 Main Topic | |
| Clear presentation of core information with visual hierarchy and organized structure. | |
| ### 📊 Important Details | |
| - **Primary points** highlighted for easy scanning | |
| - **Secondary information** properly categorized | |
| - **Visual elements** integrated for better comprehension | |
| ### ✅ Summary Points | |
| Essential takeaways presented in an accessible, scannable format with consistent organization. | |
| """ | |
| def _generate_technical_content(self, prompt): | |
| return """ | |
| ## 🔬 Technical Deep Dive | |
| **Comprehensive Analysis** with detailed specifications: | |
| ### 🔧 Technical Specifications | |
| Advanced implementation details with precise terminology and comprehensive coverage of all relevant aspects. | |
| ### 📈 Performance Metrics | |
| - **Efficiency ratings**: 94.7% optimization achieved | |
| - **Processing speed**: 2.3ms average response time | |
| - **Accuracy measures**: 99.2% precision in target scenarios | |
| - **Resource utilization**: Optimal memory allocation patterns | |
| ### 🎛️ Advanced Configuration | |
| Detailed parameter settings and fine-tuning options for specialized use cases and expert-level customization. | |
| """ | |
| def _generate_sensory_content(self, prompt): | |
| return """ | |
| ## 🌸 Gentle Learning Space | |
| **Comfortable Environment** designed for ease: | |
| ### 🕊️ Peaceful Introduction | |
| A calm and welcoming approach to the topic, presented at a comfortable pace. | |
| ### 💫 Gentle Progression | |
| Learning unfolds naturally: | |
| • Soft transitions between concepts | |
| • Comfortable information density | |
| • Regular pause points for reflection | |
| ### 🌱 Supportive Summary | |
| Key insights presented gently, with encouragement and positive reinforcement for continued learning. | |
| """ | |
| def _generate_interest_content(self, prompt): | |
| return """ | |
| ## 🎮 Interactive Learning Adventure | |
| **Engaging Experience** tailored to your interests: | |
| ### 🏆 Achievement Unlocked | |
| You've started an exciting learning journey! Connect this topic to your favorite interests for maximum engagement. | |
| ### 🎯 Challenge Mode | |
| - **Discovery Quest**: Explore core concepts | |
| - **Knowledge Builder**: Stack new information | |
| - **Mastery Challenge**: Apply what you've learned | |
| - **Bonus Round**: Find real-world connections | |
| ### ⭐ Power-Up Summary | |
| Level up your understanding with these key insights, designed to fuel your curiosity and passion for learning! | |
| """ | |
| def _generate_default_content(self, prompt): | |
| return """ | |
| ## 📖 Adaptive Learning Content | |
| **Personalized Approach** for your learning style: | |
| ### 🎓 Core Concepts | |
| Essential information presented clearly and effectively for optimal understanding. | |
| ### 🔍 Key Details | |
| Important points highlighted with appropriate depth and clarity for your learning needs. | |
| ### 📝 Learning Summary | |
| Comprehensive overview designed to reinforce understanding and support continued learning progress. | |
| """ | |
| # ============================================================================ | |
| # 3. PROFILE SYSTEM | |
| # ============================================================================ | |
| class NeuroProfileSystem: | |
| """Neurodiverse learning profile system""" | |
| def __init__(self): | |
| self.profiles = { | |
| "visual_structure": { | |
| "name": "🎯 Visual Structure", | |
| "description": "Clear organization, visual hierarchy, and structured elements", | |
| "colors": ["#2E86AB", "#A23B72", "#F18F01", "#C73E1D"], | |
| "characteristics": [ | |
| "Clear hierarchical organization with consistent structure", | |
| "Strategic use of visual elements and color coding", | |
| "Predictable navigation patterns and layout design", | |
| "Visual learning aids and interactive elements" | |
| ], | |
| "best_for": [ | |
| "Visual learners who need structure", | |
| "People who benefit from clear organization", | |
| "Those who prefer predictable layouts" | |
| ] | |
| }, | |
| "hyperfocus_directed": { | |
| "name": "🔬 Directed Hyperfocus", | |
| "description": "Deep technical focus, detailed information, and comprehensive analysis", | |
| "colors": ["#1B4332", "#2D6A4F", "#40916C", "#52B788"], | |
| "characteristics": [ | |
| "Detailed technical content with comprehensive data", | |
| "In-depth analysis and specialized terminology", | |
| "Extended exploration opportunities and resources", | |
| "Advanced tools and expert-level information" | |
| ], | |
| "best_for": [ | |
| "Deep technical learning", | |
| "Specialized interest areas", | |
| "Comprehensive analysis needs" | |
| ] | |
| }, | |
| "sensory_adaptation": { | |
| "name": "🌸 Sensory Adaptation", | |
| "description": "Calm environment, sensory awareness, and accessible design", | |
| "colors": ["#F7F3E9", "#E8DDBF", "#D4C5A9", "#C4A77D"], | |
| "characteristics": [ | |
| "Gentle presentation with calming visual design", | |
| "Reduced sensory load and minimal distractions", | |
| "Comfortable pacing with built-in break suggestions", | |
| "Accessibility features and customization options" | |
| ], | |
| "best_for": [ | |
| "Sensory-sensitive learners", | |
| "Those needing calm environments", | |
| "People requiring accessibility features" | |
| ] | |
| }, | |
| "special_interests": { | |
| "name": "🎮 Special Interests", | |
| "description": "Interest-based connections, gamification, and motivational design", | |
| "colors": ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4"], | |
| "characteristics": [ | |
| "Gamification elements with achievement systems", | |
| "Personal interest integration and connections", | |
| "Motivational design with clear goal progression", | |
| "Community features and collaborative opportunities" | |
| ], | |
| "best_for": [ | |
| "Interest-driven learning", | |
| "Motivation through gamification", | |
| "Achievement-focused students" | |
| ] | |
| } | |
| } | |
| def get_profile(self, profile_key): | |
| return self.profiles.get(profile_key, self.profiles["visual_structure"]) | |
| def get_profile_names(self): | |
| return [(profile["name"], key) for key, profile in self.profiles.items()] | |
| def get_all_profiles_info(self): | |
| """Get detailed info for all profiles""" | |
| profiles_info = {} | |
| for key, profile in self.profiles.items(): | |
| profiles_info[key] = ProfileInfo( | |
| name=profile["name"], | |
| description=profile["description"], | |
| characteristics=profile["characteristics"], | |
| best_for=profile.get("best_for", []) | |
| ) | |
| return profiles_info | |
| # ============================================================================ | |
| # 4. CONTENT ADAPTATION PIPELINE | |
| # ============================================================================ | |
| class ContentAdaptationPipeline: | |
| """Main content adaptation pipeline""" | |
| def __init__(self, ai_config): | |
| self.ai_config = ai_config | |
| self.profile_system = NeuroProfileSystem() | |
| self.adaptation_count = 0 | |
| self.session_start = datetime.now() | |
| def adapt_content(self, content, profile_key, interests, complexity="intermediate"): | |
| """Main content adaptation function""" | |
| start_time = time.time() | |
| try: | |
| # Validate inputs | |
| if not content or not content.strip(): | |
| raise ValueError("Content cannot be empty") | |
| # Get profile information | |
| profile = self.profile_system.get_profile(profile_key) | |
| # Create adaptation prompt | |
| prompt = self._create_adaptation_prompt(content, profile_key, interests, complexity) | |
| # Generate adapted content | |
| adapted_text = self.ai_config.generate_with_gemma3(prompt, max_length=400) | |
| # Create enhanced HTML output | |
| html_content = self._create_enhanced_html(adapted_text, profile, interests, complexity) | |
| # Generate gamification elements | |
| gamification = self._create_gamification_system(interests, profile_key) | |
| # Calculate metrics | |
| processing_time = time.time() - start_time | |
| self.adaptation_count += 1 | |
| return { | |
| "adapted_content": html_content, | |
| "gamification": gamification, | |
| "processing_time": processing_time, | |
| "profile_used": profile_key, | |
| "interests": interests, | |
| "complexity": complexity, | |
| "gemma3_used": not self.ai_config.simulation_mode, | |
| "adaptation_count": self.adaptation_count, | |
| "success": True, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| except Exception as e: | |
| print(f"❌ Adaptation error: {e}") | |
| return self._create_fallback_result(content, profile_key, str(e)) | |
| def _create_adaptation_prompt(self, content, profile_key, interests, complexity): | |
| """Create targeted adaptation prompt based on profile""" | |
| interest_text = ", ".join(interests) if interests else "general learning" | |
| prompts = { | |
| "visual_structure": f""" | |
| Adapt this educational content for VISUAL STRUCTURE learning: | |
| - Use clear headings and organization | |
| - Add visual elements and structured layout | |
| - Create scannable, hierarchical content | |
| - Include visual learning aids | |
| Content: {content} | |
| Interests: {interest_text} | |
| Complexity: {complexity} | |
| Visual structure adaptation: | |
| """, | |
| "hyperfocus_directed": f""" | |
| Adapt this educational content for DIRECTED HYPERFOCUS: | |
| - Add technical details and specifications | |
| - Include comprehensive analysis | |
| - Provide in-depth information | |
| - Use specialized terminology appropriately | |
| Content: {content} | |
| Interests: {interest_text} | |
| Complexity: {complexity} | |
| Technical deep-dive adaptation: | |
| """, | |
| "sensory_adaptation": f""" | |
| Adapt this educational content for SENSORY ADAPTATION: | |
| - Use gentle, calming language | |
| - Break into manageable sections | |
| - Reduce cognitive load | |
| - Create comfortable learning environment | |
| Content: {content} | |
| Interests: {interest_text} | |
| Complexity: {complexity} | |
| Sensory-friendly adaptation: | |
| """, | |
| "special_interests": f""" | |
| Adapt this educational content for SPECIAL INTERESTS: | |
| - Connect to personal interests: {interest_text} | |
| - Add gamification elements | |
| - Create motivational connections | |
| - Include achievement opportunities | |
| Content: {content} | |
| Interests: {interest_text} | |
| Complexity: {complexity} | |
| Interest-based gamified adaptation: | |
| """ | |
| } | |
| return prompts.get(profile_key, f"Adapt this content for {profile_key}: {content}") | |
| def _create_enhanced_html(self, content, profile, interests, complexity): | |
| """Create enhanced HTML with full styling and interactivity""" | |
| colors = profile["colors"] | |
| profile_name = profile["name"] | |
| # Complexity indicators | |
| complexity_colors = { | |
| "beginner": "#28a745", | |
| "intermediate": "#ffc107", | |
| "advanced": "#dc3545" | |
| } | |
| complexity_color = complexity_colors.get(complexity, "#6c757d") | |
| html = f""" | |
| <div style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, {colors[0]}08, {colors[1]}08); | |
| border-radius: 20px; padding: 30px; margin: 15px 0; | |
| box-shadow: 0 8px 32px rgba(0,0,0,0.1); border: 1px solid {colors[0]}20;"> | |
| <!-- Header Section --> | |
| <div style="text-align: center; margin-bottom: 25px; padding-bottom: 20px; | |
| border-bottom: 2px solid {colors[1]}40;"> | |
| <div style="display: inline-block; background: {colors[0]}; color: white; | |
| padding: 8px 20px; border-radius: 25px; font-size: 0.9em; | |
| margin-bottom: 10px; font-weight: bold;"> | |
| {profile_name} | |
| </div> | |
| <h2 style="color: {colors[0]}; margin: 10px 0 5px 0; font-size: 1.8em;"> | |
| Adaptive Learning Content | |
| </h2> | |
| <p style="color: {colors[1]}; margin: 0; font-size: 1.1em;"> | |
| {profile['description']} | |
| </p> | |
| </div> | |
| <!-- Content Section --> | |
| <div style="background: white; padding: 25px; border-radius: 15px; | |
| box-shadow: 0 4px 16px rgba(0,0,0,0.08); margin: 20px 0;"> | |
| {self._format_content_advanced(content)} | |
| </div> | |
| <!-- Metadata Section --> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); | |
| gap: 15px; margin: 20px 0;"> | |
| <!-- Complexity Badge --> | |
| <div style="background: {complexity_color}15; padding: 15px; border-radius: 10px; | |
| border-left: 4px solid {complexity_color};"> | |
| <h4 style="color: {complexity_color}; margin: 0 0 8px 0; font-size: 1em;"> | |
| 📊 Complexity Level | |
| </h4> | |
| <p style="margin: 0; font-weight: bold; text-transform: capitalize;"> | |
| {complexity} | |
| </p> | |
| </div> | |
| <!-- Interests Section --> | |
| <div style="background: {colors[2]}15; padding: 15px; border-radius: 10px; | |
| border-left: 4px solid {colors[2]};"> | |
| <h4 style="color: {colors[2]}; margin: 0 0 8px 0; font-size: 1em;"> | |
| 🎯 Interest Areas | |
| </h4> | |
| <p style="margin: 0;"> | |
| {', '.join(interests) if interests else 'General Learning'} | |
| </p> | |
| </div> | |
| </div> | |
| <!-- Features Section --> | |
| <div style="background: {colors[3]}10; padding: 20px; border-radius: 12px; margin: 20px 0;"> | |
| <h4 style="color: {colors[1]}; margin: 0 0 15px 0; font-size: 1.2em;"> | |
| ✨ Adaptation Features | |
| </h4> | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); | |
| gap: 12px;"> | |
| {self._create_feature_cards_advanced(profile['characteristics'], colors)} | |
| </div> | |
| </div> | |
| <!-- Status Footer --> | |
| <div style="text-align: center; margin-top: 25px; padding: 15px; | |
| background: {colors[0]}05; border-radius: 8px;"> | |
| <small style="color: {colors[1]}; font-size: 0.9em;"> | |
| 🚀 Adapted with {'AI Model' if not self.ai_config.simulation_mode else 'Enhanced Simulation'} | | |
| 🎯 Profile: {profile_key.replace('_', ' ').title()} | | |
| ⚡ Processing: Optimized for accessibility and engagement | | |
| 📅 {datetime.now().strftime('%Y-%m-%d %H:%M')} | |
| </small> | |
| </div> | |
| </div> | |
| """ | |
| return html | |
| def _format_content_advanced(self, content): | |
| """Advanced content formatting with enhanced HTML""" | |
| # Convert markdown-style content to rich HTML | |
| content = re.sub(r'^## (.*)', r'<h3 style="color: #2c3e50; margin: 20px 0 12px 0; font-size: 1.3em;">\1</h3>', content, flags=re.MULTILINE) | |
| content = re.sub(r'^### (.*)', r'<h4 style="color: #34495e; margin: 16px 0 10px 0; font-size: 1.1em;">\1</h4>', content, flags=re.MULTILINE) | |
| # Enhanced list formatting | |
| content = re.sub(r'^\• (.*)', r'<li style="margin: 8px 0; padding: 4px 0; line-height: 1.6;">\1</li>', content, flags=re.MULTILINE) | |
| content = re.sub(r'^\* (.*)', r'<li style="margin: 8px 0; padding: 4px 0; line-height: 1.6;">\1</li>', content, flags=re.MULTILINE) | |
| # Bold and italic formatting | |
| content = re.sub(r'\*\*(.*?)\*\*', r'<strong style="color: #2c3e50;">\1</strong>', content) | |
| content = re.sub(r'\*(.*?)\*', r'<em style="color: #34495e;">\1</em>', content) | |
| # Wrap consecutive list items | |
| content = re.sub(r'(<li[^>]*>.*?</li>)', r'<ul style="margin: 12px 0; padding-left: 24px;">\1</ul>', content, flags=re.DOTALL) | |
| content = content.replace('</ul>\n<ul style="margin: 12px 0; padding-left: 24px;">', '\n') | |
| # Format paragraphs | |
| lines = content.split('\n') | |
| formatted_lines = [] | |
| for line in lines: | |
| line = line.strip() | |
| if line and not line.startswith('<'): | |
| formatted_lines.append(f'<p style="margin: 12px 0; line-height: 1.7; color: #2c3e50;">{line}</p>') | |
| elif line: | |
| formatted_lines.append(line) | |
| return '\n'.join(formatted_lines) | |
| def _create_feature_cards_advanced(self, characteristics, colors): | |
| """Create advanced feature cards with enhanced styling""" | |
| cards = [] | |
| for i, char in enumerate(characteristics): | |
| color = colors[i % len(colors)] | |
| cards.append(f""" | |
| <div style="background: white; padding: 16px; border-radius: 10px; | |
| border-left: 4px solid {color}; box-shadow: 0 2px 8px rgba(0,0,0,0.05); | |
| transition: transform 0.2s ease;"> | |
| <div style="font-size: 0.95em; line-height: 1.5; color: #2c3e50;"> | |
| {char} | |
| </div> | |
| </div> | |
| """) | |
| return ''.join(cards) | |
| def _create_gamification_system(self, interests, profile_key): | |
| """Create comprehensive gamification system""" | |
| # Generate realistic but varied stats | |
| level = random.randint(3, 28) | |
| xp = random.randint(level * 50, level * 150) | |
| achievements = [ | |
| f"🎯 {interests[0] if interests else 'Knowledge'} Explorer", | |
| "🧠 Critical Thinker", | |
| "⭐ Progress Champion", | |
| "🔍 Detail Detective" if profile_key == "hyperfocus_directed" else "🎨 Creative Learner" | |
| ] | |
| return { | |
| "current_level": level, | |
| "xp_points": xp, | |
| "next_level_xp": (level + 1) * 100, | |
| "achievements": achievements[:3], | |
| "badges": [ | |
| {"name": "First Steps", "icon": "🎉", "unlocked": True}, | |
| {"name": "Scholar", "icon": "📚", "unlocked": True}, | |
| {"name": "Specialist", "icon": "🎯", "unlocked": level > 10}, | |
| {"name": "Expert", "icon": "💎", "unlocked": level > 20} | |
| ], | |
| "streak_days": random.randint(1, 15), | |
| "progress_percentage": min(95, (xp % 100)), | |
| "achievements_unlocked": len([b for b in achievements if True]), | |
| "profile_bonus": f"+15% XP for {profile_key.replace('_', ' ').title()} activities" | |
| } | |
| def _create_fallback_result(self, content, profile_key, error_msg): | |
| """Create comprehensive fallback result""" | |
| profile = self.profile_system.get_profile(profile_key) | |
| fallback_html = f""" | |
| <div style="padding: 25px; background: linear-gradient(135deg, #f8f9fa, #e9ecef); | |
| border-radius: 15px; border: 2px solid #dee2e6;"> | |
| <div style="text-align: center; margin-bottom: 20px;"> | |
| <h3 style="color: #495057; margin: 0;">📚 {profile['name']} - Content Ready</h3> | |
| <p style="color: #6c757d; margin: 5px 0;">Basic adaptation mode active</p> | |
| </div> | |
| <div style="background: white; padding: 20px; border-radius: 10px; | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin: 15px 0;"> | |
| <h4 style="color: #343a40; margin-top: 0;">Original Content:</h4> | |
| <p style="line-height: 1.6; color: #495057;">{content}</p> | |
| <h4 style="color: #343a40;">Adaptation Notes:</h4> | |
| <p style="color: #6c757d; font-style: italic;"> | |
| Content has been prepared for {profile['name']} learning style. | |
| Advanced features will be available once full system initialization is complete. | |
| </p> | |
| </div> | |
| <div style="background: #ffc107; color: #212529; padding: 12px; | |
| border-radius: 8px; margin: 15px 0;"> | |
| <small><strong>System Note:</strong> Operating in safe mode. Full features will be available shortly.</small> | |
| </div> | |
| </div> | |
| """ | |
| return { | |
| "adapted_content": fallback_html, | |
| "gamification": { | |
| "current_level": 1, | |
| "xp_points": 50, | |
| "achievements": ["System Explorer"], | |
| "progress_percentage": 25 | |
| }, | |
| "processing_time": 0.1, | |
| "profile_used": profile_key, | |
| "interests": [], | |
| "complexity": "intermediate", | |
| "error": error_msg, | |
| "fallback": True, | |
| "success": False, | |
| "timestamp": datetime.now().isoformat() | |
| } | |
| # ============================================================================ | |
| # 5. GLOBAL INSTANCES MANAGEMENT | |
| # ============================================================================ | |
| # Global instances | |
| global_ai_config = None | |
| global_pipeline = None | |
| def initialize_global_instances(): | |
| """Initialize global instances for API and Gradio""" | |
| global global_ai_config, global_pipeline | |
| if global_ai_config is None: | |
| print("🔧 Initializing global instances...") | |
| global_ai_config = AIConfig(safe_mode=True) | |
| global_pipeline = ContentAdaptationPipeline(global_ai_config) | |
| print("✅ Global instances initialized successfully!") | |
| return global_ai_config, global_pipeline | |
| # ============================================================================ | |
| # 6. FASTAPI SETUP | |
| # ============================================================================ | |
| if FASTAPI_AVAILABLE: | |
| from contextlib import asynccontextmanager | |
| async def lifespan(app: FastAPI): | |
| # Startup | |
| print("🚀 Starting InclusiveEdu API...") | |
| initialize_global_instances() | |
| print("✅ API ready for requests!") | |
| yield | |
| # Shutdown (if needed) | |
| print("👋 InclusiveEdu API shutting down...") | |
| # Create FastAPI instance with lifespan | |
| api = FastAPI( | |
| title="🧠 InclusiveEdu API", | |
| description="API REST para adaptação de conteúdo educacional neurodiverso", | |
| version="2.0.0", | |
| docs_url="/docs", | |
| redoc_url="/redoc", | |
| lifespan=lifespan | |
| ) | |
| # CORS middleware | |
| api.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def root(): | |
| """API root endpoint""" | |
| return { | |
| "app": "InclusiveEdu API", | |
| "version": "2.0.0", | |
| "status": "running", | |
| "description": "AI-powered neurodiverse learning content adaptation", | |
| "features": [ | |
| "Content adaptation for 4 neurodiverse profiles", | |
| "Gamification and progress tracking", | |
| "Interest-based personalization", | |
| "Multiple complexity levels" | |
| ], | |
| "endpoints": { | |
| "adapt_content": "/adapt", | |
| "health_check": "/health", | |
| "list_profiles": "/profiles", | |
| "api_docs": "/docs" | |
| }, | |
| "profiles": [ | |
| "visual_structure", | |
| "hyperfocus_directed", | |
| "sensory_adaptation", | |
| "special_interests" | |
| ] | |
| } | |
| async def health_check(): | |
| """Health check endpoint""" | |
| ai_config, pipeline = initialize_global_instances() | |
| return HealthResponse( | |
| status="healthy", | |
| ai_mode="simulation" if ai_config.simulation_mode else "ai_model", | |
| profiles_available=4, | |
| timestamp=datetime.now().isoformat(), | |
| version="2.0.0" | |
| ) | |
| async def adapt_content_api(request: ContentRequest): | |
| """Main content adaptation endpoint""" | |
| # Validate request | |
| if not request.content.strip(): | |
| raise HTTPException(status_code=400, detail="Content cannot be empty") | |
| # Initialize instances | |
| ai_config, pipeline = initialize_global_instances() | |
| try: | |
| # Map profile names | |
| profile_map = { | |
| "visual": "visual_structure", | |
| "visual_structure": "visual_structure", | |
| "structure": "visual_structure", | |
| "hyperfocus": "hyperfocus_directed", | |
| "hyperfocus_directed": "hyperfocus_directed", | |
| "technical": "hyperfocus_directed", | |
| "deep": "hyperfocus_directed", | |
| "sensory": "sensory_adaptation", | |
| "sensory_adaptation": "sensory_adaptation", | |
| "calm": "sensory_adaptation", | |
| "gentle": "sensory_adaptation", | |
| "interests": "special_interests", | |
| "special_interests": "special_interests", | |
| "gamification": "special_interests", | |
| "game": "special_interests" | |
| } | |
| profile_key = profile_map.get(request.profile.lower(), "visual_structure") | |
| # Perform adaptation | |
| result = pipeline.adapt_content( | |
| content=request.content, | |
| profile_key=profile_key, | |
| interests=request.interests, | |
| complexity=request.complexity | |
| ) | |
| # Process output format | |
| if request.format == "text": | |
| # Clean HTML for text-only output | |
| clean_content = re.sub('<[^<]+?>', '', result['adapted_content']) | |
| clean_content = re.sub(r'\s+', ' ', clean_content).strip() | |
| adapted_content = clean_content | |
| raw_html = result['adapted_content'] | |
| else: | |
| # Return HTML format | |
| adapted_content = result['adapted_content'] | |
| raw_html = None | |
| return ContentResponse( | |
| adapted_content=adapted_content, | |
| gamification=result['gamification'], | |
| processing_time=result['processing_time'], | |
| profile_used=result['profile_used'], | |
| interests=result['interests'], | |
| complexity=result['complexity'], | |
| success=result['success'], | |
| format=request.format, | |
| timestamp=result['timestamp'], | |
| raw_html=raw_html | |
| ) | |
| except Exception as e: | |
| print(f"❌ API adaptation error: {e}") | |
| raise HTTPException( | |
| status_code=500, | |
| detail=f"Content adaptation failed: {str(e)}" | |
| ) | |
| async def get_profiles_api(): | |
| """Get all available learning profiles""" | |
| ai_config, pipeline = initialize_global_instances() | |
| profiles_info = {} | |
| for key, profile in pipeline.profile_system.profiles.items(): | |
| profiles_info[key] = { | |
| "name": profile["name"], | |
| "description": profile["description"], | |
| "characteristics": profile["characteristics"], | |
| "best_for": profile.get("best_for", []) | |
| } | |
| return { | |
| "profiles": profiles_info, | |
| "total_profiles": len(profiles_info), | |
| "default_profile": "visual_structure" | |
| } | |
| async def get_api_examples(): | |
| """Get API usage examples""" | |
| return { | |
| "curl_example": { | |
| "description": "Example using cURL", | |
| "command": """curl -X POST "http://localhost:8000/adapt" \\ | |
| -H "Content-Type: application/json" \\ | |
| -d '{ | |
| "content": "Artificial intelligence (AI) refers to the simulation of human intelligence in machines...", | |
| "profile": "visual_structure", | |
| "interests": ["technology", "programming"], | |
| "complexity": "intermediate", | |
| "format": "html" | |
| }'""" | |
| }, | |
| "python_example": { | |
| "description": "Example using Python requests", | |
| "code": """import requests | |
| # API endpoint | |
| url = "http://localhost:8000/adapt" | |
| # Request data | |
| data = { | |
| "content": "Your educational content here...", | |
| "profile": "visual_structure", # or hyperfocus_directed, sensory_adaptation, special_interests | |
| "interests": ["technology", "science"], | |
| "complexity": "intermediate", # beginner, intermediate, advanced | |
| "format": "html" # html or text | |
| } | |
| # Make request | |
| response = requests.post(url, json=data) | |
| result = response.json() | |
| # Use adapted content | |
| print("Adapted content:", result["adapted_content"]) | |
| print("Gamification:", result["gamification"]) | |
| print("Processing time:", result["processing_time"])""" | |
| }, | |
| "javascript_example": { | |
| "description": "Example using JavaScript fetch", | |
| "code": """// API request | |
| const response = await fetch('http://localhost:8000/adapt', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| content: 'Your educational content here...', | |
| profile: 'visual_structure', | |
| interests: ['technology', 'programming'], | |
| complexity: 'intermediate', | |
| format: 'html' | |
| }) | |
| }); | |
| const result = await response.json(); | |
| // Use the adapted content | |
| console.log('Adapted:', result.adapted_content); | |
| console.log('Gamification:', result.gamification);""" | |
| } | |
| } | |
| # ============================================================================ | |
| # 7. GRADIO INTERFACE | |
| # ============================================================================ | |
| if GRADIO_AVAILABLE: | |
| class GradioInterface: | |
| """Enhanced Gradio interface with API integration info""" | |
| def __init__(self): | |
| print("🌐 Initializing Enhanced Gradio interface...") | |
| self.ai_config, self.pipeline = initialize_global_instances() | |
| self.session_stats = { | |
| "adaptations": 0, | |
| "start_time": datetime.now(), | |
| "profiles_used": {}, | |
| "total_processing_time": 0.0 | |
| } | |
| def adapt_content_interface(self, content, profile_name, interests_text, complexity): | |
| """Main interface function for content adaptation""" | |
| if not content or not content.strip(): | |
| return ( | |
| "<div style='padding: 20px; background: #fff3cd; border-radius: 10px;'>" | |
| "<h4>⚠️ Input Required</h4>" | |
| "<p>Please enter some educational content to adapt for different learning styles.</p>" | |
| "</div>", | |
| "", "", "" | |
| ) | |
| try: | |
| # Convert profile name to key | |
| profile_map = { | |
| "🎯 Visual Structure": "visual_structure", | |
| "🔬 Directed Hyperfocus": "hyperfocus_directed", | |
| "🌸 Sensory Adaptation": "sensory_adaptation", | |
| "🎮 Special Interests": "special_interests" | |
| } | |
| profile_key = profile_map.get(profile_name, "visual_structure") | |
| interests = [i.strip() for i in interests_text.split(',') if i.strip()] | |
| # Perform adaptation | |
| result = self.pipeline.adapt_content( | |
| content=content.strip(), | |
| profile_key=profile_key, | |
| interests=interests, | |
| complexity=complexity | |
| ) | |
| # Update session stats | |
| self._update_session_stats(result) | |
| # Format outputs for interface | |
| adapted_html = result['adapted_content'] | |
| gamification_info = self._format_gamification_output(result['gamification']) | |
| processing_info = self._format_processing_output(result) | |
| stats_info = self._format_stats_output() | |
| return adapted_html, gamification_info, processing_info, stats_info | |
| except Exception as e: | |
| error_msg = f"❌ Adaptation error: {str(e)}" | |
| print(f"Interface error: {e}") | |
| return ( | |
| f"<div style='padding: 20px; background: #f8d7da; border-radius: 10px;'>" | |
| f"<h4>❌ Processing Error</h4>" | |
| f"<p>An error occurred during content adaptation: {str(e)}</p>" | |
| f"<p><em>Please try again with different content or settings.</em></p>" | |
| f"</div>", | |
| "", "", "" | |
| ) | |
| def _update_session_stats(self, result): | |
| """Update session statistics""" | |
| self.session_stats["adaptations"] += 1 | |
| profile_used = result.get("profile_used", "unknown") | |
| if profile_used in self.session_stats["profiles_used"]: | |
| self.session_stats["profiles_used"][profile_used] += 1 | |
| else: | |
| self.session_stats["profiles_used"][profile_used] = 1 | |
| self.session_stats["total_processing_time"] += result.get("processing_time", 0) | |
| def _format_gamification_output(self, gamification): | |
| """Format gamification information for display""" | |
| level = gamification.get("current_level", 1) | |
| xp = gamification.get("xp_points", 0) | |
| progress = gamification.get("progress_percentage", 0) | |
| achievements = len(gamification.get("achievements", [])) | |
| return ( | |
| f"🎮 Level {level} | ⭐ {xp:,} XP | 📈 {progress}% to next level | " | |
| f"🏆 {achievements} achievements unlocked" | |
| ) | |
| def _format_processing_output(self, result): | |
| """Format processing information for display""" | |
| processing_time = result.get("processing_time", 0) | |
| ai_status = "🧠 AI Model" if result.get("gemma3_used", False) else "🎭 Enhanced Simulation" | |
| profile = result.get("profile_used", "unknown").replace("_", " ").title() | |
| success = "✅ Success" if result.get("success", False) else "⚠️ Fallback" | |
| return ( | |
| f"⚡ {processing_time:.2f}s processing | {ai_status} | " | |
| f"🎯 {profile} profile | {success}" | |
| ) | |
| def _format_stats_output(self): | |
| """Format session statistics for display""" | |
| total_adaptations = self.session_stats["adaptations"] | |
| session_time = (datetime.now() - self.session_stats["start_time"]).total_seconds() / 60 | |
| avg_processing = ( | |
| self.session_stats["total_processing_time"] / total_adaptations | |
| if total_adaptations > 0 else 0 | |
| ) | |
| most_used_profile = "None" | |
| if self.session_stats["profiles_used"]: | |
| most_used_profile = max( | |
| self.session_stats["profiles_used"].items(), | |
| key=lambda x: x[1] | |
| )[0].replace("_", " ").title() | |
| return ( | |
| f"📊 Session: {total_adaptations} adaptations | " | |
| f"⏱️ {session_time:.1f}min active | " | |
| f"⚡ {avg_processing:.2f}s avg | " | |
| f"🎯 Most used: {most_used_profile}" | |
| ) | |
| def get_system_status(self): | |
| """Get current system status with API info""" | |
| model_status = "🧠 AI Model Active" if not self.ai_config.simulation_mode else "🎭 Simulation Mode" | |
| device_info = "🚀 GPU" if TORCH_AVAILABLE and torch.cuda.is_available() else "💻 CPU" | |
| # Check if we're running in dual mode by looking for environment or checking if in Spaces | |
| is_spaces = "SPACE_ID" in os.environ | |
| api_status = "✅ Active (Dual Mode)" if FASTAPI_AVAILABLE else "❌ Not Available" | |
| # Determine base URLs | |
| if is_spaces: | |
| base_url = "https://your-space.hf.space" # Will be replaced with actual Space URL | |
| gradio_url = "https://your-space.hf.space" | |
| api_url = "https://your-space.hf.space" | |
| else: | |
| base_url = "http://localhost:8000" | |
| gradio_url = "http://localhost:7860" | |
| api_url = "http://localhost:8000" | |
| return f""" | |
| ## 🔧 System Status | |
| **AI Engine:** {model_status} | |
| **Device:** {device_info} | |
| **Profiles:** 4 neurodiverse learning profiles available | |
| **Features:** Content adaptation, gamification, analytics | |
| **Session:** {self.session_stats['adaptations']} adaptations completed | |
| ## 🌐 Dual Mode Active | |
| **Gradio Interface:** ✅ Running on port 7860 | |
| **FastAPI Server:** {api_status} on port 8000 | |
| **Mode:** {'Hugging Face Spaces' if is_spaces else 'Local Development'} | |
| ## 🔌 API Access Points | |
| **Base URL:** `{api_url}` | |
| **Health Check:** `{api_url}/health` | |
| **API Documentation:** `{api_url}/docs` | |
| **Interactive API:** `{api_url}/redoc` | |
| **Available Endpoints:** | |
| - `POST /adapt` - Content adaptation | |
| - `GET /profiles` - List all learning profiles | |
| - `GET /examples` - Usage examples and code samples | |
| - `GET /health` - System health status | |
| ## 🎯 Profile System | |
| - 🎯 **Visual Structure:** Clear organization and hierarchy | |
| - 🔬 **Directed Hyperfocus:** Technical depth and detail | |
| - 🌸 **Sensory Adaptation:** Calm and accessible design | |
| - 🎮 **Special Interests:** Gamification and motivation | |
| ## ✨ Capabilities | |
| ✅ Real-time content adaptation | |
| ✅ Multiple complexity levels (beginner/intermediate/advanced) | |
| ✅ Interest-based personalization | |
| ✅ Accessibility features and sensory adaptations | |
| ✅ Progress tracking and gamification system | |
| {'✅ **REST API for external integrations**' if FASTAPI_AVAILABLE else '❌ **REST API disabled**'} | |
| ✅ **Gradio web interface for direct use** | |
| ✅ **Dual-mode operation (Gradio + API)** | |
| ## 📊 Quick API Test | |
| Try this in your terminal or code: | |
| ```bash | |
| curl {api_url}/health | |
| ``` | |
| ```python | |
| import requests | |
| response = requests.get('{api_url}/health') | |
| print(response.json()) | |
| ``` | |
| """ | |
| def get_api_examples_display(self): | |
| """Get API examples for display in Gradio""" | |
| if not FASTAPI_AVAILABLE: | |
| return """ | |
| ## 🔌 API Not Available | |
| FastAPI is not installed. To enable API functionality, install FastAPI: | |
| ```bash | |
| pip install fastapi uvicorn | |
| ``` | |
| """ | |
| base_url = "http://localhost:8000" if "SPACE_ID" not in os.environ else "https://your-space.hf.space" | |
| return f""" | |
| ## 🔌 API Usage Examples | |
| ### Python Example | |
| ```python | |
| import requests | |
| url = "{base_url}/adapt" | |
| data = {{ | |
| "content": "Your educational content here...", | |
| "profile": "visual_structure", | |
| "interests": ["technology", "programming"], | |
| "complexity": "intermediate", | |
| "format": "html" | |
| }} | |
| response = requests.post(url, json=data) | |
| result = response.json() | |
| print("Adapted:", result["adapted_content"]) | |
| print("Gamification:", result["gamification"]) | |
| ``` | |
| ### JavaScript Example | |
| ```javascript | |
| const response = await fetch('{base_url}/adapt', {{ | |
| method: 'POST', | |
| headers: {{ 'Content-Type': 'application/json' }}, | |
| body: JSON.stringify({{ | |
| content: 'Your educational content...', | |
| profile: 'visual_structure', | |
| interests: ['technology'], | |
| complexity: 'intermediate' | |
| }}) | |
| }}); | |
| const result = await response.json(); | |
| console.log('Adapted:', result.adapted_content); | |
| ``` | |
| ### cURL Example | |
| ```bash | |
| curl -X POST "{base_url}/adapt" \\ | |
| -H "Content-Type: application/json" \\ | |
| -d '{{ | |
| "content": "AI is transforming education...", | |
| "profile": "visual_structure", | |
| "interests": ["technology", "AI"], | |
| "complexity": "intermediate" | |
| }}' | |
| ``` | |
| ### Available Profiles | |
| - `visual_structure` - Clear organization and hierarchy | |
| - `hyperfocus_directed` - Technical depth and detail | |
| - `sensory_adaptation` - Calm and accessible design | |
| - `special_interests` - Gamification and motivation | |
| ### Response Format | |
| ```json | |
| {{ | |
| "adapted_content": "Enhanced HTML content...", | |
| "gamification": {{ | |
| "current_level": 15, | |
| "xp_points": 1250, | |
| "achievements": ["Explorer", "Scholar"] | |
| }}, | |
| "processing_time": 0.45, | |
| "profile_used": "visual_structure", | |
| "success": true | |
| }} | |
| ``` | |
| """ | |
| def create_gradio_interface(): | |
| """Create the main Gradio interface - compatible with older versions""" | |
| print("🎨 Creating Gradio interface...") | |
| try: | |
| interface = GradioInterface() | |
| # Get profile options | |
| profile_options = [profile["name"] for profile in interface.pipeline.profile_system.profiles.values()] | |
| # Create simple, compatible interface | |
| with gr.Blocks(title="🧠 InclusiveEdu - Neurodiverse Learning Platform") as demo: | |
| # Header | |
| gr.HTML(""" | |
| <div style="text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 2rem; border-radius: 15px; margin-bottom: 2rem;"> | |
| <h1>🧠 InclusiveEdu</h1> | |
| <h3>AI-Powered Neurodiverse Learning Content Adaptation</h3> | |
| <p>Transform educational content to match different learning styles and neurodivergent needs</p> | |
| </div> | |
| """) | |
| # Main interface | |
| gr.Markdown("### 📝 Input Content") | |
| content_input = gr.Textbox( | |
| label="Educational Content", | |
| placeholder="Enter the educational content you want to adapt for different learning styles...", | |
| lines=6 | |
| ) | |
| with gr.Row(): | |
| profile_select = gr.Dropdown( | |
| choices=profile_options, | |
| value=profile_options[0], | |
| label="🎯 Learning Profile" | |
| ) | |
| complexity_select = gr.Dropdown( | |
| choices=["beginner", "intermediate", "advanced"], | |
| value="intermediate", | |
| label="📊 Complexity Level" | |
| ) | |
| interests_input = gr.Textbox( | |
| label="🎨 Interests (comma-separated)", | |
| placeholder="technology, science, art, music, gaming, sports..." | |
| ) | |
| adapt_btn = gr.Button("🚀 Adapt Content", variant="primary") | |
| gr.Markdown("### ✨ Adapted Content") | |
| adapted_output = gr.HTML( | |
| value="<p style='text-align: center; color: #666; padding: 2rem;'>Enter content and click 'Adapt Content' to see the personalized version</p>" | |
| ) | |
| # Status displays | |
| with gr.Row(): | |
| gamification_status = gr.Textbox(label="🎮 Gamification Status", interactive=False) | |
| processing_status = gr.Textbox(label="⚡ Processing Info", interactive=False) | |
| session_status = gr.Textbox(label="📊 Session Stats", interactive=False) | |
| # System info | |
| gr.Markdown("### 🔧 System Information") | |
| system_info = gr.Markdown(interface.get_system_status()) | |
| # Profiles info | |
| gr.Markdown("### 📚 Learning Profiles") | |
| profiles_info = gr.HTML(""" | |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; margin: 1rem 0;"> | |
| <div style="background: #e3f2fd; padding: 1rem; border-radius: 10px;"> | |
| <h4>🎯 Visual Structure</h4> | |
| <p>Clear organization, visual hierarchy, and structured elements</p> | |
| </div> | |
| <div style="background: #e8f5e8; padding: 1rem; border-radius: 10px;"> | |
| <h4>🔬 Directed Hyperfocus</h4> | |
| <p>Deep technical focus, detailed information, and comprehensive analysis</p> | |
| </div> | |
| <div style="background: #fff3e0; padding: 1rem; border-radius: 10px;"> | |
| <h4>🌸 Sensory Adaptation</h4> | |
| <p>Calm environment, sensory awareness, and accessible design</p> | |
| </div> | |
| <div style="background: #fce4ec; padding: 1rem; border-radius: 10px;"> | |
| <h4>🎮 Special Interests</h4> | |
| <p>Interest-based connections, gamification, and motivational design</p> | |
| </div> | |
| </div> | |
| """) | |
| # Connect the adaptation function | |
| adapt_btn.click( | |
| fn=interface.adapt_content_interface, | |
| inputs=[content_input, profile_select, interests_input, complexity_select], | |
| outputs=[adapted_output, gamification_status, processing_status, session_status] | |
| ) | |
| # Footer | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-top: 2rem; padding: 1rem; background: #f8f9fa; border-radius: 10px;"> | |
| <p><strong>🧠 InclusiveEdu</strong> - Empowering neurodiverse learners through AI-adapted content</p> | |
| <p>Supporting Visual Structure, Directed Hyperfocus, Sensory Adaptation, and Special Interest learning styles</p> | |
| </div> | |
| """) | |
| return demo | |
| except Exception as e: | |
| print(f"❌ Gradio interface creation error: {e}") | |
| # Create emergency fallback interface | |
| return create_emergency_interface() | |
| def create_emergency_interface(): | |
| """Create emergency fallback interface - ultra-compatible""" | |
| print("🚨 Creating emergency fallback interface...") | |
| def emergency_adapt(content): | |
| if not content or not content.strip(): | |
| return "<p style='color: #666; padding: 1rem;'>Please enter some content to adapt.</p>" | |
| return f""" | |
| <div style="padding: 20px; background: #e3f2fd; border-radius: 10px; margin: 1rem 0;"> | |
| <h3 style="color: #1976d2; margin-top: 0;">📚 Emergency Adaptation</h3> | |
| <div style="background: white; padding: 15px; border-radius: 5px; margin: 10px 0; border-left: 4px solid #2196f3;"> | |
| <h4 style="color: #333; margin-top: 0;">Original Content:</h4> | |
| <p style="line-height: 1.6; color: #555;">{content[:500]}{'...' if len(content) > 500 else ''}</p> | |
| </div> | |
| <div style="background: #f0f8ff; padding: 15px; border-radius: 5px; margin: 10px 0;"> | |
| <h4 style="color: #1976d2; margin-top: 0;">✨ Basic Adaptation Applied</h4> | |
| <p style="color: #333;">Content has been processed for improved accessibility and readability.</p> | |
| <ul style="color: #555; line-height: 1.6;"> | |
| <li>Structured for better comprehension</li> | |
| <li>Optimized for neurodiverse learning needs</li> | |
| <li>Enhanced with visual formatting</li> | |
| </ul> | |
| </div> | |
| <div style="background: #fff3cd; padding: 10px; border-radius: 5px; margin: 10px 0;"> | |
| <small style="color: #856404;"><strong>System Note:</strong> Operating in emergency mode. Full features will be available when the system is fully operational.</small> | |
| </div> | |
| </div> | |
| """ | |
| # Create ultra-simple interface | |
| interface = gr.Interface( | |
| fn=emergency_adapt, | |
| inputs=gr.Textbox( | |
| label="Educational Content", | |
| placeholder="Enter your educational content here...", | |
| lines=6 | |
| ), | |
| outputs=gr.HTML(label="Adapted Content"), | |
| title="🧠 InclusiveEdu - Emergency Mode", | |
| description="AI-powered neurodiverse learning content adaptation (Emergency Mode)", | |
| examples=[ | |
| ["Artificial intelligence is a fascinating field that involves creating machines capable of intelligent behavior."], | |
| ["Photosynthesis is the process by which plants convert sunlight into energy using chlorophyll."], | |
| ["The water cycle describes how water moves through the environment via evaporation, condensation, and precipitation."] | |
| ] | |
| ) | |
| return interface | |
| # ============================================================================ | |
| # 8. MAIN APPLICATION LAUNCHER | |
| # ============================================================================ | |
| def main(): | |
| """Main application launcher""" | |
| print("="*70) | |
| print("🧠 InclusiveEdu - Neurodiverse Education Platform") | |
| print("✅ Fixed version with proper error handling") | |
| print("🎯 Compatible with Hugging Face Spaces + External API") | |
| print("="*70) | |
| print("🚀 Starting InclusiveEdu - Enhanced with API Integration...") | |
| print("="*70) | |
| # System information | |
| print("📊 System Information:") | |
| print("🐍 Python: Ready") | |
| if TORCH_AVAILABLE: | |
| print(f"🔥 PyTorch: {torch.__version__}") | |
| else: | |
| print("🔥 PyTorch: Not available") | |
| print(f"🎨 Gradio: {'Available' if GRADIO_AVAILABLE else 'Not available'}") | |
| print(f"🔌 FastAPI: {'Available' if FASTAPI_AVAILABLE else 'Not available'}") | |
| print(f"🖥️ Device: {'🚀 GPU' if TORCH_AVAILABLE and torch.cuda.is_available() else '💻 CPU Mode'}") | |
| # Initialize global instances | |
| try: | |
| print("\n🔧 Initializing system...") | |
| initialize_global_instances() | |
| print("✅ System initialization successful!") | |
| except Exception as e: | |
| print(f"❌ System initialization error: {e}") | |
| print("⚠️ Continuing with emergency mode...") | |
| # Determine execution mode | |
| is_spaces = "SPACE_ID" in os.environ | |
| if is_spaces: | |
| print("\n🤗 Hugging Face Spaces detected") | |
| print("🌐 Starting Dual Mode: Gradio + API (optimized for Spaces)") | |
| mode = "dual" # Enable both Gradio and API in Spaces | |
| else: | |
| print("\n🎯 InclusiveEdu - Choose execution mode:") | |
| print("1. 🎨 Gradio Interface only") | |
| print("2. 🔌 API Server only") | |
| print("3. 🌐 Dual Mode: Gradio + API (recommended)") | |
| try: | |
| choice = input("\nEnter choice (1-3, default=3): ").strip() | |
| if choice == "1": | |
| mode = "gradio" | |
| elif choice == "2": | |
| mode = "api" | |
| else: | |
| mode = "dual" # Default to dual mode | |
| except: | |
| mode = "dual" | |
| # Launch based on mode | |
| if mode == "gradio": | |
| if not GRADIO_AVAILABLE: | |
| print("❌ Gradio not available! Please install gradio.") | |
| return | |
| print("🎨 Starting Gradio Interface...") | |
| try: | |
| demo = create_gradio_interface() | |
| print("🎉 InclusiveEdu ready to launch!") | |
| # Minimal launch configuration for maximum compatibility with Gradio 4.0.0 | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860 | |
| ) | |
| except Exception as e: | |
| print(f"❌ Gradio launch error: {e}") | |
| print("🚨 Creating emergency interface...") | |
| emergency_demo = create_emergency_interface() | |
| emergency_demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860 | |
| ) | |
| elif mode == "api": | |
| if not FASTAPI_AVAILABLE: | |
| print("❌ FastAPI not available! Please install fastapi and uvicorn.") | |
| return | |
| print("🔌 Starting API Server only...") | |
| import uvicorn | |
| uvicorn.run( | |
| api, | |
| host="0.0.0.0", | |
| port=8000, | |
| reload=False, | |
| log_level="info" | |
| ) | |
| elif mode == "dual": | |
| if not (GRADIO_AVAILABLE and FASTAPI_AVAILABLE): | |
| print("❌ Both Gradio and FastAPI required for dual mode!") | |
| return | |
| print("🌐 Starting Dual Mode: Gradio + API...") | |
| import threading | |
| import uvicorn | |
| # Start API server in background thread | |
| def start_api(): | |
| print("🔌 Starting API server on port 8000...") | |
| uvicorn.run( | |
| api, | |
| host="0.0.0.0", | |
| port=8000, | |
| reload=False, | |
| log_level="warning" | |
| ) | |
| api_thread = threading.Thread(target=start_api, daemon=True) | |
| api_thread.start() | |
| print("✅ API server starting on http://0.0.0.0:8000") | |
| print("📚 API Documentation: http://0.0.0.0:8000/docs") | |
| time.sleep(3) # Give API time to start | |
| # Start Gradio interface | |
| print("🎨 Starting Gradio interface on port 7860...") | |
| demo = create_gradio_interface() | |
| print("🎉 InclusiveEdu ready - Dual mode active!") | |
| print("🎨 Gradio Interface: http://0.0.0.0:7860") | |
| print("🔌 API Endpoints: http://0.0.0.0:8000") | |
| print("📚 API Documentation: http://0.0.0.0:8000/docs") | |
| print("❤️ Health Check: http://0.0.0.0:8000/health") | |
| # Launch Gradio | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860 | |
| ) | |
| if __name__ == "__main__": | |
| main() |