| """ |
| 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 |
|
|
|
|
| |
| 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}") |
|
|
| |
| 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" |
|
|
| @dataclass |
| 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] |
|
|
| @dataclass |
| 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] |
|
|
| @dataclass |
| 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] |
|
|
| @dataclass |
| 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] |
|
|
| @dataclass |
| 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') |
| |
| |
| 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) |
| } |
| |
| |
| 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' |
| } |
| |
| |
| 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]] = {} |
| |
| |
| self.lms_integration = None |
| if self.education_config['lms_integration']: |
| self.lms_integration = self._initialize_lms_integration() |
| |
| |
| self.sis_integration = None |
| if self.education_config['student_information_system']: |
| self.sis_integration = self._initialize_sis_integration() |
| |
| |
| 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') |
| |
| |
| 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 |
| |
| |
| 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) |
| } |
| |
| |
| 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: |
| |
| await self._setup_ferpa_compliance() |
| |
| |
| if self.lms_integration: |
| await self._initialize_lms_connection() |
| |
| |
| if self.sis_integration: |
| await self._initialize_sis_connection() |
| |
| |
| await self._setup_encryption_and_security() |
| |
| |
| await self._setup_audit_logging() |
| |
| |
| await self._setup_access_control() |
| |
| |
| if self.education_config['educational_ai_enabled']: |
| await self._setup_educational_ai() |
| |
| |
| if self.education_config['personalized_learning']: |
| await self._setup_learning_pathways() |
| |
| |
| if self.education_config['automated_grading']: |
| await self._setup_automated_grading() |
| |
| |
| if self.education_config['plagiarism_detection']: |
| await self._setup_plagiarism_detection() |
| |
| |
| await self._setup_integrations() |
| |
| |
| await self._load_existing_data() |
| |
| |
| 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""" |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "initialize", locals()) |
| try: |
| |
| 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" |
| ) |
|
|
| |
| 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() |
| |
| 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 |
| |
| 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']} |
| |
| if self.education_config['educational_ai_enabled']: |
| ai_analysis = await self._analyze_student_with_educational_ai(student_data) |
| student_data.update(ai_analysis) |
| |
| encrypted_data = await self._encrypt_student_data(student_data) |
| |
| 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 |
| } |
| } |
| |
| 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() |
| |
| creation_time = time.time() - start_time |
| self.performance_metrics['api_response_time'] = creation_time |
| |
| await self._log_audit_event('student_created', student_data, encrypted_data) |
| |
| if self.sis_integration: |
| await self._sync_student_to_sis(student) |
| |
| if platform and platform in self.platform_integrations: |
| await self._notify_platform_student_created(student, platform) |
| |
| 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""" |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_student", locals()) |
| |
| 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" |
| ) |
| |
| 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() |
| |
| |
| self.analytics_metrics['total_courses'] += 1 |
| self.analytics_metrics['course_difficulty_distribution'][course_data.get('difficulty_level', 'intermediate')] += 1 |
| |
| |
| 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']} |
| |
| |
| if self.education_config['educational_ai_enabled']: |
| ai_analysis = await self._analyze_course_with_educational_ai(course_data) |
| course_data.update(ai_analysis) |
| |
| |
| 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'] |
| } |
| } |
| |
| |
| 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() |
| |
| |
| creation_time = time.time() - start_time |
| self.performance_metrics['api_response_time'] = creation_time |
| |
| |
| await self._log_audit_event('course_created', course_data, course_payload) |
| |
| |
| if self.lms_integration: |
| await self._sync_course_to_lms(course) |
| |
| |
| if platform and platform in self.platform_integrations: |
| await self._notify_platform_course_created(course, platform) |
| |
| |
| 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""" |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_course", locals()) |
| |
| 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" |
| ) |
| |
| 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() |
| |
| |
| self.analytics_metrics['total_assignments'] += 1 |
| |
| |
| 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']} |
| |
| |
| if self.education_config['educational_ai_enabled']: |
| ai_analysis = await self._analyze_assignment_with_educational_ai(assignment_data) |
| assignment_data.update(ai_analysis) |
| |
| |
| 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'] |
| } |
| } |
| |
| |
| 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() |
| |
| |
| creation_time = time.time() - start_time |
| self.performance_metrics['api_response_time'] = creation_time |
| |
| |
| await self._log_audit_event('assignment_created', assignment_data, assignment_payload) |
| |
| |
| if self.lms_integration: |
| await self._sync_assignment_to_lms(assignment) |
| |
| |
| if platform and platform in self.platform_integrations: |
| await self._notify_platform_assignment_created(assignment, platform) |
| |
| |
| 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, |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "generate_learning_analytics", locals()) |
| |
| 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" |
| ) |
| |
| 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""" |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "create_assignment", locals()) |
| |
| 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" |
| ) |
| |
| 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() |
| |
| |
| end_date = datetime.utcnow() |
| start_date = end_date - timedelta(days=7) |
| |
| |
| 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']} |
| |
| |
| 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'} |
| |
| |
| if self.education_config['educational_ai_enabled']: |
| insights = await self._generate_educational_ai_insights(analytics_data, analytics_type) |
| analytics_data['ai_insights'] = insights |
| |
| |
| 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} |
| ) |
| |
| |
| 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() |
| |
| 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': [] |
| } |
| |
| analysis_time = time.time() - start_time |
| self.performance_metrics['educational_ai_processing_time'] = analysis_time |
| |
| self.analytics_metrics['educational_ai_accuracy'] = ( |
| (self.analytics_metrics['educational_ai_accuracy'] * 0.9 + 0.1) |
| ) |
| 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() |
| |
| 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': [] |
| } |
| |
| 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() |
| |
| 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), |
| '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': [] |
| } |
| |
| 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""" |
| |
| self.compliance_standards = [ |
| EducationComplianceStandard.FERPA, |
| EducationComplianceStandard.COPPA, |
| EducationComplianceStandard.IDEA, |
| EducationComplianceStandard.ADA, |
| EducationComplianceStandard.GDPR |
| ] |
| |
| 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() |
| |
| encrypted_data = student_data.copy() |
| |
| 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: |
| |
| encrypted_data[field] = base64.b64encode(str(encrypted_data[field]).encode()).decode() |
| |
| 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) |
| |
| audit_time = time.time() - start_time |
| self.performance_metrics['audit_log_processing_time'] = audit_time |
| |
| 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() |
| |
| phi_elements = ['first_name', 'last_name', 'date_of_birth', 'address'] |
| phi_present = any(element in data for element in phi_elements) |
| |
| encryption_required = self.education_config['encryption_in_transit'] |
| |
| audit_required = self.education_config['audit_logging'] |
| |
| 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 |
| } |
| |
| 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""" |
| |
| 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""" |
| |
| 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""" |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "get_service_status", locals()) |
| |
| 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" |
| ) |
| |
| 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}") |
|
|
| |
| |
| _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, |
| 'cache': None, |
| } |
|
|
| |
| _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) |
| |
| audit_ctx = log_integration_attempt("atom_education_customization", "close", locals()) |
| |
| 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" |
| ) |
| |
| 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" |
| ) |