Meet Patel commited on
Commit
71c0fd0
·
1 Parent(s): 3d56f3d

Fix some major issue with api and integrations

Browse files
Files changed (7) hide show
  1. .coverage +0 -0
  2. README.md +1 -16
  3. client.py +2 -49
  4. docs/api.md +0 -368
  5. docs/prd.md +2 -16
  6. main.py +2 -122
  7. utils/integrations.py +0 -251
.coverage ADDED
Binary file (53.2 kB). View file
 
README.md CHANGED
@@ -166,25 +166,10 @@ uv install -e ".[test]"
166
  python run_tests.py
167
  ```
168
 
169
- ### Integration with External Systems
170
-
171
- TutorX-MCP can integrate with various external educational systems:
172
-
173
- 1. **Learning Management Systems (LMS)**
174
- - Canvas, Moodle, Blackboard
175
- - Grade syncing and assignment management
176
-
177
- 2. **Open Educational Resources (OER)**
178
- - Search and integration with OER repositories
179
- - Access to diverse educational content
180
-
181
- 3. **Real-time Personalized Tutoring Platforms**
182
- - Schedule and manage tutoring sessions
183
- - Connect students with expert tutors
184
 
185
  ## Documentation
186
 
187
- - [API Documentation](docs/api.md): Complete API reference for developers
188
  - [MCP Protocol](docs/mcp.md): Details about the Model Context Protocol
189
  - [Product Requirements](docs/prd.md): Original requirements document
190
  - [SDK Documentation](docs/sdk.md): Client SDK usage
 
166
  python run_tests.py
167
  ```
168
 
169
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  ## Documentation
172
 
 
173
  - [MCP Protocol](docs/mcp.md): Details about the Model Context Protocol
174
  - [Product Requirements](docs/prd.md): Original requirements document
175
  - [SDK Documentation](docs/sdk.md): Client SDK usage
client.py CHANGED
@@ -190,60 +190,13 @@ class TutorXClient:
190
  return self._call_tool("get_student_analytics", {
191
  "student_id": student_id,
192
  "timeframe_days": timeframe_days
193
- })
194
- def check_submission_originality(self, submission: str, reference_sources: List[str]) -> Dict[str, Any]:
195
  """Check student submission for potential plagiarism"""
196
  return self._call_tool("check_submission_originality", {
197
  "submission": submission,
198
  "reference_sources": reference_sources
199
  })
200
-
201
- # ------------ External Integrations ------------
202
-
203
- def lms_sync_grades(self, lms_type: str, api_url: str, api_key: str,
204
- course_id: str, assignment_id: str,
205
- grades: List[Dict[str, Any]]) -> Dict[str, Any]:
206
- """Sync grades with a Learning Management System"""
207
- return self._call_tool("lms_sync_grades", {
208
- "lms_type": lms_type,
209
- "api_url": api_url,
210
- "api_key": api_key,
211
- "course_id": course_id,
212
- "assignment_id": assignment_id,
213
- "grades": grades
214
- })
215
-
216
- def oer_search(self, repository_url: str, query: str,
217
- subject: Optional[str] = None, grade_level: Optional[str] = None,
218
- api_key: Optional[str] = None) -> Dict[str, Any]:
219
- """Search for educational resources in OER repositories"""
220
- params = {
221
- "repository_url": repository_url,
222
- "query": query
223
- }
224
-
225
- if subject:
226
- params["subject"] = subject
227
-
228
- if grade_level:
229
- params["grade_level"] = grade_level
230
-
231
- if api_key:
232
- params["api_key"] = api_key
233
-
234
- return self._call_tool("oer_search", params)
235
-
236
- def schedule_tutoring_session(self, platform_url: str, client_id: str, client_secret: str,
237
- student_id: str, subject: str, datetime_str: str) -> Dict[str, Any]:
238
- """Schedule a session with a real-time personalized tutoring platform"""
239
- return self._call_tool("schedule_tutoring_session", {
240
- "platform_url": platform_url,
241
- "client_id": client_id,
242
- "client_secret": client_secret,
243
- "student_id": student_id,
244
- "subject": subject,
245
- "datetime_str": datetime_str
246
- })
247
 
