Skip to main content
Glama

OpenEdu MCP Server

base.pyโ€ข6.8 kB
""" Base model classes for OpenEdu MCP Server. This module provides base classes and common functionality for all data models used throughout the application. """ from abc import ABC, abstractmethod from datetime import datetime from typing import Dict, Any, Optional from dataclasses import dataclass, field from enum import Enum class GradeLevel(Enum): """Educational grade levels.""" K_2 = "K-2" GRADES_3_5 = "3-5" GRADES_6_8 = "6-8" GRADES_9_12 = "9-12" COLLEGE = "College" @classmethod def from_string(cls, value: str) -> Optional['GradeLevel']: """Create GradeLevel from string value.""" for grade_level in cls: if grade_level.value == value: return grade_level return None @classmethod def all_values(cls) -> list[str]: """Get all grade level values.""" return [gl.value for gl in cls] class CurriculumStandard(Enum): """Curriculum standards.""" COMMON_CORE = "Common Core" NGSS = "NGSS" STATE_STANDARDS = "State Standards" @classmethod def from_string(cls, value: str) -> Optional['CurriculumStandard']: """Create CurriculumStandard from string value.""" for standard in cls: if standard.value == value: return standard return None @classmethod def all_values(cls) -> list[str]: """Get all curriculum standard values.""" return [cs.value for cs in cls] class Subject(Enum): """Educational subjects.""" MATHEMATICS = "Mathematics" SCIENCE = "Science" ENGLISH_LANGUAGE_ARTS = "English Language Arts" SOCIAL_STUDIES = "Social Studies" ARTS = "Arts" PHYSICAL_EDUCATION = "Physical Education" TECHNOLOGY = "Technology" @classmethod def from_string(cls, value: str) -> Optional['Subject']: """Create Subject from string value.""" for subject in cls: if subject.value == value: return subject return None @classmethod def all_values(cls) -> list[str]: """Get all subject values.""" return [s.value for s in cls] @dataclass class BaseModel(ABC): """Base class for all data models.""" created_at: datetime = field(default_factory=datetime.now) updated_at: datetime = field(default_factory=datetime.now) @abstractmethod def to_dict(self) -> Dict[str, Any]: """Convert model to dictionary for serialization.""" pass @classmethod @abstractmethod def from_dict(cls, data: Dict[str, Any]) -> 'BaseModel': """Create model from dictionary.""" pass def update_timestamp(self) -> None: """Update the updated_at timestamp.""" self.updated_at = datetime.now() @dataclass class EducationalMetadata: """Common educational metadata for all content types.""" grade_levels: list[GradeLevel] = field(default_factory=list) curriculum_alignment: list[CurriculumStandard] = field(default_factory=list) educational_subjects: list[str] = field(default_factory=list) educational_relevance_score: float = 0.0 reading_level: Optional[str] = None difficulty_level: Optional[str] = None def to_dict(self) -> Dict[str, Any]: """Convert to dictionary.""" return { "grade_levels": [gl.value if hasattr(gl, 'value') else gl for gl in self.grade_levels], "curriculum_alignment": [ca.value if hasattr(ca, 'value') else ca for ca in self.curriculum_alignment], "educational_subjects": self.educational_subjects, "educational_relevance_score": self.educational_relevance_score, "reading_level": self.reading_level, "difficulty_level": self.difficulty_level } @classmethod def from_dict(cls, data: Dict[str, Any]) -> 'EducationalMetadata': """Create from dictionary.""" return cls( grade_levels=[ gl if isinstance(gl, GradeLevel) else GradeLevel.from_string(gl) for gl in data.get("grade_levels", []) if gl and (isinstance(gl, GradeLevel) or GradeLevel.from_string(gl)) ], curriculum_alignment=[ ca if isinstance(ca, CurriculumStandard) else CurriculumStandard.from_string(ca) for ca in data.get("curriculum_alignment", []) if ca and (isinstance(ca, CurriculumStandard) or CurriculumStandard.from_string(ca)) ], educational_subjects=data.get("educational_subjects", []), educational_relevance_score=data.get("educational_relevance_score", 0.0), reading_level=data.get("reading_level"), difficulty_level=data.get("difficulty_level") ) @dataclass class APIResponse: """Base class for API responses.""" success: bool data: Optional[Any] = None error: Optional[str] = None metadata: Optional[Dict[str, Any]] = None timestamp: datetime = field(default_factory=datetime.now) def to_dict(self) -> Dict[str, Any]: """Convert to dictionary.""" return { "success": self.success, "data": self.data, "error": self.error, "metadata": self.metadata, "timestamp": self.timestamp.isoformat() } @classmethod def success_response(cls, data: Any, metadata: Optional[Dict[str, Any]] = None) -> 'APIResponse': """Create a successful response.""" return cls(success=True, data=data, metadata=metadata) @classmethod def error_response(cls, error: str, metadata: Optional[Dict[str, Any]] = None) -> 'APIResponse': """Create an error response.""" return cls(success=False, error=error, metadata=metadata) @dataclass class CacheEntry: """Cache entry model.""" key: str value: Any content_type: str = "json" expires_at: datetime = field(default_factory=lambda: datetime.now()) access_count: int = 0 last_accessed: datetime = field(default_factory=datetime.now) size_bytes: int = 0 def is_expired(self) -> bool: """Check if cache entry is expired.""" return datetime.now() > self.expires_at def access(self) -> None: """Record access to this cache entry.""" self.access_count += 1 self.last_accessed = datetime.now() def to_dict(self) -> Dict[str, Any]: """Convert to dictionary.""" return { "key": self.key, "value": self.value, "content_type": self.content_type, "expires_at": self.expires_at.isoformat(), "access_count": self.access_count, "last_accessed": self.last_accessed.isoformat(), "size_bytes": self.size_bytes }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cicatriiz/openedu-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server