schoolmospy 0.0.2__py3-none-any.whl → 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- schoolmospy/__init__.py +4 -2
- schoolmospy/core/basic_client.py +29 -14
- schoolmospy/core/events_client.py +62 -0
- schoolmospy/core/homeworks_client.py +4 -4
- schoolmospy/core/marks_client.py +4 -3
- schoolmospy/core/student_client.py +26 -15
- schoolmospy/models/events.py +37 -0
- schoolmospy/models/homeworks.py +10 -10
- schoolmospy/models/marks.py +4 -4
- schoolmospy/models/profile.py +7 -7
- schoolmospy/models/userinfo.py +5 -7
- schoolmospy/utils/exceptions.py +14 -12
- schoolmospy-0.2.2.dist-info/METADATA +108 -0
- schoolmospy-0.2.2.dist-info/RECORD +18 -0
- schoolmospy-0.0.2.dist-info/METADATA +0 -28
- schoolmospy-0.0.2.dist-info/RECORD +0 -16
- {schoolmospy-0.0.2.dist-info → schoolmospy-0.2.2.dist-info}/WHEEL +0 -0
- {schoolmospy-0.0.2.dist-info → schoolmospy-0.2.2.dist-info}/licenses/LICENSE +0 -0
schoolmospy/__init__.py
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
from schoolmospy.core.
|
|
2
|
-
from schoolmospy.core.
|
|
1
|
+
from schoolmospy.core.basic_client import BasicClient as BasicClient
|
|
2
|
+
from schoolmospy.core.student_client import StudentClient as StudentClient
|
|
3
|
+
|
|
4
|
+
__all__ = ["BasicClient", "StudentClient"]
|
schoolmospy/core/basic_client.py
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
import httpx
|
|
2
|
-
from typing import Any, Optional, Type
|
|
3
4
|
from pydantic import BaseModel
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
from schoolmospy.utils.exceptions import APIError, AuthError, HTTPError, NotFoundError, ServerError
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class BasicClient:
|
|
8
10
|
def __init__(
|
|
9
11
|
self,
|
|
10
12
|
base_url: str,
|
|
11
|
-
token:
|
|
12
|
-
profile_id:
|
|
13
|
+
token: str | None = None,
|
|
14
|
+
profile_id: int | None = None,
|
|
13
15
|
profile_type: str = "student",
|
|
14
16
|
timeout: float = 15.0,
|
|
15
|
-
):
|
|
17
|
+
) -> None:
|
|
16
18
|
self.base_url = base_url.rstrip("/")
|
|
17
19
|
self.token = token
|
|
18
20
|
self.profile_id = profile_id
|
|
@@ -33,29 +35,36 @@ class BasicClient:
|
|
|
33
35
|
headers["Profile-Id"] = str(self.profile_id)
|
|
34
36
|
if self.profile_type:
|
|
35
37
|
headers["Profile-Type"] = self.profile_type
|
|
38
|
+
headers["X-Mes-Role"] = self.profile_type
|
|
36
39
|
return headers
|
|
37
40
|
|
|
38
|
-
async def _handle_response(
|
|
39
|
-
|
|
41
|
+
async def _handle_response(
|
|
42
|
+
self,
|
|
43
|
+
response: httpx.Response,
|
|
44
|
+
response_model: type[BaseModel] | None = None,
|
|
45
|
+
) -> Any:
|
|
40
46
|
if response.is_success:
|
|
41
47
|
if response_model:
|
|
42
48
|
return response_model.model_validate(response.json())
|
|
43
49
|
return response.json()
|
|
44
50
|
|
|
45
|
-
# Ошибки
|
|
46
51
|
text = response.text.strip()
|
|
47
52
|
status = response.status_code
|
|
48
53
|
|
|
49
54
|
if status == 401:
|
|
50
55
|
raise AuthError("Unauthorized or invalid token", status, text)
|
|
51
|
-
|
|
56
|
+
if status == 404:
|
|
52
57
|
raise NotFoundError("Resource not found", status, text)
|
|
53
|
-
|
|
58
|
+
if status >= 500:
|
|
54
59
|
raise ServerError("Server error", status, text)
|
|
55
|
-
|
|
56
|
-
raise HTTPError(f"Unexpected response ({status})", status, text)
|
|
60
|
+
raise HTTPError(f"Unexpected response ({status})", status, text)
|
|
57
61
|
|
|
58
|
-
async def get(
|
|
62
|
+
async def get(
|
|
63
|
+
self,
|
|
64
|
+
endpoint: str,
|
|
65
|
+
response_model: type[BaseModel] | None = None,
|
|
66
|
+
**kwargs: Any,
|
|
67
|
+
) -> Any:
|
|
59
68
|
url = f"{self.base_url}/{endpoint.lstrip('/')}"
|
|
60
69
|
async with httpx.AsyncClient(headers=self.headers, timeout=self.timeout) as client:
|
|
61
70
|
try:
|
|
@@ -64,7 +73,13 @@ class BasicClient:
|
|
|
64
73
|
raise APIError(f"Request failed: {e}") from e
|
|
65
74
|
return await self._handle_response(resp, response_model)
|
|
66
75
|
|
|
67
|
-
async def post(
|
|
76
|
+
async def post(
|
|
77
|
+
self,
|
|
78
|
+
endpoint: str,
|
|
79
|
+
data: Any = None,
|
|
80
|
+
response_model: type[BaseModel] | None = None,
|
|
81
|
+
**kwargs: Any,
|
|
82
|
+
) -> Any:
|
|
68
83
|
url = f"{self.base_url}/{endpoint.lstrip('/')}"
|
|
69
84
|
async with httpx.AsyncClient(headers=self.headers, timeout=self.timeout) as client:
|
|
70
85
|
try:
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from schoolmospy.core.basic_client import BasicClient
|
|
4
|
+
from schoolmospy.models.events import Events
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EventClient:
|
|
8
|
+
def __init__(self, client: BasicClient) -> None:
|
|
9
|
+
"""
|
|
10
|
+
Initialization the EventClient instance.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
client (BasicClient): An instance of BasicClient or any compatible subclass,
|
|
14
|
+
used for making API requests.
|
|
15
|
+
"""
|
|
16
|
+
self.client = client
|
|
17
|
+
|
|
18
|
+
async def get(self, from_date: datetime, to_date: datetime, contingent_guid: str) -> Events:
|
|
19
|
+
"""
|
|
20
|
+
Method for getting events done within a certain period of time
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
from_date (datetime): The start date of the period (inclusive).
|
|
24
|
+
to_date (datetime): The end date of the period (inclusive).
|
|
25
|
+
contingent_guid (str): Person ID
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Events: A Pydantic model containing a list of events items.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
APIError: If the request fails or returns an unexpected response.
|
|
32
|
+
AuthError: If the provided token is invalid or expired.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
```python
|
|
36
|
+
from datetime import datetime
|
|
37
|
+
from schoolmospy.clients.student_client import StudentClient
|
|
38
|
+
|
|
39
|
+
client = StudentClient(token="YOUR_TOKEN", profile_id=17234613)
|
|
40
|
+
|
|
41
|
+
me = await client.get_me()
|
|
42
|
+
|
|
43
|
+
events = await client.events.get(
|
|
44
|
+
from_date=datetime(2025, 10, 1),
|
|
45
|
+
to_date=datetime(2025, 10, 24),
|
|
46
|
+
contingent_guid=me.contingent_guid
|
|
47
|
+
)
|
|
48
|
+
print(events.response)
|
|
49
|
+
```
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
return await self.client.get(
|
|
53
|
+
"/api/eventcalendar/v1/api/events",
|
|
54
|
+
Events,
|
|
55
|
+
params={
|
|
56
|
+
"from": from_date.strftime("%Y-%m-%d"),
|
|
57
|
+
"to": to_date.strftime("%Y-%m-%d"),
|
|
58
|
+
"person_ids": contingent_guid,
|
|
59
|
+
"expand": "marks,homework,absence_reason_id,health_status,nonattendance_reason_id",
|
|
60
|
+
"source_types": "PLAN,AE,EC,EVENTS,AFISHA,ORGANIZER,OLYMPIAD,PROF",
|
|
61
|
+
},
|
|
62
|
+
)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
+
|
|
2
3
|
from schoolmospy.core.basic_client import BasicClient
|
|
3
4
|
from schoolmospy.models.homeworks import Homeworks
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class HomeworkClient:
|
|
7
|
-
def __init__(self, client: BasicClient):
|
|
8
|
+
def __init__(self, client: BasicClient) -> None:
|
|
8
9
|
"""
|
|
9
10
|
Initialization the HomeworkClient instance.
|
|
10
11
|
|
|
@@ -43,13 +44,12 @@ class HomeworkClient:
|
|
|
43
44
|
```
|
|
44
45
|
"""
|
|
45
46
|
|
|
46
|
-
|
|
47
47
|
return await self.client.get(
|
|
48
48
|
"/api/family/web/v1/homeworks",
|
|
49
49
|
Homeworks,
|
|
50
50
|
params={
|
|
51
51
|
"from": from_date.strftime("%Y-%m-%d"),
|
|
52
52
|
"to": to_date.strftime("%Y-%m-%d"),
|
|
53
|
-
"student_id": self.client.profile_id
|
|
54
|
-
}
|
|
53
|
+
"student_id": self.client.profile_id,
|
|
54
|
+
},
|
|
55
55
|
)
|
schoolmospy/core/marks_client.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
+
|
|
2
3
|
from schoolmospy.core.basic_client import BasicClient
|
|
3
4
|
from schoolmospy.models.marks import Marks
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class MarksClient:
|
|
7
|
-
def __init__(self, client: BasicClient):
|
|
8
|
+
def __init__(self, client: BasicClient) -> None:
|
|
8
9
|
self.client = client
|
|
9
10
|
|
|
10
11
|
async def get(self, from_date: datetime, to_date: datetime) -> Marks:
|
|
@@ -41,6 +42,6 @@ class MarksClient:
|
|
|
41
42
|
params={
|
|
42
43
|
"from": from_date.strftime("%Y-%m-%d"),
|
|
43
44
|
"to": to_date.strftime("%Y-%m-%d"),
|
|
44
|
-
"student_id": self.client.profile_id
|
|
45
|
-
}
|
|
45
|
+
"student_id": self.client.profile_id,
|
|
46
|
+
},
|
|
46
47
|
)
|
|
@@ -1,31 +1,42 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
1
|
from schoolmospy.core.basic_client import BasicClient
|
|
3
|
-
from schoolmospy.
|
|
4
|
-
from schoolmospy.models.userinfo import Userinfo
|
|
2
|
+
from schoolmospy.core.events_client import EventClient
|
|
5
3
|
from schoolmospy.core.homeworks_client import HomeworkClient
|
|
6
4
|
from schoolmospy.core.marks_client import MarksClient
|
|
5
|
+
from schoolmospy.models.profile import Profile
|
|
6
|
+
from schoolmospy.models.userinfo import Userinfo
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class StudentClient(BasicClient):
|
|
10
|
-
def __init__(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
base_url: str = "https://school.mos.ru",
|
|
13
|
+
token: str | None = None,
|
|
14
|
+
profile_id: int | None = None,
|
|
15
|
+
profile_type: str = "student",
|
|
16
|
+
timeout: float = 15.0,
|
|
17
|
+
) -> None:
|
|
16
18
|
super().__init__(base_url, token, profile_id, profile_type, timeout)
|
|
17
19
|
self.homeworks = HomeworkClient(self)
|
|
18
20
|
self.marks = MarksClient(self)
|
|
19
|
-
|
|
21
|
+
self.events = EventClient(self)
|
|
20
22
|
|
|
21
23
|
async def get_me(self) -> Profile:
|
|
24
|
+
"""
|
|
25
|
+
Get the current user's profile information.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
Profile: Profile object containing user data
|
|
29
|
+
"""
|
|
22
30
|
return await self.get(
|
|
23
31
|
"/api/family/web/v1/profile",
|
|
24
32
|
Profile,
|
|
25
33
|
)
|
|
26
|
-
|
|
34
|
+
|
|
27
35
|
async def userinfo(self) -> Userinfo:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
"""
|
|
37
|
+
Get basic user information from OAuth.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Userinfo: Object with basic user information
|
|
41
|
+
"""
|
|
42
|
+
return await self.get("/v1/oauth/userinfo", Userinfo)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class EventItem(BaseModel):
|
|
9
|
+
id: int
|
|
10
|
+
source_id: str
|
|
11
|
+
source: str
|
|
12
|
+
start_at: str
|
|
13
|
+
finish_at: str
|
|
14
|
+
cancelled: bool | None = None
|
|
15
|
+
lesson_type: str | None = None
|
|
16
|
+
course_lesson_type: Any | None = None
|
|
17
|
+
lesson_form: Any | None = None
|
|
18
|
+
replaced: bool | None = None
|
|
19
|
+
room_name: str | None
|
|
20
|
+
room_number: str | None
|
|
21
|
+
subject_id: int | None = None
|
|
22
|
+
subject_name: str
|
|
23
|
+
link_to_join: Any | None = None
|
|
24
|
+
health_status: Any
|
|
25
|
+
absence_reason_id: Any
|
|
26
|
+
nonattendance_reason_id: Any
|
|
27
|
+
homework: Any | None = None
|
|
28
|
+
marks: Any | None = None
|
|
29
|
+
is_missed_lesson: bool
|
|
30
|
+
esz_field_id: int | None = None
|
|
31
|
+
lesson_theme: Any | None = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Events(BaseModel):
|
|
35
|
+
total_count: int
|
|
36
|
+
response: list[EventItem]
|
|
37
|
+
errors: Any
|
schoolmospy/models/homeworks.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
@@ -11,12 +11,12 @@ class Url(BaseModel):
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class Material(BaseModel):
|
|
14
|
-
uuid:
|
|
14
|
+
uuid: str | None
|
|
15
15
|
type: str
|
|
16
|
-
selected_mode:
|
|
16
|
+
selected_mode: str | None
|
|
17
17
|
type_name: str
|
|
18
|
-
id:
|
|
19
|
-
urls:
|
|
18
|
+
id: int | None
|
|
19
|
+
urls: list[Url]
|
|
20
20
|
description: Any
|
|
21
21
|
content_type: Any
|
|
22
22
|
title: str
|
|
@@ -24,14 +24,14 @@ class Material(BaseModel):
|
|
|
24
24
|
action_name: str
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class
|
|
27
|
+
class HomeworkItem(BaseModel):
|
|
28
28
|
type: str
|
|
29
29
|
description: str
|
|
30
|
-
comments:
|
|
31
|
-
materials:
|
|
30
|
+
comments: list
|
|
31
|
+
materials: list[Material]
|
|
32
32
|
homework: str
|
|
33
33
|
homework_entry_student_id: int
|
|
34
|
-
attachments:
|
|
34
|
+
attachments: list
|
|
35
35
|
subject_id: int
|
|
36
36
|
group_id: int
|
|
37
37
|
date: str
|
|
@@ -49,4 +49,4 @@ class PayloadItem(BaseModel):
|
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
class Homeworks(BaseModel):
|
|
52
|
-
payload:
|
|
52
|
+
payload: list[HomeworkItem]
|
schoolmospy/models/marks.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
@@ -20,10 +20,10 @@ class Value(BaseModel):
|
|
|
20
20
|
grade_system_type: str
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
class
|
|
23
|
+
class MarkItem(BaseModel):
|
|
24
24
|
id: int
|
|
25
25
|
value: str
|
|
26
|
-
values:
|
|
26
|
+
values: list[Value]
|
|
27
27
|
comment: str
|
|
28
28
|
weight: int
|
|
29
29
|
point_date: Any
|
|
@@ -42,4 +42,4 @@ class PayloadItem(BaseModel):
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class Marks(BaseModel):
|
|
45
|
-
payload:
|
|
45
|
+
payload: list[MarkItem]
|
schoolmospy/models/profile.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
@@ -44,7 +44,7 @@ class Representative(BaseModel):
|
|
|
44
44
|
middle_name: str
|
|
45
45
|
type_id: int
|
|
46
46
|
type: str
|
|
47
|
-
email:
|
|
47
|
+
email: str | None
|
|
48
48
|
phone: str
|
|
49
49
|
snils: str
|
|
50
50
|
|
|
@@ -74,9 +74,9 @@ class Child(BaseModel):
|
|
|
74
74
|
class_unit_id: int
|
|
75
75
|
class_uid: str
|
|
76
76
|
age: int
|
|
77
|
-
groups:
|
|
78
|
-
representatives:
|
|
79
|
-
sections:
|
|
77
|
+
groups: list[Group]
|
|
78
|
+
representatives: list[Representative]
|
|
79
|
+
sections: list[Section]
|
|
80
80
|
sudir_account_exists: bool
|
|
81
81
|
sudir_login: Any
|
|
82
82
|
is_legal_representative: bool
|
|
@@ -90,5 +90,5 @@ class Child(BaseModel):
|
|
|
90
90
|
|
|
91
91
|
class Profile(BaseModel):
|
|
92
92
|
profile: _Profile
|
|
93
|
-
children:
|
|
94
|
-
hash: str
|
|
93
|
+
children: list[Child]
|
|
94
|
+
hash: str
|
schoolmospy/models/userinfo.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import List
|
|
4
|
-
|
|
5
3
|
from pydantic import BaseModel, Field
|
|
6
4
|
|
|
7
5
|
|
|
@@ -23,7 +21,7 @@ class Class(BaseModel):
|
|
|
23
21
|
parallel: Parallel
|
|
24
22
|
organization: Organization
|
|
25
23
|
education_stage_id: int
|
|
26
|
-
staff_ids:
|
|
24
|
+
staff_ids: list[int]
|
|
27
25
|
|
|
28
26
|
|
|
29
27
|
class ServiceType(BaseModel):
|
|
@@ -34,7 +32,7 @@ class ServiceType(BaseModel):
|
|
|
34
32
|
class EducationItem(BaseModel):
|
|
35
33
|
training_begin_at: str
|
|
36
34
|
training_end_at: str
|
|
37
|
-
class_: Class = Field(..., alias=
|
|
35
|
+
class_: Class = Field(..., alias="class")
|
|
38
36
|
service_type: ServiceType
|
|
39
37
|
|
|
40
38
|
|
|
@@ -48,9 +46,9 @@ class Userinfo(BaseModel):
|
|
|
48
46
|
phone: str
|
|
49
47
|
name: str
|
|
50
48
|
gender: str
|
|
51
|
-
education:
|
|
52
|
-
children:
|
|
53
|
-
agents:
|
|
49
|
+
education: list[EducationItem]
|
|
50
|
+
children: list
|
|
51
|
+
agents: list[str]
|
|
54
52
|
mesh_id: str
|
|
55
53
|
given_name: str
|
|
56
54
|
family_name: str
|
schoolmospy/utils/exceptions.py
CHANGED
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class APIError(Exception):
|
|
5
|
-
def __init__(
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
message: str,
|
|
8
|
+
status_code: int | None = None,
|
|
9
|
+
response: Any | None = None,
|
|
10
|
+
) -> None:
|
|
6
11
|
super().__init__(message)
|
|
7
12
|
self.status_code = status_code
|
|
8
13
|
self.response = response
|
|
9
14
|
|
|
10
|
-
def __str__(self):
|
|
11
|
-
return f"{self.__class__.__name__}: {self.args[0]} (
|
|
15
|
+
def __str__(self) -> str:
|
|
16
|
+
return f"{self.__class__.__name__}: {self.args[0]} ({self.status_code}) {self.response}"
|
|
12
17
|
|
|
13
18
|
|
|
14
|
-
class AuthError(APIError):
|
|
15
|
-
...
|
|
19
|
+
class AuthError(APIError): ...
|
|
16
20
|
|
|
17
|
-
class NotFoundError(APIError):
|
|
18
|
-
...
|
|
19
21
|
|
|
22
|
+
class NotFoundError(APIError): ...
|
|
20
23
|
|
|
21
|
-
class ServerError(APIError):
|
|
22
|
-
...
|
|
23
24
|
|
|
25
|
+
class ServerError(APIError): ...
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
class HTTPError(APIError): ...
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: schoolmospy
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: A lightweight async Python wrapper for school.mos.ru APIs
|
|
5
|
+
License: GPL-3.0-only
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: school,mos,api,education,async,wrapper,python
|
|
8
|
+
Author: Ivan Kriventsev
|
|
9
|
+
Author-email: xd2dd@icloud.com
|
|
10
|
+
Requires-Python: >=3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Dist: aiohttp (>=3.12.15,<4.0.0)
|
|
17
|
+
Requires-Dist: httpx (>=0.28.1,<0.29.0)
|
|
18
|
+
Requires-Dist: pydantic (>=2.11.9,<3.0.0)
|
|
19
|
+
Project-URL: Documentation, https://xd2dd.github.io/schoolmospy
|
|
20
|
+
Project-URL: Homepage, https://github.com/xd2dd/schoolmospy
|
|
21
|
+
Project-URL: Issues, https://github.com/xd2dd/schoolmospy/issues
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
# 📕 SchoolMosPy
|
|
29
|
+
|
|
30
|
+
SchoolMosPy is a lightweight async Python wrapper for school.mos.ru APIs. It provides a simple and intuitive interface to interact with the Moscow School Electronic Diary platform.
|
|
31
|
+
|
|
32
|
+
## ✨ Features
|
|
33
|
+
|
|
34
|
+
- **Async architecture** - built on `aiohttp` and `httpx` for high performance
|
|
35
|
+
- **Type safety** - uses `pydantic` for data validation
|
|
36
|
+
- **Simple API** - intuitive interface for working with data
|
|
37
|
+
- **Full-featured** - access to marks, homeworks, events, and profile data
|
|
38
|
+
|
|
39
|
+
## 📋 Requirements
|
|
40
|
+
|
|
41
|
+
- Python 3.12+
|
|
42
|
+
- aiohttp >= 3.12.15
|
|
43
|
+
- pydantic >= 2.11.9
|
|
44
|
+
- httpx >= 0.28.1
|
|
45
|
+
|
|
46
|
+
## 📦 Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install schoolmospy
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 🚀 Quick Start
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import asyncio
|
|
56
|
+
from schoolmospy import StudentClient
|
|
57
|
+
|
|
58
|
+
async def main():
|
|
59
|
+
# Create client
|
|
60
|
+
client = StudentClient(
|
|
61
|
+
token="your_token",
|
|
62
|
+
profile_id=12345
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Get profile
|
|
66
|
+
profile = await client.get_me()
|
|
67
|
+
print(f"Name: {profile.name}")
|
|
68
|
+
|
|
69
|
+
# Get marks
|
|
70
|
+
marks = await client.marks.get_marks(
|
|
71
|
+
from_date="2024-01-01",
|
|
72
|
+
to_date="2024-12-31"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Get homeworks
|
|
76
|
+
homeworks = await client.homeworks.get_homeworks(
|
|
77
|
+
from_date="2024-01-01",
|
|
78
|
+
to_date="2024-12-31"
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Get events/schedule
|
|
82
|
+
events = await client.events.get_events(
|
|
83
|
+
from_date="2024-01-01",
|
|
84
|
+
to_date="2024-12-31"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
await client.close()
|
|
88
|
+
|
|
89
|
+
asyncio.run(main())
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 📝 License
|
|
93
|
+
|
|
94
|
+
This project is licensed under the GPL-3.0 License. See the [LICENSE](LICENSE) file for details.
|
|
95
|
+
|
|
96
|
+
## 🔗 Links
|
|
97
|
+
|
|
98
|
+
- [Documentation](https://xd2dd.github.io/schoolmospy)
|
|
99
|
+
- [Report an Issue](https://github.com/xd2dd/schoolmospy/issues)
|
|
100
|
+
|
|
101
|
+
## 👨💻 Author
|
|
102
|
+
|
|
103
|
+
Ivan Kriventsev - [xd2dd@icloud.com](mailto:xd2dd@icloud.com)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
⭐ If you like this project, please give it a star on GitHub!
|
|
108
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
schoolmospy/__init__.py,sha256=veFE2dpRaFNhv2GhCGv9cwU341HKt2SoXIGEn3BWGZA,188
|
|
2
|
+
schoolmospy/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
schoolmospy/core/basic_client.py,sha256=jXe94Q0ioWFHBYYeiE7T217QMYpVHzHDXW9AMpvNxsc,3103
|
|
4
|
+
schoolmospy/core/events_client.py,sha256=MCtXj8aR8pEPh_kYtrzVYWZcDBPoHBUyxi2qNIVwaNk,2134
|
|
5
|
+
schoolmospy/core/homeworks_client.py,sha256=ycXPs5Za1opuoz0Y2A63ZLgT2K8M0SeE_45Wdy3jm6U,1825
|
|
6
|
+
schoolmospy/core/marks_client.py,sha256=ukBB-eYs9rlZb2otxNZu7ak1u8s4M16NtSeuIgAnocA,1554
|
|
7
|
+
schoolmospy/core/student_client.py,sha256=MfW24G7oDzGN643GDUV-Kye_BJmHgSKLa-tRFnXix4k,1343
|
|
8
|
+
schoolmospy/models/events.py,sha256=NCqfqjMIMEKZJGf0gWF1tnJfCAg3ET-SJG6wRKTJG6c,867
|
|
9
|
+
schoolmospy/models/homeworks.py,sha256=oiHHe2jTifc_5oIWKopymcsL4MBZQgoPb3c9q3hPl7E,976
|
|
10
|
+
schoolmospy/models/marks.py,sha256=Vd3c-7c8SNul4oPcrbK2T-4apSE4kl97GuwaHH5gNuA,754
|
|
11
|
+
schoolmospy/models/profile.py,sha256=vphn7so3X0gxqkmrwDzk6i5KP1U2ejOjeqKyVPLlFJo,1630
|
|
12
|
+
schoolmospy/models/userinfo.py,sha256=G7uphP0CdviQxpdjGdv1xpCA84EzkID83F6TI4W57Wo,984
|
|
13
|
+
schoolmospy/utils/exceptions.py,sha256=XemBxgi_7NElaO7W-_6xLZHmAU9NIAeNH2yZqAzgHtQ,570
|
|
14
|
+
schoolmospy/utils/logging.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
schoolmospy-0.2.2.dist-info/METADATA,sha256=8D26pY9mAJij3SVnFA9YRMDeSj7aNzA_jENP3T0w_Kc,2953
|
|
16
|
+
schoolmospy-0.2.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
17
|
+
schoolmospy-0.2.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
18
|
+
schoolmospy-0.2.2.dist-info/RECORD,,
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: schoolmospy
|
|
3
|
-
Version: 0.0.2
|
|
4
|
-
Summary: A lightweight async Python wrapper for school.mos.ru APIs
|
|
5
|
-
License: GPL-3.0-only
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Keywords: school,mos,api,education,async,wrapper,python
|
|
8
|
-
Author: Ivan Kriventsev
|
|
9
|
-
Author-email: xd2dd@icloud.com
|
|
10
|
-
Requires-Python: >=3.12
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
-
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
-
Requires-Dist: aiohttp (>=3.12.15,<4.0.0)
|
|
17
|
-
Requires-Dist: pydantic (>=2.11.9,<3.0.0)
|
|
18
|
-
Project-URL: Documentation, https://xd2dd.github.io/schoolmospy
|
|
19
|
-
Project-URL: Homepage, https://github.com/xd2dd/schoolmospy
|
|
20
|
-
Project-URL: Issues, https://github.com/xd2dd/schoolmospy/issues
|
|
21
|
-
Description-Content-Type: text/markdown
|
|
22
|
-
|
|
23
|
-
# 📕 SchoolMosPy
|
|
24
|
-
|
|
25
|
-
SchoolMosPy - a lightweight Python wrapper for school.mos.py APIs.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
schoolmospy/__init__.py,sha256=TC7F5zn-EtDtAv0xJpNlIuAEcqT94ih269zYKnE3dS8,111
|
|
2
|
-
schoolmospy/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
schoolmospy/core/basic_client.py,sha256=3oYdm5GdIAqA_EIBCFc8a2f-FmCuUVdg5TioW9mYxHw,3039
|
|
4
|
-
schoolmospy/core/homeworks_client.py,sha256=Y_qdQBQmwkub0O6KzLeYlhuFdMEJutUx9BmrdHafpwQ,1815
|
|
5
|
-
schoolmospy/core/marks_client.py,sha256=RxERCe-DJcMNTBogpd7NFeX8Nu2DB5p9nHDS5p6Baw0,1543
|
|
6
|
-
schoolmospy/core/student_client.py,sha256=frf6ezS-QCXsd77UouKkuphUz5ub088CnUbbpZ1jYmM,1040
|
|
7
|
-
schoolmospy/models/homeworks.py,sha256=0olnry0IhbhCiLTY4Y7OQdVWVyLJSdQ168cNhhKmg5A,998
|
|
8
|
-
schoolmospy/models/marks.py,sha256=3jVWRi-l7Q2gwkUuY4wudpjH-URN_D_bFYTlX_RVr8Y,765
|
|
9
|
-
schoolmospy/models/profile.py,sha256=UivTgSNFFr_Eic9Dethq-ROBLLUgCFhQcrnnhKaz8tc,1648
|
|
10
|
-
schoolmospy/models/userinfo.py,sha256=_-hY0ZOBU15w12B3FpiilTJxkD8rYNxi1UNCt5D0pY0,1009
|
|
11
|
-
schoolmospy/utils/exceptions.py,sha256=AvfHEB2gYbJCbg4w_WTPx_2yhf8sRbyXYy1jMe_XM1U,538
|
|
12
|
-
schoolmospy/utils/logging.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
schoolmospy-0.0.2.dist-info/METADATA,sha256=yi9_9k2A0O3P3skwOx2e0sbSArgadYnNEzYC9UO9mU0,997
|
|
14
|
-
schoolmospy-0.0.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
15
|
-
schoolmospy-0.0.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
16
|
-
schoolmospy-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|