248
  # Create a default client instance for easy import
249
  client = TutorXClient()
 
190
  return self._call_tool("get_student_analytics", {
191
  "student_id": student_id,
192
  "timeframe_days": timeframe_days
193
+ })
194
+ def check_submission_originality(self, submission: str, reference_sources: List[str]) -> Dict[str, Any]:
195
  """Check student submission for potential plagiarism"""
196
  return self._call_tool("check_submission_originality", {
197
  "submission": submission,
198
  "reference_sources": reference_sources
199
  })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
  # Create a default client instance for easy import
202
  client = TutorXClient()
docs/api.md DELETED
@@ -1,368 +0,0 @@
1
- # TutorX-MCP API Documentation
2
-
3
- This document provides comprehensive documentation for the TutorX-MCP API for developers who want to integrate with the system.
4
-
5
- ## API Overview
6
-
7
- The TutorX-MCP server exposes a Model Context Protocol (MCP) API that allows clients to interact with various educational tools and resources. This API follows the standard MCP protocol as defined in [MCP Specification](https://github.com/anthropics/anthropic-tools/blob/main/mcp/README.md).
8
-
9
- ## Authentication
10
-
11
- For production deployments, all API requests should include an API key in the `Authorization` header:
12
-
13
- ```
14
- Authorization: Bearer your-api-key-here
15
- ```
16
-
17
- ## Base URL
18
-
19
- Default: `http://localhost:8000`
20
-
21
- For production: See your deployment configuration
22
-
23
- ## Tools API
24
-
25
- Tools represent functionality that can be invoked by MCP clients. Each tool is accessed via:
26
-
27
- ```
28
- POST /tools/{tool_name}
29
- Content-Type: application/json
30
-
31
- {
32
- "param1": "value1",
33
- "param2": "value2"
34
- }
35
- ```
36
-
37
- ### Core Features
38
-
39
- #### Adaptive Learning Engine
40
-
41
- ##### `assess_skill`
42
-
43
- Assess a student's skill level on a specific concept.
44
-
45
- **Request:**
46
- ```json
47
- {
48
- "student_id": "student123",
49
- "concept_id": "math_algebra_basics"
50
- }
51
- ```
52
-
53
- **Response:**
54
- ```json
55
- {
56
- "student_id": "student123",
57
- "concept_id": "math_algebra_basics",
58
- "skill_level": 0.75,
59
- "confidence": 0.85,
60
- "recommendations": [
61
- "Practice more complex problems",
62
- "Review related concept: algebra_linear_equations"
63
- ],
64
- "timestamp": "2025-06-07T10:30:45.123456"
65
- }
66
- ```
67
-
68
- ##### `generate_quiz`
69
-
70
- Generate a quiz based on specified concepts and difficulty.
71
-
72
- **Request:**
73
- ```json
74
- {
75
- "concept_ids": ["math_algebra_basics", "math_algebra_linear_equations"],
76
- "difficulty": 2
77
- }
78
- ```
79
-
80
- **Response:**
81
- ```json
82
- {
83
- "quiz_id": "q12345",
84
- "concept_ids": ["math_algebra_basics", "math_algebra_linear_equations"],
85
- "difficulty": 2,
86
- "questions": [
87
- {
88
- "id": "q1",
89
- "text": "Solve for x: 2x + 3 = 7",
90
- "type": "algebraic_equation",
91
- "answer": "x = 2",
92
- "solution_steps": [
93
- "2x + 3 = 7",
94
- "2x = 7 - 3",
95
- "2x = 4",
96
- "x = 4/2 = 2"
97
- ]
98
- }
99
- ]
100
- }
101
- ```
102
-
103
- #### Feedback System
104
-
105
- ##### `analyze_error_patterns`
106
-
107
- Analyze common error patterns for a student on a specific concept.
108
-
109
- **Request:**
110
- ```json
111
- {
112
- "student_id": "student123",
113
- "concept_id": "math_algebra_basics"
114
- }
115
- ```
116
-
117
- **Response:**
118
- ```json
119
- {
120
- "student_id": "student123",
121
- "concept_id": "math_algebra_basics",
122
- "common_errors": [
123
- {
124
- "type": "sign_error",
125
- "frequency": 0.65,
126
- "example": "2x - 3 = 5 → 2x = 5 - 3 → 2x = 2 → x = 1 (should be x = 4)"
127
- }
128
- ],
129
- "recommendations": [
130
- "Practice more sign manipulation problems"
131
- ]
132
- }
133
- ```
134
-
135
- ### Advanced Features
136
-
137
- #### Neurological Engagement Monitor
138
-
139
- ##### `analyze_cognitive_state`
140
-
141
- Analyze EEG data to determine cognitive state.
142
-
143
- **Request:**
144
- ```json
145
- {
146
- "eeg_data": {
147
- "channels": [...],
148
- "sampling_rate": 256,
149
- "duration": 10.0
150
- }
151
- }
152
- ```
153
-
154
- **Response:**
155
- ```json
156
- {
157
- "attention_level": 0.82,
158
- "cognitive_load": 0.65,
159
- "stress_level": 0.25,
160
- "recommendations": [
161
- "Student is engaged but approaching cognitive overload",
162
- "Consider simplifying next problems slightly"
163
- ],
164
- "timestamp": "2025-06-07T10:32:15.123456"
165
- }
166
- ```
167
-
168
- ### External Integrations
169
-
170
- #### Learning Management Systems
171
-
172
- ##### `lms_sync_grades`
173
-
174
- Sync grades with a Learning Management System.
175
-
176
- **Request:**
177
- ```json
178
- {
179
- "lms_type": "canvas",
180
- "api_url": "https://canvas.example.com/api/v1",
181
- "api_key": "your-api-key",
182
- "course_id": "course123",
183
- "assignment_id": "assign456",
184
- "grades": [
185
- {
186
- "student_id": "student123",
187
- "score": 85.5
188
- }
189
- ]
190
- }
191
- ```
192
-
193
- **Response:**
194
- ```json
195
- {
196
- "success": true,
197
- "timestamp": "2025-06-07T10:35:22.123456",
198
- "message": "Grades successfully synced"
199
- }
200
- ```
201
-
202
- #### Open Educational Resources
203
-
204
- ##### `oer_search`
205
-
206
- Search for educational resources in OER repositories.
207
-
208
- **Request:**
209
- ```json
210
- {
211
- "repository_url": "https://oer.example.com/api",
212
- "query": "linear equations",
213
- "subject": "mathematics",
214
- "grade_level": "8"
215
- }
216
- ```
217
-
218
- **Response:**
219
- ```json
220
- {
221
- "success": true,
222
- "count": 2,
223
- "results": [
224
- {
225
- "id": "resource123",
226
- "title": "Introduction to Linear Equations",
227
- "description": "A comprehensive guide to solving linear equations",
228
- "url": "https://oer.example.com/resources/resource123",
229
- "subject": "mathematics",
230
- "grade_level": "8-9",
231
- "license": "CC-BY"
232
- }
233
- ],
234
- "timestamp": "2025-06-07T10:36:12.123456"
235
- }
236
- ```
237
-
238
- #### Real-Time Personalized Tutoring
239
-
240
- ##### `schedule_tutoring_session`
241
-
242
- Schedule a session with a real-time personalized tutoring platform.
243
-
244
- **Request:**
245
- ```json
246
- {
247
- "platform_url": "https://tutoring.example.com/api",
248
- "client_id": "your-client-id",
249
- "client_secret": "your-client-secret",
250
- "student_id": "student123",
251
- "subject": "mathematics",
252
- "datetime_str": "2025-06-10T15:00:00Z"
253
- }
254
- ```
255
-
256
- **Response:**
257
- ```json
258
- {
259
- "success": true,
260
- "session_id": "session789",
261
- "tutor": {
262
- "id": "tutor456",
263
- "name": "Dr. Jane Smith",
264
- "rating": 4.9,
265
- "specialization": "mathematics"
266
- },
267
- "datetime": "2025-06-10T15:00:00Z",
268
- "join_url": "https://tutoring.example.com/session/session789",
269
- "timestamp": "2025-06-07T10:37:45.123456"
270
- }
271
- ```
272
-
273
- ## Resources API
274
-
275
- Resources represent data that can be fetched by MCP clients. Each resource is accessed via:
276
-
277
- ```
278
- GET /resources?uri={resource_uri}
279
- Accept: application/json
280
- ```
281
-
282
- ### Available Resources
283
-
284
- #### `concept-graph://`
285
-
286
- Retrieves the full knowledge concept graph.
287
-
288
- #### `learning-path://{student_id}`
289
-
290
- Retrieves the personalized learning path for a student.
291
-
292
- #### `curriculum-standards://{country_code}`
293
-
294
- Retrieves curriculum standards for a specific country.
295
-
296
- #### `student-dashboard://{student_id}`
297
-
298
- Retrieves dashboard data for a specific student.
299
-
300
- ## Error Handling
301
-
302
- API errors follow a standard format:
303
-
304
- ```json
305
- {
306
- "error": {
307
- "code": "error_code",
308
- "message": "Human-readable error message",
309
- "details": {}
310
- }
311
- }
312
- ```
313
-
314
- Common error codes:
315
- - `invalid_request`: The request was malformed
316
- - `authentication_error`: Authentication failed
317
- - `not_found`: The requested resource does not exist
318
- - `server_error`: Internal server error
319
-
320
- ## Rate Limiting
321
-
322
- Production deployments implement rate limiting to prevent abuse. Clients should monitor the following headers:
323
-
324
- - `X-RateLimit-Limit`: Maximum requests per hour
325
- - `X-RateLimit-Remaining`: Remaining requests for the current hour
326
- - `X-RateLimit-Reset`: Timestamp when the limit will reset
327
-
328
- ## SDK
329
-
330
- For easier integration, we provide client SDKs in multiple languages:
331
-
332
- - Python: `pip install tutorx-client`
333
- - JavaScript: `npm install tutorx-client`
334
-
335
- Example usage (Python):
336
-
337
- ```python
338
- from tutorx_client import TutorXClient
339
-
340
- client = TutorXClient("http://localhost:8000", api_key="your-api-key")
341
-
342
- # Call a tool
343
- result = client.assess_skill("student123", "math_algebra_basics")
344
- print(result["skill_level"])
345
-
346
- # Access a resource
347
- concept_graph = client.get_concept_graph()
348
- ```
349
-
350
- ## Webhooks
351
-
352
- For real-time updates, you can register webhook endpoints:
353
-
354
- ```
355
- POST /webhooks/register
356
- Content-Type: application/json
357
- Authorization: Bearer your-api-key
358
-
359
- {
360
- "url": "https://your-app.example.com/webhook",
361
- "events": ["assessment.completed", "badge.awarded"],
362
- "secret": "your-webhook-secret"
363
- }
364
- ```
365
-
366
- ## Support
367
-
368
- For API support, contact us at [email protected]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/prd.md CHANGED
@@ -51,7 +51,6 @@ To provide an adaptive, multi-modal, and collaborative AI tutoring platform acce
51
  - **Feedback System**
52
  - Contextual error analysis and suggestions
53
  - Multimodal feedback (text, audio, visual)
54
- - Emotional state recognition (via webcam/EEG)
55
 
56
  ## 3.2 Advanced Features
57
 
@@ -74,8 +73,6 @@ To provide an adaptive, multi-modal, and collaborative AI tutoring platform acce
74
  - **Accessibility**
75
  - Screen reader compatibility
76
  - Text-to-speech and adjustable interface
77
- - **Gamification**
78
- - Badges, leaderboards, token-based rewards
79
 
80
  ---
81
 
@@ -85,18 +82,7 @@ To provide an adaptive, multi-modal, and collaborative AI tutoring platform acce
85
  - **Gradio Interface:** User-friendly, customizable, and accessible
86
  - **Microservices Architecture:** Modular design for scalability
87
  - **Real-Time Data Processing:** Asynchronous task queues and caching
88
- - **Cloud Deployment:** Browser-based access with no local setup
89
- - **Integration:** Supports external APIs, LMS, and educational tools
90
-
91
- ---
92
-
93
- ## 5. Non-Functional Requirements
94
-
95
- - **Performance:** Supports 100+ concurrent users with <1s response time for core features
96
- - **Security:** End-to-end encryption, role-based access control
97
- - **Privacy:** Compliant with GDPR, COPPA, and FERPA
98
- - **Scalability:** Horizontally scalable to support large institutions
99
- - **Accessibility:** WCAG 2.1 AA compliant
100
 
101
  ---
102
 
@@ -115,7 +101,7 @@ To provide an adaptive, multi-modal, and collaborative AI tutoring platform acce
115
  1. **Phase 1:** Core adaptive learning engine and MCP integration
116
  2. **Phase 2:** Multi-modal interaction and collaborative tools
117
  3. **Phase 3:** Advanced features (engagement monitor, lesson authoring)
118
- 4. **Phase 4:** Deployment, analytics, and gamification
119
 
120
  ---
121
 
 
51
  - **Feedback System**
52
  - Contextual error analysis and suggestions
53
  - Multimodal feedback (text, audio, visual)
 
54
 
55
  ## 3.2 Advanced Features
56
 
 
73
  - **Accessibility**
74
  - Screen reader compatibility
75
  - Text-to-speech and adjustable interface
 
 
76
 
77
  ---
78
 
 
82
  - **Gradio Interface:** User-friendly, customizable, and accessible
83
  - **Microservices Architecture:** Modular design for scalability
84
  - **Real-Time Data Processing:** Asynchronous task queues and caching
85
+ - **Local Access:** Browser-based access from local machine
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  ---
88
 
 
101
  1. **Phase 1:** Core adaptive learning engine and MCP integration
102
  2. **Phase 2:** Multi-modal interaction and collaborative tools
103
  3. **Phase 3:** Advanced features (engagement monitor, lesson authoring)
104
+ 4. **Phase 4:** Analytics and performance monitoring
105
 
106
  ---
107
 
main.py CHANGED
@@ -18,11 +18,6 @@ from utils.assessment import (
18
  generate_performance_analytics,
19
  detect_plagiarism
20
  )
21
- from utils.integrations import (
22
- LMSIntegration,
23
- OERIntegration,
24
- RTPTIntegration
25
- )
26
 
27
  # Create the TutorX MCP server
28
  mcp = FastMCP("TutorX")
@@ -581,124 +576,9 @@ def check_submission_originality(submission: str, reference_sources: List[str])
581
  reference_sources: List of reference texts to check against
582
 
583
  Returns:
584
- Originality analysis """
585
- return detect_plagiarism(submission, reference_sources)
586
-
587
- # ------------------ External Integrations ------------------
588
-
589
- @mcp.tool()
590
- def lms_sync_grades(lms_type: str, api_url: str, api_key: str,
591
- course_id: str, assignment_id: str,
592
- grades: List[Dict[str, Any]]) -> Dict[str, Any]:
593
- """
594
- Sync grades with a Learning Management System
595
-
596
- Args:
597
- lms_type: Type of LMS ('canvas', 'moodle', 'blackboard')
598
- api_url: URL for the LMS API
599
- api_key: API key for authentication
600
- course_id: ID of the course
601
- assignment_id: ID of the assignment
602
- grades: List of grade data to sync
603
-
604
- Returns:
605
- Status of the sync operation
606
  """
607
- try:
608
- lms = LMSIntegration(lms_type, api_url, api_key)
609
- success = lms.sync_grades(course_id, assignment_id, grades)
610
- return {
611
- "success": success,
612
- "timestamp": datetime.now().isoformat(),
613
- "message": "Grades successfully synced" if success else "Failed to sync grades"
614
- }
615
- except Exception as e:
616
- return {
617
- "success": False,
618
- "error": str(e),
619
- "timestamp": datetime.now().isoformat()
620
- }
621
-
622
- @mcp.tool()
623
- def oer_search(repository_url: str, query: str,
624
- subject: Optional[str] = None, grade_level: Optional[str] = None,
625
- api_key: Optional[str] = None) -> Dict[str, Any]:
626
- """
627
- Search for educational resources in OER repositories
628
-
629
- Args:
630
- repository_url: URL of the OER repository
631
- query: Search query
632
- subject: Optional subject filter
633
- grade_level: Optional grade level filter
634
- api_key: Optional API key if required
635
-
636
- Returns:
637
- List of matching resources
638
- """
639
- try:
640
- oer = OERIntegration(repository_url, api_key)
641
- results = oer.search_resources(query, subject, grade_level)
642
- return {
643
- "success": True,
644
- "count": len(results),
645
- "results": results,
646
- "timestamp": datetime.now().isoformat()
647
- }
648
- except Exception as e:
649
- return {
650
- "success": False,
651
- "error": str(e),
652
- "timestamp": datetime.now().isoformat()
653
- }
654
-
655
- @mcp.tool()
656
- def schedule_tutoring_session(platform_url: str, client_id: str, client_secret: str,
657
- student_id: str, subject: str, datetime_str: str) -> Dict[str, Any]:
658
- """
659
- Schedule a session with a real-time personalized tutoring platform
660
-
661
- Args:
662
- platform_url: URL of the tutoring platform
663
- client_id: OAuth client ID
664
- client_secret: OAuth client secret
665
- student_id: ID of the student
666
- subject: Subject for tutoring
667
- datetime_str: ISO format datetime for the session
668
-
669
- Returns:
670
- Session details
671
- """
672
- try:
673
- # Find an available tutor
674
- rtpt = RTPTIntegration(platform_url, client_id, client_secret)
675
- tutors = rtpt.get_available_tutors(subject, "intermediate")
676
-
677
- if not tutors:
678
- return {
679
- "success": False,
680
- "message": "No tutors available for this subject",
681
- "timestamp": datetime.now().isoformat()
682
- }
683
-
684
- # Schedule with first available tutor
685
- tutor_id = tutors[0]["id"]
686
- session = rtpt.schedule_session(student_id, tutor_id, subject, datetime_str)
687
-
688
- return {
689
- "success": True,
690
- "session_id": session.get("id"),
691
- "tutor": session.get("tutor"),
692
- "datetime": session.get("datetime"),
693
- "join_url": session.get("join_url"),
694
- "timestamp": datetime.now().isoformat()
695
- }
696
- except Exception as e:
697
- return {
698
- "success": False,
699
- "error": str(e),
700
- "timestamp": datetime.now().isoformat()
701
- }
702
 
703
  if __name__ == "__main__":
704
  mcp.run()
 
18
  generate_performance_analytics,
19
  detect_plagiarism
20
  )
 
 
 
 
 
21
 
22
  # Create the TutorX MCP server
23
  mcp = FastMCP("TutorX")
 
576
  reference_sources: List of reference texts to check against
577
 
578
  Returns:
579
+ Originality analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580
  """
581
+ return detect_plagiarism(submission, reference_sources)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
582
 
583
  if __name__ == "__main__":
584
  mcp.run()
utils/integrations.py DELETED
@@ -1,251 +0,0 @@
1
- """
2
- Integration utilities for connecting TutorX-MCP with external educational systems
3
- """
4
-
5
- import requests
6
- import json
7
- import os
8
- from typing import Dict, Any, List, Optional
9
- import logging
10
-
11
- logger = logging.getLogger(__name__)
12
-
13
- class LMSIntegration:
14
- """Integration with Learning Management Systems (Canvas, Moodle, etc.)"""
15
-
16
- def __init__(self, lms_type: str, api_url: str, api_key: str):
17
- """
18
- Initialize LMS integration
19
-
20
- Args:
21
- lms_type: Type of LMS ('canvas', 'moodle', 'blackboard', etc.)
22
- api_url: Base URL for LMS API
23
- api_key: API key or token for authentication
24
- """
25
- self.lms_type = lms_type.lower()
26
- self.api_url = api_url.rstrip('/')
27
- self.api_key = api_key
28
-
29
- def get_courses(self) -> List[Dict[str, Any]]:
30
- """Get list of courses from LMS"""
31
- if self.lms_type == 'canvas':
32
- return self._canvas_get_courses()
33
- elif self.lms_type == 'moodle':
34
- return self._moodle_get_courses()
35
- else:
36
- raise ValueError(f"Unsupported LMS type: {self.lms_type}")
37
-
38
- def _canvas_get_courses(self) -> List[Dict[str, Any]]:
39
- """Get courses from Canvas LMS"""
40
- headers = {"Authorization": f"Bearer {self.api_key}"}
41
- response = requests.get(f"{self.api_url}/courses", headers=headers)
42
- response.raise_for_status()
43
- return response.json()
44
-
45
- def _moodle_get_courses(self) -> List[Dict[str, Any]]:
46
- """Get courses from Moodle"""
47
- params = {
48
- "wstoken": self.api_key,
49
- "wsfunction": "core_course_get_courses",
50
- "moodlewsrestformat": "json"
51
- }
52
- response = requests.get(f"{self.api_url}/webservice/rest/server.php", params=params)
53
- response.raise_for_status()
54
- return response.json()
55
-
56
- def sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
57
- """
58
- Sync grades to LMS
59
-
60
- Args:
61
- course_id: ID of the course
62
- assignment_id: ID of the assignment
63
- grades: List of grade data to sync
64
-
65
- Returns:
66
- Success status
67
- """
68
- try:
69
- if self.lms_type == 'canvas':
70
- return self._canvas_sync_grades(course_id, assignment_id, grades)
71
- elif self.lms_type == 'moodle':
72
- return self._moodle_sync_grades(course_id, assignment_id, grades)
73
- else:
74
- raise ValueError(f"Unsupported LMS type: {self.lms_type}")
75
- except Exception as e:
76
- logger.error(f"Error syncing grades: {e}")
77
- return False
78
-
79
- def _canvas_sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
80
- """Sync grades to Canvas LMS"""
81
- headers = {"Authorization": f"Bearer {self.api_key}"}
82
-
83
- for grade in grades:
84
- data = {
85
- "submission": {
86
- "posted_grade": grade["score"]
87
- }
88
- }
89
-
90
- url = f"{self.api_url}/courses/{course_id}/assignments/{assignment_id}/submissions/{grade['student_id']}"
91
- response = requests.put(url, json=data, headers=headers)
92
-
93
- if response.status_code != 200:
94
- logger.error(f"Failed to sync grade for student {grade['student_id']}: {response.text}")
95
- return False
96
-
97
- return True
98
-
99
- def _moodle_sync_grades(self, course_id: str, assignment_id: str, grades: List[Dict[str, Any]]) -> bool:
100
- """Sync grades to Moodle"""
101
- # Implementation specific to Moodle's API
102
- # This would use the Moodle grade update API
103
- return True # Placeholder
104
-
105
- class OERIntegration:
106
- """Integration with Open Educational Resources repositories"""
107
-
108
- def __init__(self, repository_url: str, api_key: Optional[str] = None):
109
- """
110
- Initialize OER repository integration
111
-
112
- Args:
113
- repository_url: Base URL for OER repository API
114
- api_key: Optional API key if required by the repository
115
- """
116
- self.repository_url = repository_url.rstrip('/')
117
- self.api_key = api_key
118
-
119
- def search_resources(self, query: str, subject: Optional[str] = None,
120
- grade_level: Optional[str] = None) -> List[Dict[str, Any]]:
121
- """
122
- Search for educational resources
123
-
124
- Args:
125
- query: Search query
126
- subject: Optional subject filter
127
- grade_level: Optional grade level filter
128
-
129
- Returns:
130
- List of matching resources
131
- """
132
- params = {"q": query}
133
-
134
- if subject:
135
- params["subject"] = subject
136
-
137
- if grade_level:
138
- params["grade"] = grade_level
139
-
140
- headers = {}
141
- if self.api_key:
142
- headers["Authorization"] = f"Bearer {self.api_key}"
143
-
144
- response = requests.get(f"{self.repository_url}/search", params=params, headers=headers)
145
- response.raise_for_status()
146
-
147
- return response.json().get("results", [])
148
-
149
- def get_resource(self, resource_id: str) -> Dict[str, Any]:
150
- """
151
- Get details for a specific resource
152
-
153
- Args:
154
- resource_id: ID of the resource to fetch
155
-
156
- Returns:
157
- Resource details
158
- """
159
- headers = {}
160
- if self.api_key:
161
- headers["Authorization"] = f"Bearer {self.api_key}"
162
-
163
- response = requests.get(f"{self.repository_url}/resources/{resource_id}", headers=headers)
164
- response.raise_for_status()
165
-
166
- return response.json()
167
-
168
-
169
- class RTPTIntegration:
170
- """Integration with real-time personalized tutoring platforms"""
171
-
172
- def __init__(self, platform_url: str, client_id: str, client_secret: str):
173
- """
174
- Initialize RTPT integration
175
-
176
- Args:
177
- platform_url: Base URL for RTPT platform API
178
- client_id: OAuth client ID
179
- client_secret: OAuth client secret
180
- """
181
- self.platform_url = platform_url.rstrip('/')
182
- self.client_id = client_id
183
- self.client_secret = client_secret
184
- self._access_token = None
185
-
186
- def _get_access_token(self) -> str:
187
- """Get OAuth access token"""
188
- if self._access_token:
189
- return self._access_token
190
-
191
- data = {
192
- "grant_type": "client_credentials",
193
- "client_id": self.client_id,
194
- "client_secret": self.client_secret
195
- }
196
-
197
- response = requests.post(f"{self.platform_url}/oauth/token", data=data)
198
- response.raise_for_status()
199
-
200
- token_data = response.json()
201
- self._access_token = token_data["access_token"]
202
- return self._access_token
203
-
204
- def get_available_tutors(self, subject: str, level: str) -> List[Dict[str, Any]]:
205
- """
206
- Get available tutors for a subject and level
207
-
208
- Args:
209
- subject: Academic subject
210
- level: Academic level
211
-
212
- Returns:
213
- List of available tutors
214
- """
215
- headers = {"Authorization": f"Bearer {self._get_access_token()}"}
216
- params = {
217
- "subject": subject,
218
- "level": level
219
- }
220
-
221
- response = requests.get(f"{self.platform_url}/tutors/available", params=params, headers=headers)
222
- response.raise_for_status()
223
-
224
- return response.json()
225
-
226
- def schedule_session(self, student_id: str, tutor_id: str,
227
- subject: str, datetime_str: str) -> Dict[str, Any]:
228
- """
229
- Schedule a tutoring session
230
-
231
- Args:
232
- student_id: ID of the student
233
- tutor_id: ID of the tutor
234
- subject: Subject for tutoring
235
- datetime_str: ISO format datetime for the session
236
-
237
- Returns:
238
- Session details
239
- """
240
- headers = {"Authorization": f"Bearer {self._get_access_token()}"}
241
- data = {
242
- "student_id": student_id,
243
- "tutor_id": tutor_id,
244
- "subject": subject,
245
- "datetime": datetime_str
246
- }
247
-
248
- response = requests.post(f"{self.platform_url}/sessions", json=data, headers=headers)
249
- response.raise_for_status()
250
-
251
- return response.json()