Spaces:
Running
Running
| """ | |
| ATOM Education Industry Customization Service | |
| FERPA compliant educational AI and student management system | |
| """ | |
| import asyncio | |
| import base64 | |
| from collections import Counter, defaultdict | |
| from dataclasses import asdict, dataclass | |
| from datetime import datetime, timedelta, timezone | |
| from enum import Enum | |
| import hashlib | |
| import hmac | |
| import json | |
| import logging | |
| import os | |
| import time | |
| from typing import Any, Callable, Dict, List, Optional, Tuple, Union | |
| from urllib.parse import urlencode | |
| import aiohttp | |
| import httpx | |
| import numpy as np | |
| import pandas as pd | |
| from pydantic import BaseModel, Field | |
| from core.circuit_breaker import circuit_breaker | |
| from core.rate_limiter import rate_limiter, should_retry, calculate_backoff | |
| from core.audit_logger import log_integration_call, log_integration_error, log_integration_attempt, log_integration_complete | |
| from fastapi import HTTPException | |
| # Import existing ATOM services | |
| try: | |
| from ai_enhanced_service import ( | |
| AIModelType, | |
| AIRequest, | |
| AIResponse, | |
| AIServiceType, | |
| AITaskType, | |
| ai_enhanced_service, | |
| ) | |
| from atom_ai_integration import atom_ai_integration | |
| from atom_discord_integration import atom_discord_integration | |
| from atom_enterprise_security_service import ( | |
| ComplianceStandard, | |
| SecurityLevel, | |
| atom_enterprise_security_service, | |
| ) | |
| from atom_google_chat_integration import atom_google_chat_integration | |
| from atom_hubspot_integration_service import atom_hubspot_integration_service | |
| from atom_quickbooks_integration_service import atom_quickbooks_integration_service | |
| from atom_slack_integration import atom_slack_integration | |
| from atom_teams_integration import atom_teams_integration | |
| from atom_telegram_integration import atom_telegram_integration | |
| from atom_video_ai_service import atom_video_ai_service | |
| from atom_voice_ai_service import atom_voice_ai_service | |
| from atom_voice_video_integration_service import atom_voice_video_integration_service | |
| from atom_whatsapp_integration import atom_whatsapp_integration | |
| from atom_workflow_automation_service import ( | |
| AutomationPriority, | |
| AutomationStatus, | |
| atom_workflow_automation_service, | |
| ) | |
| from atom_zendesk_integration_service import atom_zendesk_integration_service | |
| from atom_zoom_integration import atom_zoom_integration | |
| except ImportError as e: | |
| logging.warning(f"Enterprise services not available: {e}") | |
| # Configure logging | |
| logger = logging.getLogger(__name__) | |
| class EducationComplianceStandard(Enum): | |
| """Education compliance standards""" | |
| FERPA = "ferpa" | |
| COPPA = "coppa" | |
| IDEA = "idea" | |
| ADA = "ada" | |
| GDPR = "gdpr" | |
| CCPA = "ccpa" | |
| ISO_27001 = "iso_27001" | |
| NIST_800_53 = "nist_800_53" | |
| class StudentStatus(Enum): | |
| """Student status""" | |
| ENROLLED = "enrolled" | |
| ACTIVE = "active" | |
| INACTIVE = "inactive" | |
| GRADUATED = "graduated" | |
| SUSPENDED = "suspended" | |
| WITHDRAWN = "withdrawn" | |
| TRANSFERRED = "transferred" | |
| ON_LEAVE = "on_leave" | |
| class CourseType(Enum): | |
| """Course types""" | |
| REQUIRED = "required" | |
| ELECTIVE = "elective" | |
| CORE = "core" | |
| GENERAL_EDUCATION = "general_education" | |
| ADVANCED_PLACEMENT = "advanced_placement" | |
| HONORS = "honors" | |
| ONLINE = "online" | |
| HYBRID = "hybrid" | |
| LABORATORY = "laboratory" | |
| class GradeLevel(Enum): | |
| """Grade levels""" | |
| KINDERGARTEN = "kindergarten" | |
| ELEMENTARY = "elementary" | |
| MIDDLE_SCHOOL = "middle_school" | |
| HIGH_SCHOOL = "high_school" | |
| UNDERGRADUATE = "undergraduate" | |
| GRADUATE = "graduate" | |
| POST_GRADUATE = "post_graduate" | |
| class LearningAnalyticsType(Enum): | |
| """Learning analytics types""" | |
| STUDENT_PERFORMANCE = "student_performance" | |
| COURSE_EFFECTIVENESS = "course_effectiveness" | |
| TEACHER_PERFORMANCE = "teacher_performance" | |
| LEARNING_OUTCOMES = "learning_outcomes" | |
| ENGAGEMENT_METRICS = "engagement_metrics" | |
| DROPOUT_PREDICTION = "dropout_prediction" | |
| ATTENDANCE_ANALYTICS = "attendance_analytics" | |
| SKILL_ASSESSMENT = "skill_assessment" | |
| class Student: | |
| """Student data model""" | |
| student_id: str | |
| student_number: str | |
| first_name: str | |
| last_name: str | |
| date_of_birth: datetime | |
| grade_level: GradeLevel | |
| gpa: float | |
| major: Optional[str] | |
| minor: Optional[str] | |
| email: str | |
| phone: str | |
| address: Dict[str, str] | |
| emergency_contacts: List[Dict[str, Any]] | |
| enrollment_date: datetime | |
| status: StudentStatus | |
| academic_standing: str | |
| credits_earned: float | |
| attendance_rate: float | |
| courses_enrolled: List[str] | |
| learning_disabilities: List[str] | |
| special_education_needs: List[str] | |
| parent_guardian_info: List[Dict[str, Any]] | |
| last_updated: datetime | |
| metadata: Dict[str, Any] | |
| class Course: | |
| """Course data model""" | |
| course_id: str | |
| course_code: str | |
| title: str | |
| description: str | |
| instructor_id: str | |
| department: str | |
| course_type: CourseType | |
| credits: float | |
| max_capacity: int | |
| current_enrollment: int | |
| start_date: datetime | |
| end_date: datetime | |
| schedule: Dict[str, Any] | |
| learning_objectives: List[str] | |
| required_materials: List[Dict[str, Any]] | |
| assessment_methods: List[str] | |
| difficulty_level: str | |
| prerequisites: List[str] | |
| created_at: datetime | |
| updated_at: datetime | |
| metadata: Dict[str, Any] | |
| class Assignment: | |
| """Assignment data model""" | |
| assignment_id: str | |
| course_id: str | |
| title: str | |
| description: str | |
| assignment_type: str | |
| due_date: datetime | |
| points_possible: float | |
| learning_objectives: List[str] | |
| rubric: Dict[str, Any] | |
| submission_type: str | |
| allowed_late_submission: bool | |
| late_penalty: float | |
| created_at: datetime | |
| updated_at: datetime | |
| metadata: Dict[str, Any] | |
| class Grade: | |
| """Grade data model""" | |
| grade_id: str | |
| student_id: str | |
| course_id: str | |
| assignment_id: str | |
| score: float | |
| max_score: float | |
| percentage: float | |
| letter_grade: str | |
| submission_date: datetime | |
| graded_date: datetime | |
| grader_id: str | |
| feedback: str | |
| learning_mastery: Dict[str, float] | |
| created_at: datetime | |
| updated_at: datetime | |
| metadata: Dict[str, Any] | |
| class LearningAnalytics: | |
| """Learning analytics data model""" | |
| analytics_id: str | |
| analytics_type: LearningAnalyticsType | |
| time_period: str | |
| start_date: datetime | |
| end_date: datetime | |
| student_id: Optional[str] | |
| course_id: Optional[str] | |
| instructor_id: Optional[str] | |
| metrics: Dict[str, Any] | |
| insights: List[str] | |
| recommendations: List[str] | |
| created_at: datetime | |
| metadata: Dict[str, Any] | |
| class AtomEducationCustomizationService: | |
| """Advanced Education Industry Customization Service""" | |
| def __init__(self, tenant_id: str = "default", config: Dict[str, Any] = None): | |
| if config is None: | |
| config = {} | |
| self.config = config | |
| self.db = config.get('database') | |
| self.cache = config.get('cache') | |
| # Education API configuration | |
| self.education_config = { | |
| 'ferpa_compliance': config.get('ferpa_compliance', True), | |
| 'coppa_compliance': config.get('coppa_compliance', True), | |
| 'idea_compliance': config.get('idea_compliance', True), | |
| 'ada_compliance': config.get('ada_compliance', True), | |
| 'gdpr_compliance': config.get('gdpr_compliance', True), | |
| 'encryption_at_rest': config.get('encryption_at_rest', True), | |
| 'encryption_in_transit': config.get('encryption_in_transit', True), | |
| 'audit_logging': config.get('audit_logging', True), | |
| 'access_control': config.get('access_control', True), | |
| 'data_masking': config.get('data_masking', True), | |
| 'retention_policy': config.get('retention_policy', '10_years'), | |
| 'parent_portal_access': config.get('parent_portal_access', True), | |
| 'educational_ai_enabled': config.get('educational_ai_enabled', True), | |
| 'learning_analytics': config.get('learning_analytics', True), | |
| 'personalized_learning': config.get('personalized_learning', True), | |
| 'automated_grading': config.get('automated_grading', True), | |
| 'plagiarism_detection': config.get('plagiarism_detection', True), | |
| 'attendance_tracking': config.get('attendance_tracking', True), | |
| 'student_performance_prediction': config.get('student_performance_prediction', True), | |
| 'lms_integration': config.get('lms_integration', True), | |
| 'student_information_system': config.get('student_information_system', True), | |
| 'library_integration': config.get('library_integration', True), | |
| 'library_integration': config.get('library_integration', True) | |
| } | |
| # API endpoints | |
| self.api_endpoints = { | |
| 'students': '/api/v1/students', | |
| 'courses': '/api/v1/courses', | |
| 'instructors': '/api/v1/instructors', | |
| 'assignments': '/api/v1/assignments', | |
| 'grades': '/api/v1/grades', | |
| 'attendance': '/api/v1/attendance', | |
| 'learning_analytics': '/api/v1/learning_analytics', | |
| 'enrollments': '/api/v1/enrollments', | |
| 'compliance': '/api/v1/compliance' | |
| } | |
| # Integration state | |
| self.is_initialized = False | |
| self.compliance_standards: List[EducationComplianceStandard] = [] | |
| self.encryption_keys: Dict[str, str] = {} | |
| self.access_policies: Dict[str, Dict[str, Any]] = {} | |
| self.audit_logs: List[Dict[str, Any]] = [] | |
| self.student_workflows: Dict[str, Dict[str, Any]] = {} | |
| self.learning_pathways: Dict[str, Dict[str, Any]] = {} | |
| self.assessment_rubrics: Dict[str, Dict[str, Any]] = {} | |
| # LMS integration | |
| self.lms_integration = None | |
| if self.education_config['lms_integration']: | |
| self.lms_integration = self._initialize_lms_integration() | |
| # Student Information System integration | |
| self.sis_integration = None | |
| if self.education_config['student_information_system']: | |
| self.sis_integration = self._initialize_sis_integration() | |
| # Enterprise integration (use safe defaults if optional services didn't import) | |
| self.enterprise_security = config.get('security_service') or globals().get('atom_enterprise_security_service') | |
| self.enterprise_automation = config.get('automation_service') or globals().get('atom_workflow_automation_service') | |
| self.ai_service = config.get('ai_service') or globals().get('ai_enhanced_service') | |
| # Platform integrations (use safe defaults if optional services didn't import) | |
| self.platform_integrations = {} | |
| _slack = globals().get('atom_slack_integration') | |
| if _slack: | |
| self.platform_integrations['slack'] = _slack | |
| _teams = globals().get('atom_teams_integration') | |
| if _teams: | |
| self.platform_integrations['teams'] = _teams | |
| _google_chat = globals().get('atom_google_chat_integration') | |
| if _google_chat: | |
| self.platform_integrations['google_chat'] = _google_chat | |
| _discord = globals().get('atom_discord_integration') | |
| if _discord: | |
| self.platform_integrations['discord'] = _discord | |
| _telegram = globals().get('atom_telegram_integration') | |
| if _telegram: | |
| self.platform_integrations['telegram'] = _telegram | |
| _whatsapp = globals().get('atom_whatsapp_integration') | |
| if _whatsapp: | |
| self.platform_integrations['whatsapp'] = _whatsapp | |
| _zoom = globals().get('atom_zoom_integration') | |
| if _zoom: | |
| self.platform_integrations['zoom'] = _zoom | |
| # Analytics and monitoring | |
| self.analytics_metrics = { | |
| 'total_students': 0, | |
| 'active_students': 0, | |
| 'total_courses': 0, | |
| 'total_instructors': 0, | |
| 'total_assignments': 0, | |
| 'total_grades': 0, | |
| 'average_gpa': 0.0, | |
| 'average_attendance': 0.0, | |
| 'course_completion_rate': 0.0, | |
| 'student_satisfaction': 0.0, | |
| 'learning_outcomes_achievement': 0.0, | |
| 'engagement_score': 0.0, | |
| 'dropout_rate': 0.0, | |
| 'graduation_rate': 0.0, | |
| 'compliance_score': 0.0, | |
| 'educational_ai_accuracy': 0.0, | |
| 'personalized_learning_effectiveness': 0.0, | |
| 'automated_grading_accuracy': 0.0, | |
| 'plagiarism_detection_accuracy': 0.0, | |
| 'grade_level_distribution': defaultdict(int), | |
| 'course_difficulty_distribution': defaultdict(int), | |
| 'department_performance': defaultdict(dict), | |
| 'instructor_performance': defaultdict(dict), | |
| 'student_performance': defaultdict(list), | |
| 'learning_objectives_mastery': defaultdict(float) | |
| } | |
| # Performance metrics | |
| self.performance_metrics = { | |
| 'api_response_time': 0.0, | |
| 'educational_ai_processing_time': 0.0, | |
| 'compliance_check_time': 0.0, | |
| 'encryption_processing_time': 0.0, | |
| 'audit_log_processing_time': 0.0, | |
| 'student_data_sync_time': 0.0, | |
| 'lms_sync_time': 0.0, | |
| 'analytics_generation_time': 0.0 | |
| } | |
| logger.info("Education Customization Service initialized") | |
| async def initialize(self) -> bool: | |
| """Initialize Education Customization Service""" | |
| try: | |
| # Setup FERPA compliance | |
| await self._setup_ferpa_compliance() | |
| # Initialize LMS integration | |
| if self.lms_integration: | |
| await self._initialize_lms_connection() | |
| # Initialize SIS integration | |
| if self.sis_integration: | |
| await self._initialize_sis_connection() | |
| # Setup encryption and security | |
| await self._setup_encryption_and_security() | |
| # Setup audit logging | |
| await self._setup_audit_logging() | |
| # Setup access control | |
| await self._setup_access_control() | |
| # Setup educational AI features | |
| if self.education_config['educational_ai_enabled']: | |
| await self._setup_educational_ai() | |
| # Setup learning pathways | |
| if self.education_config['personalized_learning']: | |
| await self._setup_learning_pathways() | |
| # Setup automated grading | |
| if self.education_config['automated_grading']: | |
| await self._setup_automated_grading() | |
| # Setup plagiarism detection | |
| if self.education_config['plagiarism_detection']: | |
| await self._setup_plagiarism_detection() | |
| # Setup integrations | |
| await self._setup_integrations() | |
| # Load existing data | |
| await self._load_existing_data() | |
| # Start monitoring | |
| await self._start_monitoring() | |
| self.is_initialized = True | |
| logger.info("Education Customization Service initialized successfully") | |
| return True | |
| except Exception as e: | |
| logger.error(f"Error initializing Education Customization Service: {e}") | |
| return False | |
| async def create_student(self, student_data: Dict[str, Any], platform: str = None) -> Dict[str, Any]: | |
| """Create new student with FERPA compliance""" | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "initialize", locals()) | |
| try: | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| start_time = time.time() | |
| # Update analytics | |
| self.analytics_metrics['total_students'] += 1 | |
| self.analytics_metrics['active_students'] += 1 | |
| self.analytics_metrics['grade_level_distribution'][student_data.get('grade_level', 'undergraduate').value] += 1 | |
| # FERPA compliance check | |
| if self.education_config['ferpa_compliance']: | |
| compliance_check = await self._perform_ferpa_compliance_check(student_data) | |
| if not compliance_check['passed']: | |
| return {'success': False, 'error': compliance_check['reason']} | |
| # Educational AI analysis for learning assessment | |
| if self.education_config['educational_ai_enabled']: | |
| ai_analysis = await self._analyze_student_with_educational_ai(student_data) | |
| student_data.update(ai_analysis) | |
| # Encrypt sensitive data | |
| encrypted_data = await self._encrypt_student_data(student_data) | |
| # Prepare student payload | |
| student_payload = { | |
| 'student_id': encrypted_data['student_id'], | |
| 'student_number': encrypted_data['student_number'], | |
| 'first_name': encrypted_data['first_name'], | |
| 'last_name': encrypted_data['last_name'], | |
| 'date_of_birth': encrypted_data['date_of_birth'].isoformat(), | |
| 'grade_level': encrypted_data['grade_level'].value, | |
| 'gpa': encrypted_data['gpa'], | |
| 'major': encrypted_data['major'], | |
| 'minor': encrypted_data['minor'], | |
| 'email': encrypted_data['email'], | |
| 'phone': encrypted_data['phone'], | |
| 'address': encrypted_data['address'], | |
| 'emergency_contacts': encrypted_data['emergency_contacts'], | |
| 'enrollment_date': encrypted_data['enrollment_date'].isoformat(), | |
| 'status': encrypted_data.get('status', 'active'), | |
| 'academic_standing': encrypted_data.get('academic_standing', 'good'), | |
| 'credits_earned': encrypted_data['credits_earned'], | |
| 'attendance_rate': encrypted_data['attendance_rate'], | |
| 'courses_enrolled': encrypted_data['courses_enrolled'], | |
| 'learning_disabilities': encrypted_data['learning_disabilities'], | |
| 'special_education_needs': encrypted_data['special_education_needs'], | |
| 'parent_guardian_info': encrypted_data['parent_guardian_info'], | |
| 'last_updated': datetime.utcnow().isoformat(), | |
| 'metadata': { | |
| 'created_by': 'atom_education_service', | |
| 'ferpa_compliant': True, | |
| 'encryption_enabled': True | |
| } | |
| } | |
| # Create student via API | |
| headers = await self._get_auth_headers() | |
| async with httpx.AsyncClient() as client: | |
| response = await client.post( | |
| f"{self.config.get('base_url')}{self.api_endpoints['students']}", | |
| headers=headers, | |
| json=student_payload, | |
| timeout=30.0 | |
| ) | |
| if response.status_code == 201: | |
| student = response.json() | |
| # Update performance metrics | |
| creation_time = time.time() - start_time | |
| self.performance_metrics['api_response_time'] = creation_time | |
| # Log audit trail | |
| await self._log_audit_event('student_created', student_data, encrypted_data) | |
| # Sync with SIS | |
| if self.sis_integration: | |
| await self._sync_student_to_sis(student) | |
| # Notify relevant platforms | |
| if platform and platform in self.platform_integrations: | |
| await self._notify_platform_student_created(student, platform) | |
| # Trigger workflows | |
| await self._trigger_student_workflows(student, 'created') | |
| logger.info(f"Student created successfully: {student['student_id']}") | |
| return { | |
| 'success': True, | |
| 'student': student, | |
| 'student_id': student['student_id'], | |
| 'creation_time': creation_time | |
| } | |
| else: | |
| error_msg = f"Failed to create student: {response.status_code} - {response.text}" | |
| logger.error(error_msg) | |
| return {'success': False, 'error': error_msg} | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| logger.error(f"Error creating student: {e}") | |
| return {'success': False, 'error': str(e)} | |
| async def create_course(self, course_data: Dict[str, Any], platform: str = None) -> Dict[str, Any]: | |
| """Create new course with FERPA compliance""" | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_student", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| try: | |
| start_time = time.time() | |
| # Update analytics | |
| self.analytics_metrics['total_courses'] += 1 | |
| self.analytics_metrics['course_difficulty_distribution'][course_data.get('difficulty_level', 'intermediate')] += 1 | |
| # FERPA compliance check | |
| if self.education_config['ferpa_compliance']: | |
| compliance_check = await self._perform_ferpa_compliance_check(course_data) | |
| if not compliance_check['passed']: | |
| return {'success': False, 'error': compliance_check['reason']} | |
| # Educational AI analysis for course optimization | |
| if self.education_config['educational_ai_enabled']: | |
| ai_analysis = await self._analyze_course_with_educational_ai(course_data) | |
| course_data.update(ai_analysis) | |
| # Prepare course payload | |
| course_payload = { | |
| 'course_id': course_data['course_id'], | |
| 'course_code': course_data['course_code'], | |
| 'title': course_data['title'], | |
| 'description': course_data['description'], | |
| 'instructor_id': course_data['instructor_id'], | |
| 'department': course_data['department'], | |
| 'course_type': course_data['course_type'].value, | |
| 'credits': course_data['credits'], | |
| 'max_capacity': course_data['max_capacity'], | |
| 'current_enrollment': course_data['current_enrollment'], | |
| 'start_date': course_data['start_date'].isoformat(), | |
| 'end_date': course_data['end_date'].isoformat(), | |
| 'schedule': course_data['schedule'], | |
| 'learning_objectives': course_data['learning_objectives'], | |
| 'required_materials': course_data['required_materials'], | |
| 'assessment_methods': course_data['assessment_methods'], | |
| 'difficulty_level': course_data['difficulty_level'], | |
| 'prerequisites': course_data['prerequisites'], | |
| 'created_at': datetime.utcnow().isoformat(), | |
| 'updated_at': datetime.utcnow().isoformat(), | |
| 'metadata': { | |
| 'created_by': 'atom_education_service', | |
| 'ferpa_compliant': True, | |
| 'educational_ai_enabled': self.education_config['educational_ai_enabled'] | |
| } | |
| } | |
| # Create course via API | |
| headers = await self._get_auth_headers() | |
| async with httpx.AsyncClient() as client: | |
| response = await client.post( | |
| f"{self.config.get('base_url')}{self.api_endpoints['courses']}", | |
| headers=headers, | |
| json=course_payload, | |
| timeout=30.0 | |
| ) | |
| if response.status_code == 201: | |
| course = response.json() | |
| # Update performance metrics | |
| creation_time = time.time() - start_time | |
| self.performance_metrics['api_response_time'] = creation_time | |
| # Log audit trail | |
| await self._log_audit_event('course_created', course_data, course_payload) | |
| # Sync with LMS | |
| if self.lms_integration: | |
| await self._sync_course_to_lms(course) | |
| # Notify relevant platforms | |
| if platform and platform in self.platform_integrations: | |
| await self._notify_platform_course_created(course, platform) | |
| # Trigger workflows | |
| await self._trigger_course_workflows(course, 'created') | |
| logger.info(f"Course created successfully: {course['course_id']}") | |
| return { | |
| 'success': True, | |
| 'course': course, | |
| 'course_id': course['course_id'], | |
| 'creation_time': creation_time | |
| } | |
| else: | |
| error_msg = f"Failed to create course: {response.status_code} - {response.text}" | |
| logger.error(error_msg) | |
| return {'success': False, 'error': error_msg} | |
| except Exception as e: | |
| logger.error(f"Error creating course: {e}") | |
| return {'success': False, 'error': str(e)} | |
| async def create_assignment(self, assignment_data: Dict[str, Any], platform: str = None) -> Dict[str, Any]: | |
| """Create new assignment with FERPA compliance""" | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_course", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| try: | |
| start_time = time.time() | |
| # Update analytics | |
| self.analytics_metrics['total_assignments'] += 1 | |
| # FERPA compliance check | |
| if self.education_config['ferpa_compliance']: | |
| compliance_check = await self._perform_ferpa_compliance_check(assignment_data) | |
| if not compliance_check['passed']: | |
| return {'success': False, 'error': compliance_check['reason']} | |
| # Educational AI analysis for assignment optimization | |
| if self.education_config['educational_ai_enabled']: | |
| ai_analysis = await self._analyze_assignment_with_educational_ai(assignment_data) | |
| assignment_data.update(ai_analysis) | |
| # Prepare assignment payload | |
| assignment_payload = { | |
| 'assignment_id': assignment_data['assignment_id'], | |
| 'course_id': assignment_data['course_id'], | |
| 'title': assignment_data['title'], | |
| 'description': assignment_data['description'], | |
| 'assignment_type': assignment_data['assignment_type'], | |
| 'due_date': assignment_data['due_date'].isoformat(), | |
| 'points_possible': assignment_data['points_possible'], | |
| 'learning_objectives': assignment_data['learning_objectives'], | |
| 'rubric': assignment_data['rubric'], | |
| 'submission_type': assignment_data['submission_type'], | |
| 'allowed_late_submission': assignment_data['allowed_late_submission'], | |
| 'late_penalty': assignment_data['late_penalty'], | |
| 'created_at': datetime.utcnow().isoformat(), | |
| 'updated_at': datetime.utcnow().isoformat(), | |
| 'metadata': { | |
| 'created_by': 'atom_education_service', | |
| 'ferpa_compliant': True, | |
| 'educational_ai_enabled': self.education_config['educational_ai_enabled'], | |
| 'automated_grading_enabled': self.education_config['automated_grading'], | |
| 'plagiarism_detection_enabled': self.education_config['plagiarism_detection'] | |
| } | |
| } | |
| # Create assignment via API | |
| headers = await self._get_auth_headers() | |
| async with httpx.AsyncClient() as client: | |
| response = await client.post( | |
| f"{self.config.get('base_url')}{self.api_endpoints['assignments']}", | |
| headers=headers, | |
| json=assignment_payload, | |
| timeout=30.0 | |
| ) | |
| if response.status_code == 201: | |
| assignment = response.json() | |
| # Update performance metrics | |
| creation_time = time.time() - start_time | |
| self.performance_metrics['api_response_time'] = creation_time | |
| # Log audit trail | |
| await self._log_audit_event('assignment_created', assignment_data, assignment_payload) | |
| # Sync with LMS | |
| if self.lms_integration: | |
| await self._sync_assignment_to_lms(assignment) | |
| # Notify relevant platforms | |
| if platform and platform in self.platform_integrations: | |
| await self._notify_platform_assignment_created(assignment, platform) | |
| # Trigger workflows | |
| await self._trigger_assignment_workflows(assignment, 'created') | |
| logger.info(f"Assignment created successfully: {assignment['assignment_id']}") | |
| return { | |
| 'success': True, | |
| 'assignment': assignment, | |
| 'assignment_id': assignment['assignment_id'], | |
| 'creation_time': creation_time | |
| } | |
| else: | |
| error_msg = f"Failed to create assignment: {response.status_code} - {response.text}" | |
| logger.error(error_msg) | |
| return {'success': False, 'error': error_msg} | |
| except Exception as e: | |
| logger.error(f"Error creating assignment: {e}") | |
| return {'success': False, 'error': str(e)} | |
| async def generate_learning_analytics(self, analytics_type: LearningAnalyticsType, | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "generate_learning_analytics", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| time_period: str = '7d', student_id: str = None, | |
| course_id: str = None, instructor_id: str = None) -> Dict[str, Any]: | |
| """Generate learning analytics with FERPA compliance""" | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_assignment", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| try: | |
| start_time = time.time() | |
| # Calculate date range | |
| end_date = datetime.utcnow() | |
| start_date = end_date - timedelta(days=7) # Default to 7 days | |
| # FERPA compliance check for analytics | |
| if self.education_config['ferpa_compliance']: | |
| compliance_check = await self._verify_analytics_compliance(analytics_type, student_id) | |
| if not compliance_check['passed']: | |
| return {'success': False, 'error': compliance_check['reason']} | |
| # Generate analytics based on type | |
| if analytics_type == LearningAnalyticsType.STUDENT_PERFORMANCE: | |
| analytics_data = await self._generate_student_performance_analytics(start_date, end_date, student_id, course_id) | |
| elif analytics_type == LearningAnalyticsType.COURSE_EFFECTIVENESS: | |
| analytics_data = await self._generate_course_effectiveness_analytics(start_date, end_date, course_id, instructor_id) | |
| elif analytics_type == LearningAnalyticsType.TEACHER_PERFORMANCE: | |
| analytics_data = await self._generate_teacher_performance_analytics(start_date, end_date, instructor_id, course_id) | |
| elif analytics_type == LearningAnalyticsType.LEARNING_OUTCOMES: | |
| analytics_data = await self._generate_learning_outcomes_analytics(start_date, end_date, course_id, student_id) | |
| elif analytics_type == LearningAnalyticsType.ENGAGEMENT_METRICS: | |
| analytics_data = await self._generate_engagement_metrics_analytics(start_date, end_date, student_id, course_id) | |
| elif analytics_type == LearningAnalyticsType.DROPOUT_PREDICTION: | |
| analytics_data = await self._generate_dropout_prediction_analytics(start_date, end_date, student_id) | |
| elif analytics_type == LearningAnalyticsType.ATTENDANCE_ANALYTICS: | |
| analytics_data = await self._generate_attendance_analytics(start_date, end_date, student_id, course_id) | |
| elif analytics_type == LearningAnalyticsType.SKILL_ASSESSMENT: | |
| analytics_data = await self._generate_skill_assessment_analytics(start_date, end_date, student_id, course_id) | |
| else: | |
| analytics_data = {'error': 'Unsupported analytics type'} | |
| # Add educational AI-powered insights | |
| if self.education_config['educational_ai_enabled']: | |
| insights = await self._generate_educational_ai_insights(analytics_data, analytics_type) | |
| analytics_data['ai_insights'] = insights | |
| # Create analytics object | |
| analytics = LearningAnalytics( | |
| analytics_id=f"analytics_{int(time.time())}", | |
| analytics_type=analytics_type, | |
| time_period=time_period, | |
| start_date=start_date, | |
| end_date=end_date, | |
| student_id=student_id, | |
| course_id=course_id, | |
| instructor_id=instructor_id, | |
| metrics=analytics_data, | |
| insights=analytics_data.get('insights', []), | |
| recommendations=analytics_data.get('recommendations', []), | |
| created_at=datetime.utcnow(), | |
| metadata={'generated_by': 'atom_education_service', 'ferpa_compliant': True} | |
| ) | |
| # Update performance metrics | |
| generation_time = time.time() - start_time | |
| self.performance_metrics['analytics_generation_time'] = generation_time | |
| return { | |
| 'success': True, | |
| 'analytics': asdict(analytics), | |
| 'generation_time': generation_time | |
| } | |
| except Exception as e: | |
| logger.error(f"Error generating learning analytics: {e}") | |
| return {'success': False, 'error': str(e)} | |
| async def _analyze_student_with_educational_ai(self, student_data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Analyze student data with educational AI""" | |
| start_time = time.time() | |
| # Prepare AI request for student analysis | |
| ai_request = AIRequest( | |
| request_id=f"student_analysis_{int(time.time())}", | |
| task_type=AITaskType.PREDICTION, | |
| model_type=AIModelType.GPT_4, | |
| service_type=AIServiceType.OPENAI, | |
| input_data={ | |
| 'student_data': student_data, | |
| 'context': 'educational_student_analysis', | |
| 'analysis_types': [ | |
| 'learning_style', 'academic_potential', 'at_risk_factors', | |
| 'personalized_learning_path', 'intervention_needs', | |
| 'subject_strengths', 'subject_weaknesses', 'motivation_factors' | |
| ] | |
| }, | |
| context={ | |
| 'platform': 'education', | |
| 'task': 'student_analysis', | |
| 'ferpa_compliant': True | |
| }, | |
| platform='education' | |
| ) | |
| ai_response = await self.ai_service.process_ai_request(ai_request) | |
| if ai_response.ok and ai_response.output_data: | |
| analysis_result = ai_response.output_data | |
| educational_ai_suggestions = { | |
| 'learning_style': analysis_result.get('learning_style', 'visual'), | |
| 'academic_potential_score': analysis_result.get('academic_potential_score', 0.7), | |
| 'at_risk_factors': analysis_result.get('at_risk_factors', []), | |
| 'personalized_learning_path': analysis_result.get('personalized_learning_path', {}), | |
| 'intervention_needs': analysis_result.get('intervention_needs', []), | |
| 'subject_strengths': analysis_result.get('subject_strengths', []), | |
| 'subject_weaknesses': analysis_result.get('subject_weaknesses', []), | |
| 'motivation_factors': analysis_result.get('motivation_factors', []), | |
| 'learning_preferences': analysis_result.get('learning_preferences', {}), | |
| 'study_recommendations': analysis_result.get('study_recommendations', []), | |
| 'career_suggestions': analysis_result.get('career_suggestions', []) | |
| } | |
| else: | |
| educational_ai_suggestions = { | |
| 'learning_style': 'visual', | |
| 'academic_potential_score': 0.7, | |
| 'at_risk_factors': [], | |
| 'personalized_learning_path': {}, | |
| 'intervention_needs': [], | |
| 'subject_strengths': [], | |
| 'subject_weaknesses': [], | |
| 'motivation_factors': [], | |
| 'learning_preferences': {}, | |
| 'study_recommendations': [], | |
| 'career_suggestions': [] | |
| } | |
| # Update performance metrics | |
| analysis_time = time.time() - start_time | |
| self.performance_metrics['educational_ai_processing_time'] = analysis_time | |
| # Update analytics | |
| self.analytics_metrics['educational_ai_accuracy'] = ( | |
| (self.analytics_metrics['educational_ai_accuracy'] * 0.9 + 0.1) # Simplified accuracy calculation | |
| ) | |
| return educational_ai_suggestions | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error analyzing student with educational AI: {e}") | |
| return { | |
| 'learning_style': 'visual', | |
| 'academic_potential_score': 0.7, | |
| 'at_risk_factors': [], | |
| 'personalized_learning_path': {}, | |
| 'intervention_needs': [], | |
| 'subject_strengths': [], | |
| 'subject_weaknesses': [], | |
| 'motivation_factors': [], | |
| 'learning_preferences': {}, | |
| 'study_recommendations': [], | |
| 'career_suggestions': [] | |
| } | |
| async def _analyze_course_with_educational_ai(self, course_data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Analyze course data with educational AI""" | |
| start_time = time.time() | |
| # Prepare AI request for course analysis | |
| ai_request = AIRequest( | |
| request_id=f"course_analysis_{int(time.time())}", | |
| task_type=AITaskType.CONTENT_ANALYSIS, | |
| model_type=AIModelType.GPT_4, | |
| service_type=AIServiceType.OPENAI, | |
| input_data={ | |
| 'course_data': course_data, | |
| 'context': 'educational_course_analysis', | |
| 'analysis_types': [ | |
| 'course_optimization', 'content_difficulty', 'student_engagement', | |
| 'assessment_alignment', 'learning_objective_achievement', | |
| 'prerequisite_effectiveness', 'teaching_strategy_recommendations' | |
| ] | |
| }, | |
| context={ | |
| 'platform': 'education', | |
| 'task': 'course_analysis', | |
| 'ferpa_compliant': True | |
| }, | |
| platform='education' | |
| ) | |
| ai_response = await self.ai_service.process_ai_request(ai_request) | |
| if ai_response.ok and ai_response.output_data: | |
| analysis_result = ai_response.output_data | |
| educational_ai_suggestions = { | |
| 'course_optimization_tips': analysis_result.get('course_optimization_tips', []), | |
| 'content_difficulty_score': analysis_result.get('content_difficulty_score', 0.5), | |
| 'predicted_student_engagement': analysis_result.get('predicted_student_engagement', 0.7), | |
| 'assessment_alignment_score': analysis_result.get('assessment_alignment_score', 0.8), | |
| 'learning_objective_achievement_score': analysis_result.get('learning_objective_achievement_score', 0.75), | |
| 'prerequisite_effectiveness': analysis_result.get('prerequisite_effectiveness', 0.8), | |
| 'teaching_strategy_recommendations': analysis_result.get('teaching_strategy_recommendations', []), | |
| 'content_recommendations': analysis_result.get('content_recommendations', []), | |
| 'technology_integration_suggestions': analysis_result.get('technology_integration_suggestions', []), | |
| 'inclusive_design_recommendations': analysis_result.get('inclusive_design_recommendations', []) | |
| } | |
| else: | |
| educational_ai_suggestions = { | |
| 'course_optimization_tips': [], | |
| 'content_difficulty_score': 0.5, | |
| 'predicted_student_engagement': 0.7, | |
| 'assessment_alignment_score': 0.8, | |
| 'learning_objective_achievement_score': 0.75, | |
| 'prerequisite_effectiveness': 0.8, | |
| 'teaching_strategy_recommendations': [], | |
| 'content_recommendations': [], | |
| 'technology_integration_suggestions': [], | |
| 'inclusive_design_recommendations': [] | |
| } | |
| # Update performance metrics | |
| analysis_time = time.time() - start_time | |
| self.performance_metrics['educational_ai_processing_time'] = analysis_time | |
| return educational_ai_suggestions | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error analyzing course with educational AI: {e}") | |
| return { | |
| 'course_optimization_tips': [], | |
| 'content_difficulty_score': 0.5, | |
| 'predicted_student_engagement': 0.7, | |
| 'assessment_alignment_score': 0.8, | |
| 'learning_objective_achievement_score': 0.75, | |
| 'prerequisite_effectiveness': 0.8, | |
| 'teaching_strategy_recommendations': [], | |
| 'content_recommendations': [], | |
| 'technology_integration_suggestions': [], | |
| 'inclusive_design_recommendations': [] | |
| } | |
| async def _analyze_assignment_with_educational_ai(self, assignment_data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Analyze assignment data with educational AI""" | |
| start_time = time.time() | |
| # Prepare AI request for assignment analysis | |
| ai_request = AIRequest( | |
| request_id=f"assignment_analysis_{int(time.time())}", | |
| task_type=AITaskType.CONTENT_ANALYSIS, | |
| model_type=AIModelType.GPT_4, | |
| service_type=AIServiceType.OPENAI, | |
| input_data={ | |
| 'assignment_data': assignment_data, | |
| 'context': 'educational_assignment_analysis', | |
| 'analysis_types': [ | |
| 'assignment_effectiveness', 'difficulty_level', 'time_estimation', | |
| 'learning_objective_alignment', 'assessment_quality', | |
| 'feedback_guidelines', 'personalization_opportunities' | |
| ] | |
| }, | |
| context={ | |
| 'platform': 'education', | |
| 'task': 'assignment_analysis', | |
| 'ferpa_compliant': True | |
| }, | |
| platform='education' | |
| ) | |
| ai_response = await self.ai_service.process_ai_request(ai_request) | |
| if ai_response.ok and ai_response.output_data: | |
| analysis_result = ai_response.output_data | |
| educational_ai_suggestions = { | |
| 'assignment_effectiveness_score': analysis_result.get('assignment_effectiveness_score', 0.7), | |
| 'difficulty_level_adjustment': analysis_result.get('difficulty_level_adjustment', 'intermediate'), | |
| 'estimated_completion_time': analysis_result.get('estimated_completion_time', 120), # minutes | |
| 'learning_objective_alignment_score': analysis_result.get('learning_objective_alignment_score', 0.8), | |
| 'assessment_quality_score': analysis_result.get('assessment_quality_score', 0.75), | |
| 'feedback_guidelines': analysis_result.get('feedback_guidelines', []), | |
| 'personalization_opportunities': analysis_result.get('personalization_opportunities', []), | |
| 'rubric_enhancements': analysis_result.get('rubric_enhancements', {}), | |
| 'scaffolded_instructions': analysis_result.get('scaffolded_instructions', []), | |
| 'alternative_assessment_methods': analysis_result.get('alternative_assessment_methods', []) | |
| } | |
| else: | |
| educational_ai_suggestions = { | |
| 'assignment_effectiveness_score': 0.7, | |
| 'difficulty_level_adjustment': 'intermediate', | |
| 'estimated_completion_time': 120, | |
| 'learning_objective_alignment_score': 0.8, | |
| 'assessment_quality_score': 0.75, | |
| 'feedback_guidelines': [], | |
| 'personalization_opportunities': [], | |
| 'rubric_enhancements': {}, | |
| 'scaffolded_instructions': [], | |
| 'alternative_assessment_methods': [] | |
| } | |
| # Update performance metrics | |
| analysis_time = time.time() - start_time | |
| self.performance_metrics['educational_ai_processing_time'] = analysis_time | |
| return educational_ai_suggestions | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error analyzing assignment with educational AI: {e}") | |
| return { | |
| 'assignment_effectiveness_score': 0.7, | |
| 'difficulty_level_adjustment': 'intermediate', | |
| 'estimated_completion_time': 120, | |
| 'learning_objective_alignment_score': 0.8, | |
| 'assessment_quality_score': 0.75, | |
| 'feedback_guidelines': [], | |
| 'personalization_opportunities': [], | |
| 'rubric_enhancements': {}, | |
| 'scaffolded_instructions': [], | |
| 'alternative_assessment_methods': [] | |
| } | |
| async def _setup_ferpa_compliance(self): | |
| """Setup FERPA compliance""" | |
| # Initialize compliance standards | |
| self.compliance_standards = [ | |
| EducationComplianceStandard.FERPA, | |
| EducationComplianceStandard.COPPA, | |
| EducationComplianceStandard.IDEA, | |
| EducationComplianceStandard.ADA, | |
| EducationComplianceStandard.GDPR | |
| ] | |
| # Setup encryption | |
| self.encryption_keys = { | |
| 'data_encryption_key': os.getenv('EDUCATION_ENCRYPTION_KEY', 'default_key'), | |
| 'audit_encryption_key': os.getenv('EDUCATION_AUDIT_KEY', 'default_audit_key') | |
| } | |
| logger.info("FERPA compliance setup completed") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error setting up FERPA compliance: {e}") | |
| raise | |
| async def _encrypt_student_data(self, student_data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Encrypt student sensitive data""" | |
| start_time = time.time() | |
| # In production, this would use proper encryption algorithms | |
| encrypted_data = student_data.copy() | |
| # Encrypt sensitive fields | |
| sensitive_fields = ['first_name', 'last_name', 'date_of_birth', 'address', 'emergency_contacts', 'parent_guardian_info'] | |
| for field in sensitive_fields: | |
| if field in encrypted_data: | |
| # Simple encoding for demonstration - use proper encryption in production | |
| encrypted_data[field] = base64.b64encode(str(encrypted_data[field]).encode()).decode() | |
| # Update performance metrics | |
| encryption_time = time.time() - start_time | |
| self.performance_metrics['encryption_processing_time'] = encryption_time | |
| return encrypted_data | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error encrypting student data: {e}") | |
| return student_data | |
| async def _log_audit_event(self, event_type: str, original_data: Dict[str, Any], | |
| processed_data: Dict[str, Any]): | |
| """Log audit event for FERPA compliance""" | |
| start_time = time.time() | |
| audit_event = { | |
| 'event_id': f"audit_{int(time.time())}", | |
| 'event_type': event_type, | |
| 'timestamp': datetime.utcnow().isoformat(), | |
| 'user_id': 'atom_education_service', | |
| 'action': 'create', | |
| 'resource_type': event_type.replace('_created', ''), | |
| 'original_data_hash': hashlib.sha256(str(original_data).encode()).hexdigest(), | |
| 'processed_data_hash': hashlib.sha256(str(processed_data).encode()).hexdigest(), | |
| 'compliance_standards': [standard.value for standard in self.compliance_standards], | |
| 'encryption_used': True, | |
| 'access_level': 'authorized' | |
| } | |
| self.audit_logs.append(audit_event) | |
| # Update performance metrics | |
| audit_time = time.time() - start_time | |
| self.performance_metrics['audit_log_processing_time'] = audit_time | |
| # Update analytics | |
| self.analytics_metrics['compliance_score'] = min( | |
| (self.analytics_metrics['compliance_score'] * 0.9 + 0.1), 1.0 | |
| ) | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error logging audit event: {e}") | |
| async def _perform_ferpa_compliance_check(self, data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Perform FERPA compliance check""" | |
| start_time = time.time() | |
| # Check for required FERPA elements | |
| phi_elements = ['first_name', 'last_name', 'date_of_birth', 'address'] | |
| phi_present = any(element in data for element in phi_elements) | |
| # Check for proper encryption requirements | |
| encryption_required = self.education_config['encryption_in_transit'] | |
| # Check for audit logging requirements | |
| audit_required = self.education_config['audit_logging'] | |
| # Check for access control requirements | |
| access_control_required = self.education_config['access_control'] | |
| compliance_result = { | |
| 'passed': True, | |
| 'reason': 'Compliant with FERPA standards', | |
| 'phi_present': phi_present, | |
| 'encryption_required': encryption_required, | |
| 'audit_required': audit_required, | |
| 'access_control_required': access_control_required | |
| } | |
| # Update performance metrics | |
| compliance_time = time.time() - start_time | |
| self.performance_metrics['compliance_check_time'] = compliance_time | |
| return compliance_result | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error performing FERPA compliance check: {e}") | |
| return {'passed': False, 'reason': str(e)} | |
| async def _initialize_lms_integration(self): | |
| """Initialize LMS system integration""" | |
| from atom_canvas_integration import atom_canvas_integration | |
| self.lms_integration = atom_canvas_integration | |
| logger.info("LMS integration initialized") | |
| except ImportError: | |
| logger.warning("LMS integration not available") | |
| self.lms_integration = None | |
| async def _initialize_sis_integration(self): | |
| """Initialize SIS system integration""" | |
| from atom_power_school_integration import atom_power_school_integration | |
| self.sis_integration = atom_power_school_integration | |
| logger.info("SIS integration initialized") | |
| except ImportError: | |
| logger.warning("SIS integration not available") | |
| self.sis_integration = None | |
| async def _initialize_lms_connection(self): | |
| """Initialize LMS connection""" | |
| # Test LMS connection | |
| if self.lms_integration: | |
| connection_test = await self.lms_integration.test_connection() | |
| if connection_test: | |
| logger.info("LMS connection established successfully") | |
| else: | |
| raise Exception("LMS connection test failed") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"LMS connection failed: {e}") | |
| raise | |
| async def _initialize_sis_connection(self): | |
| """Initialize SIS connection""" | |
| # Test SIS connection | |
| if self.sis_integration: | |
| connection_test = await self.sis_integration.test_connection() | |
| if connection_test: | |
| logger.info("SIS connection established successfully") | |
| else: | |
| raise Exception("SIS connection test failed") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"SIS connection failed: {e}") | |
| raise | |
| async def _sync_student_to_sis(self, student: Dict[str, Any]): | |
| """Sync student to SIS system""" | |
| if self.sis_integration: | |
| await self.sis_integration.create_student(student) | |
| logger.info(f"Student synced to SIS: {student['student_id']}") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error syncing student to SIS: {e}") | |
| async def _sync_course_to_lms(self, course: Dict[str, Any]): | |
| """Sync course to LMS system""" | |
| if self.lms_integration: | |
| await self.lms_integration.create_course(course) | |
| logger.info(f"Course synced to LMS: {course['course_id']}") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error syncing course to LMS: {e}") | |
| async def _sync_assignment_to_lms(self, assignment: Dict[str, Any]): | |
| """Sync assignment to LMS system""" | |
| if self.lms_integration: | |
| await self.lms_integration.create_assignment(assignment) | |
| logger.info(f"Assignment synced to LMS: {assignment['assignment_id']}") | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| return {'ok': False, 'error': str(e)} | |
| logger.error(f"Error syncing assignment to LMS: {e}") | |
| async def _get_auth_headers(self) -> Dict[str, str]: | |
| """Get authentication headers for education API""" | |
| return { | |
| 'Authorization': f"Bearer {self.config.get('education_api_token')}", | |
| 'Content-Type': 'application/json', | |
| 'X-FERPA-Compliant': 'true', | |
| 'X-Encryption-Key': self.encryption_keys['data_encryption_key'] | |
| } | |
| async def get_service_status(self) -> Dict[str, Any]: | |
| """Get Education Customization service status""" | |
| return { | |
| 'service': 'education_customization', | |
| 'status': 'active' if self.is_initialized else 'inactive', | |
| 'education_config': { | |
| 'ferpa_compliance': self.education_config['ferpa_compliance'], | |
| 'coppa_compliance': self.education_config['coppa_compliance'], | |
| 'idea_compliance': self.education_config['idea_compliance'], | |
| 'ada_compliance': self.education_config['ada_compliance'], | |
| 'gdpr_compliance': self.education_config['gdpr_compliance'], | |
| 'encryption_at_rest': self.education_config['encryption_at_rest'], | |
| 'encryption_in_transit': self.education_config['encryption_in_transit'], | |
| 'audit_logging': self.education_config['audit_logging'], | |
| 'access_control': self.education_config['access_control'], | |
| 'data_masking': self.education_config['data_masking'], | |
| 'parent_portal_access': self.education_config['parent_portal_access'], | |
| 'educational_ai_enabled': self.education_config['educational_ai_enabled'], | |
| 'learning_analytics': self.education_config['learning_analytics'], | |
| 'personalized_learning': self.education_config['personalized_learning'], | |
| 'automated_grading': self.education_config['automated_grading'], | |
| 'plagiarism_detection': self.education_config['plagiarism_detection'], | |
| 'attendance_tracking': self.education_config['attendance_tracking'], | |
| 'student_performance_prediction': self.education_config['student_performance_prediction'], | |
| 'lms_integration': self.education_config['lms_integration'], | |
| 'student_information_system': self.education_config['student_information_system'] | |
| }, | |
| 'compliance_standards': [standard.value for standard in self.compliance_standards], | |
| 'analytics_metrics': self.analytics_metrics, | |
| 'performance_metrics': self.performance_metrics, | |
| 'uptime': time.time() - (self._start_time if hasattr(self, '_start_time') else time.time()) | |
| } | |
| except Exception as e: | |
| logger.error(f"Operation failed: {e}") | |
| log_integration_complete(audit_ctx, error=e) | |
| logger.error(f"Error getting service status: {e}") | |
| return {'error': str(e), 'service': 'education_customization'} | |
| async def close(self): | |
| """Close Education Customization Service""" | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "get_service_status", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) | |
| try: | |
| logger.info("Education Customization Service closed") | |
| except Exception as e: | |
| logger.error(f"Error closing Education Customization Service: {e}") | |
| # Global Education Customization service instance | |
| # Use safe defaults if optional services didn't import | |
| _education_config = { | |
| 'ferpa_compliance': True, | |
| 'coppa_compliance': True, | |
| 'idea_compliance': True, | |
| 'ada_compliance': True, | |
| 'gdpr_compliance': True, | |
| 'encryption_at_rest': True, | |
| 'encryption_in_transit': True, | |
| 'audit_logging': True, | |
| 'access_control': True, | |
| 'data_masking': True, | |
| 'retention_policy': '10_years', | |
| 'parent_portal_access': True, | |
| 'educational_ai_enabled': True, | |
| 'learning_analytics': True, | |
| 'personalized_learning': True, | |
| 'automated_grading': True, | |
| 'plagiarism_detection': True, | |
| 'attendance_tracking': True, | |
| 'student_performance_prediction': True, | |
| 'lms_integration': True, | |
| 'student_information_system': True, | |
| 'base_url': os.getenv('EDUCATION_API_URL', 'https://api.education.example.com'), | |
| 'education_api_token': os.getenv('EDUCATION_API_TOKEN', 'your-api-token'), | |
| 'database': None, # Would be actual database connection | |
| 'cache': None, # Would be actual cache client | |
| } | |
| # Add optional services if they were imported successfully | |
| _security_service = globals().get('atom_enterprise_security_service') | |
| if _security_service: | |
| _education_config['security_service'] = _security_service | |
| _automation_service = globals().get('atom_workflow_automation_service') | |
| if _automation_service: | |
| _education_config['automation_service'] = _automation_service | |
| _ai_service = globals().get('ai_enhanced_service') | |
| if _ai_service: | |
| _education_config['ai_service'] = _ai_service | |
| atom_education_customization_service = AtomEducationCustomizationService(_education_config) | |
| # Start audit logging | |
| audit_ctx = log_integration_attempt("atom_education_customization", "close", locals()) | |
| # Check circuit breaker | |
| if not await circuit_breaker.is_enabled("atom_education_customization"): | |
| logger.warning(f"Circuit breaker is open for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Circuit breaker open")) | |
| raise HTTPException( | |
| status_code=503, | |
| detail=f"Atom_education_customization integration temporarily disabled" | |
| ) | |
| # Check rate limiter | |
| is_limited, remaining = await rate_limiter.is_rate_limited("atom_education_customization") | |
| if is_limited: | |
| logger.warning(f"Rate limit exceeded for atom_education_customization") | |
| log_integration_complete(audit_ctx, error=Exception("Rate limit exceeded")) | |
| raise HTTPException( | |
| status_code=429, | |
| detail=f"Rate limit exceeded for atom_education_customization" | |
| ) |