File size: 8,609 Bytes
411f252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
"""
Integration utilities for connecting TutorX-MCP with external educational systems
"""

import requests
import json
import os
from typing import Dict, Any, List, Optional
import logging

logger = logging.getLogger(__name__)

class LMSIntegration:
    """Integration with Learning Management Systems (Canvas, Moodle, etc.)"""
    
    def __init__(self, lms_type: str, api_url: str, api_key: str):
        """
        Initialize LMS integration
        
        Args:
            lms_type: Type of LMS ('canvas', 'moodle', 'blackboard', etc.)
            api_url: Base URL for LMS API
            api_key: API key or token for authentication
        """
        self.lms_type = lms_type.lower()
        self.api_url = api_url.rstrip('/')
        self.api_key = api_key
        
    def get_courses(self) -> List[Dict[str, Any]]:
        """Get list of courses from LMS"""
        if self.lms_type == 'canvas':
            return self._canvas_get_courses()
        elif self.lms_type == 'moodle':
            return self._moodle_get_courses()
        else:
            raise ValueError(f"Unsupported LMS type: {self.lms_type}")
            
    def _canvas_get_courses(self) -> List[Dict[str, Any]]:
        """Get courses from Canvas LMS"""
        headers = {"Authorization": f"Bearer {self.api_key}"}
        response = requests.get(f"{self.api_url}/courses", headers=headers)
        response.raise_for_status()
        return response.json()
        
    def _moodle_get_courses(self) -> List[Dict[str, Any]]:
        """Get courses from Moodle"""
        params = {
            "wstoken": self.api_key,
            "wsfunction": "core_course_get_courses",
            "moodlewsrestformat": "json"
        }
        response = requests.get(f"{self.api_url}/webservice/rest/server.php", params=params)
        response.raise_for_status()
        return response.json()
        
    def sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
        """
        Sync grades to LMS
        
        Args:
            course_id: ID of the course
            assignment_id: ID of the assignment
            grades: List of grade data to sync
            
        Returns:
            Success status
        """
        try:
            if self.lms_type == 'canvas':
                return self._canvas_sync_grades(course_id, assignment_id, grades)
            elif self.lms_type == 'moodle':
                return self._moodle_sync_grades(course_id, assignment_id, grades)
            else:
                raise ValueError(f"Unsupported LMS type: {self.lms_type}")
        except Exception as e:
            logger.error(f"Error syncing grades: {e}")
            return False
            
    def _canvas_sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
        """Sync grades to Canvas LMS"""
        headers = {"Authorization": f"Bearer {self.api_key}"}
        
        for grade in grades:
            data = {
                "submission": {
                    "posted_grade": grade["score"]
                }
            }
            
            url = f"{self.api_url}/courses/{course_id}/assignments/{assignment_id}/submissions/{grade['student_id']}"
            response = requests.put(url, json=data, headers=headers)
            
            if response.status_code != 200:
                logger.error(f"Failed to sync grade for student {grade['student_id']}: {response.text}")
                return False
                
        return True
        
    def _moodle_sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
        """Sync grades to Moodle"""
        # Implementation specific to Moodle's API
        # This would use the Moodle grade update API
        return True  # Placeholder
        
class OERIntegration:
    """Integration with Open Educational Resources repositories"""
    
    def __init__(self, repository_url: str, api_key: Optional[str] = None):
        """
        Initialize OER repository integration
        
        Args:
            repository_url: Base URL for OER repository API
            api_key: Optional API key if required by the repository
        """
        self.repository_url = repository_url.rstrip('/')
        self.api_key = api_key
        
    def search_resources(self, query: str, subject: Optional[str] = None, 
                        grade_level: Optional[str] = None) -> List[Dict[str, Any]]:
        """
        Search for educational resources
        
        Args:
            query: Search query
            subject: Optional subject filter
            grade_level: Optional grade level filter
            
        Returns:
            List of matching resources
        """
        params = {"q": query}
        
        if subject:
            params["subject"] = subject
            
        if grade_level:
            params["grade"] = grade_level
            
        headers = {}
        if self.api_key:
            headers["Authorization"] = f"Bearer {self.api_key}"
            
        response = requests.get(f"{self.repository_url}/search", params=params, headers=headers)
        response.raise_for_status()
        
        return response.json().get("results", [])
        
    def get_resource(self, resource_id: str) -> Dict[str, Any]:
        """
        Get details for a specific resource
        
        Args:
            resource_id: ID of the resource to fetch
            
        Returns:
            Resource details
        """
        headers = {}
        if self.api_key:
            headers["Authorization"] = f"Bearer {self.api_key}"
            
        response = requests.get(f"{self.repository_url}/resources/{resource_id}", headers=headers)
        response.raise_for_status()
        
        return response.json()
        

class RTPTIntegration:
    """Integration with real-time personalized tutoring platforms"""
    
    def __init__(self, platform_url: str, client_id: str, client_secret: str):
        """
        Initialize RTPT integration
        
        Args:
            platform_url: Base URL for RTPT platform API
            client_id: OAuth client ID
            client_secret: OAuth client secret
        """
        self.platform_url = platform_url.rstrip('/')
        self.client_id = client_id
        self.client_secret = client_secret
        self._access_token = None
        
    def _get_access_token(self) -> str:
        """Get OAuth access token"""
        if self._access_token:
            return self._access_token
            
        data = {
            "grant_type": "client_credentials",
            "client_id": self.client_id,
            "client_secret": self.client_secret
        }
        
        response = requests.post(f"{self.platform_url}/oauth/token", data=data)
        response.raise_for_status()
        
        token_data = response.json()
        self._access_token = token_data["access_token"]
        return self._access_token
        
    def get_available_tutors(self, subject: str, level: str) -> List[Dict[str, Any]]:
        """
        Get available tutors for a subject and level
        
        Args:
            subject: Academic subject
            level: Academic level
            
        Returns:
            List of available tutors
        """
        headers = {"Authorization": f"Bearer {self._get_access_token()}"}
        params = {
            "subject": subject,
            "level": level
        }
        
        response = requests.get(f"{self.platform_url}/tutors/available", params=params, headers=headers)
        response.raise_for_status()
        
        return response.json()
        
    def schedule_session(self, student_id: str, tutor_id: str, 
                        subject: str, datetime_str: str) -> Dict[str, Any]:
        """
        Schedule a tutoring session
        
        Args:
            student_id: ID of the student
            tutor_id: ID of the tutor
            subject: Subject for tutoring
            datetime_str: ISO format datetime for the session
            
        Returns:
            Session details
        """
        headers = {"Authorization": f"Bearer {self._get_access_token()}"}
        data = {
            "student_id": student_id,
            "tutor_id": tutor_id,
            "subject": subject,
            "datetime": datetime_str
        }
        
        response = requests.post(f"{self.platform_url}/sessions", json=data, headers=headers)
        response.raise_for_status()
        
        return response.json()