# ============================================================================
# ๐ฆ 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
# ============================================================================
@dataclass
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"""
{profile_name}
Adaptive Learning Content
{profile['description']}
{self._format_content_advanced(content)}
๐ Complexity Level
{complexity}
๐ฏ Interest Areas
{', '.join(interests) if interests else 'General Learning'}
โจ Adaptation Features
{self._create_feature_cards_advanced(profile['characteristics'], colors)}
๐ 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')}
"""
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'\1
', content, flags=re.MULTILINE)
content = re.sub(r'^### (.*)', r'\1
', content, flags=re.MULTILINE)
# Enhanced list formatting
content = re.sub(r'^\โข (.*)', r'\1', content, flags=re.MULTILINE)
content = re.sub(r'^\* (.*)', r'\1', content, flags=re.MULTILINE)
# Bold and italic formatting
content = re.sub(r'\*\*(.*?)\*\*', r'\1', content)
content = re.sub(r'\*(.*?)\*', r'\1', content)
# Wrap consecutive list items
content = re.sub(r'(]*>.*?)', r'', content, flags=re.DOTALL)
content = content.replace('\n', '\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'{line}
')
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"""
""")
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"""
๐ {profile['name']} - Content Ready
Basic adaptation mode active
Original Content:
{content}
Adaptation Notes:
Content has been prepared for {profile['name']} learning style.
Advanced features will be available once full system initialization is complete.
System Note: Operating in safe mode. Full features will be available shortly.
"""
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
@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=["*"],
)
@api.get("/", response_model=dict)
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"
]
}
@api.get("/health", response_model=HealthResponse)
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"
)
@api.post("/adapt", response_model=ContentResponse)
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)}"
)
@api.get("/profiles")
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"
}
@api.get("/examples")
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 (
""
"
โ ๏ธ Input Required
"
"
Please enter some educational content to adapt for different learning styles.
"
"
",
"", "", ""
)
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""
f"
โ Processing Error
"
f"
An error occurred during content adaptation: {str(e)}
"
f"
Please try again with different content or settings.
"
f"
",
"", "", ""
)
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("""
๐ง InclusiveEdu
AI-Powered Neurodiverse Learning Content Adaptation
Transform educational content to match different learning styles and neurodivergent needs
""")
# 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="Enter content and click 'Adapt Content' to see the personalized version
"
)
# 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("""
๐ฏ Visual Structure
Clear organization, visual hierarchy, and structured elements
๐ฌ Directed Hyperfocus
Deep technical focus, detailed information, and comprehensive analysis
๐ธ Sensory Adaptation
Calm environment, sensory awareness, and accessible design
๐ฎ Special Interests
Interest-based connections, gamification, and motivational design
""")
# 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("""
๐ง InclusiveEdu - Empowering neurodiverse learners through AI-adapted content
Supporting Visual Structure, Directed Hyperfocus, Sensory Adaptation, and Special Interest learning styles
""")
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 "Please enter some content to adapt.
"
return f"""
๐ Emergency Adaptation
Original Content:
{content[:500]}{'...' if len(content) > 500 else ''}
โจ Basic Adaptation Applied
Content has been processed for improved accessibility and readability.
- Structured for better comprehension
- Optimized for neurodiverse learning needs
- Enhanced with visual formatting
System Note: Operating in emergency mode. Full features will be available when the system is fully operational.
"""
# 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()