Skip to content
This repository was archived by the owner on Sep 22, 2024. It is now read-only.

Commit 5fb580f

Browse files
committed
Reduced the potentially errorneous repetition
1 parent 9665c55 commit 5fb580f

2 files changed

Lines changed: 98 additions & 71 deletions

File tree

netschoolapi/async_client_wrapper.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111

1212
class Requester(Protocol):
1313

14-
def __call__(
15-
self, path: str, method="GET", params: dict = None,
16-
json: dict = None, data: dict = None) -> Awaitable:
14+
def __call__(self, request: httpx.Request, follow_redirects=False) -> Awaitable:
1715
pass
1816

1917

@@ -31,33 +29,26 @@ def make_requester(self, requests_timeout: Optional[int]) -> Requester:
3129
return functools.partial(self.request, requests_timeout)
3230

3331
async def request(
34-
self, requests_timeout: Optional[int], path: str,
35-
method="GET", params: dict = None, json: dict = None,
36-
data: dict = None, allow_redirects=False):
32+
self, requests_timeout: Optional[int], request: httpx.Request,
33+
follow_redirects=False):
3734
if requests_timeout is None:
3835
requests_timeout = self._default_requests_timeout
3936
try:
4037
if requests_timeout == 0:
4138
return await self._infinite_request(
42-
path, method, params, json, data, allow_redirects
39+
request, follow_redirects
4340
)
4441
else:
4542
return await asyncio.wait_for(self._infinite_request(
46-
path, method, params, json, data, allow_redirects
43+
request, follow_redirects
4744
), requests_timeout)
4845
except asyncio.TimeoutError:
4946
raise errors.NoResponseFromServer from None
5047

51-
async def _infinite_request(
52-
self, path: str, method: str, params: Optional[dict],
53-
json: Optional[dict], data: Optional[dict],
54-
allow_redirects: bool):
48+
async def _infinite_request(self, request: httpx.Request, follow_redirects: bool):
5549
while True:
5650
try:
57-
response = await self.client.request(
58-
method, path, params=params, json=json, data=data, # type: ignore
59-
follow_redirects=allow_redirects # type: ignore
60-
)
51+
response = await self.client.send(request, follow_redirects=follow_redirects)
6152
except httpx.ReadTimeout:
6253
pass
6354
else:

netschoolapi/netschoolapi.py

Lines changed: 91 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ async def _die_on_bad_status(response: Response):
1919

2020

2121
class NetSchoolAPI:
22-
def __init__(
23-
self, url: str, default_requests_timeout: int = None):
22+
def __init__(self, url: str, default_requests_timeout: int = None):
2423
url = url.rstrip('/')
2524
self._wrapped_client = AsyncClientWrapper(
2625
async_client=AsyncClient(
@@ -51,10 +50,14 @@ async def login(
5150
requests_timeout: int = None):
5251
requester = self._wrapped_client.make_requester(requests_timeout)
5352
# Getting the `NSSESSIONID` cookie for `auth/getdata`
54-
await requester('logindata')
53+
await requester(self._wrapped_client.client.build_request(
54+
method="GET", url="logindata"
55+
))
5556

5657
# Getting the `NSSESSIONID` cookie for `login`
57-
response = await requester('auth/getdata', method="POST")
58+
response = await requester(self._wrapped_client.client.build_request(
59+
method="POST", url='auth/getdata'
60+
))
5861
login_meta = response.json()
5962
salt = login_meta.pop('salt')
6063

@@ -66,16 +69,18 @@ async def login(
6669

6770
try:
6871
response = await requester(
69-
'login',
70-
data={
71-
'loginType': 1,
72-
**(await self._address(school_name_or_id, requester)),
73-
'un': user_name,
74-
'pw': pw,
75-
'pw2': pw2,
76-
**login_meta,
77-
},
78-
method="POST"
72+
self._wrapped_client.client.build_request(
73+
method="POST",
74+
url='login',
75+
data={
76+
'loginType': 1,
77+
**(await self._address(school_name_or_id, requester)),
78+
'un': user_name,
79+
'pw': pw,
80+
'pw2': pw2,
81+
**login_meta,
82+
},
83+
)
7984
)
8085
except httpx.HTTPStatusError as http_status_error:
8186
if http_status_error.response.status_code == httpx.codes.CONFLICT:
@@ -99,18 +104,22 @@ async def login(
99104
self._access_token = auth_result["at"]
100105
self._wrapped_client.client.headers['at'] = auth_result['at']
101106

102-
response = await requester('student/diary/init')
107+
response = await requester(self._wrapped_client.client.build_request(
108+
method="GET", url='student/diary/init',
109+
))
103110
diary_info = response.json()
104111
student = diary_info['students'][diary_info['currentStudentId']]
105112
self._student_id = student['studentId']
106113

107-
response = await requester('years/current')
114+
response = await requester(self._wrapped_client.client.build_request(
115+
method="GET", url='years/current'
116+
))
108117
year_reference = response.json()
109118
self._year_id = year_reference['id']
110119

111-
response = await requester(
112-
'grade/assignment/types', params={'all': False}
113-
)
120+
response = await requester(self._wrapped_client.client.build_request(
121+
method="GET", url="grade/assignment/types", params={"all": False},
122+
))
114123
assignment_reference = response.json()
115124
self._assignment_types = {
116125
assignment['id']: assignment['name']
@@ -119,13 +128,11 @@ async def login(
119128
self._login_data = (user_name, password, school_name_or_id)
120129

121130
async def _request_with_optional_relogin(
122-
self, requests_timeout: Optional[int], path: str,
123-
method="GET", params: dict = None, json: dict = None,
124-
data: dict = None, allow_redirects=False):
131+
self, requests_timeout: Optional[int], request: httpx.Request,
132+
follow_redirects=False):
125133
try:
126134
response = await self._wrapped_client.request(
127-
requests_timeout, path, method, params, json,
128-
data, allow_redirects
135+
requests_timeout, request
129136
)
130137
except httpx.HTTPStatusError as http_status_error:
131138
if (
@@ -135,8 +142,7 @@ async def _request_with_optional_relogin(
135142
if self._login_data:
136143
await self.login(*self._login_data)
137144
return await self._request_with_optional_relogin(
138-
requests_timeout, path, method, params, json,
139-
data, allow_redirects
145+
requests_timeout, request, follow_redirects
140146
)
141147
else:
142148
raise errors.AuthError(
@@ -154,7 +160,9 @@ async def download_attachment(
154160
buffer.write((
155161
await self._request_with_optional_relogin(
156162
requests_timeout,
157-
f"attachments/{attachment_id}",
163+
self._wrapped_client.client.build_request(
164+
method="GET", url=f"attachments/{attachment_id}",
165+
)
158166
)
159167
).content)
160168

@@ -172,13 +180,16 @@ async def diary(
172180

173181
response = await self._request_with_optional_relogin(
174182
requests_timeout,
175-
'student/diary',
176-
params={
177-
'studentId': self._student_id,
178-
'yearId': self._year_id,
179-
'weekStart': start.isoformat(),
180-
'weekEnd': end.isoformat(),
181-
},
183+
self._wrapped_client.client.build_request(
184+
method="GET",
185+
url="student/diary",
186+
params={
187+
'studentId': self._student_id,
188+
'yearId': self._year_id,
189+
'weekStart': start.isoformat(),
190+
'weekEnd': end.isoformat(),
191+
},
192+
)
182193
)
183194
diary_schema = schemas.Diary()
184195
diary_schema.context['assignment_types'] = self._assignment_types
@@ -199,13 +210,16 @@ async def overdue(
199210

200211
response = await self._request_with_optional_relogin(
201212
requests_timeout,
202-
'student/diary/pastMandatory',
203-
params={
204-
'studentId': self._student_id,
205-
'yearId': self._year_id,
206-
'weekStart': start.isoformat(),
207-
'weekEnd': end.isoformat(),
208-
},
213+
self._wrapped_client.client.build_request(
214+
method="GET",
215+
url='student/diary/pastMandatory',
216+
params={
217+
'studentId': self._student_id,
218+
'yearId': self._year_id,
219+
'weekStart': start.isoformat(),
220+
'weekEnd': end.isoformat(),
221+
},
222+
)
209223
)
210224
assignments_schema = schemas.Assignment()
211225
assignments_schema.context['assignment_types'] = self._assignment_types
@@ -217,8 +231,11 @@ async def announcements(
217231
requests_timeout: int = None) -> List[schemas.Announcement]:
218232
response = await self._request_with_optional_relogin(
219233
requests_timeout,
220-
'announcements',
221-
params={'take': take},
234+
self._wrapped_client.client.build_request(
235+
method="GET",
236+
url="announcements",
237+
params={"take": take},
238+
)
222239
)
223240
announcements = schemas.Announcement().load(response.json(), many=True)
224241
return announcements # type: ignore
@@ -228,10 +245,12 @@ async def attachments(
228245
requests_timeout: int = None) -> List[schemas.Attachment]:
229246
response = await self._request_with_optional_relogin(
230247
requests_timeout,
231-
method="POST",
232-
path='student/diary/get-attachments',
233-
params={'studentId': self._student_id},
234-
json={'assignId': [assignment_id]},
248+
self._wrapped_client.client.build_request(
249+
method="POST",
250+
url='student/diary/get-attachments',
251+
params={'studentId': self._student_id},
252+
json={'assignId': [assignment_id]},
253+
),
235254
)
236255
response = response.json()
237256
if not response:
@@ -243,7 +262,10 @@ async def attachments(
243262
async def school(self, requests_timeout: int = None) -> schemas.School:
244263
response = await self._request_with_optional_relogin(
245264
requests_timeout,
246-
'schools/{0}/card'.format(self._school_id),
265+
self._wrapped_client.client.build_request(
266+
method="GET",
267+
url='schools/{0}/card'.format(self._school_id),
268+
)
247269
)
248270
school = schemas.School().load(response.json())
249271
return school # type: ignore
@@ -252,8 +274,10 @@ async def logout(self, requests_timeout: int = None):
252274
try:
253275
await self._wrapped_client.request(
254276
requests_timeout,
255-
'auth/logout',
256-
method="POST",
277+
self._wrapped_client.client.build_request(
278+
method="POST",
279+
url='auth/logout',
280+
)
257281
)
258282
except httpx.HTTPStatusError as http_status_error:
259283
if (
@@ -273,14 +297,24 @@ async def full_logout(self, requests_timeout: int = None):
273297

274298
async def schools(
275299
self, requests_timeout: int = None) -> List[schemas.ShortSchool]:
276-
resp = await self._wrapped_client.request(requests_timeout, "addresses/schools")
300+
resp = await self._wrapped_client.request(
301+
requests_timeout,
302+
self._wrapped_client.client.build_request(
303+
method="GET", url="addresses/schools",
304+
)
305+
)
277306
schools = schemas.ShortSchool().load(resp.json(), many=True)
278307
return schools # type: ignore
279308

280309
async def _address(
281310
self, school_name_or_id: Union[int, str],
282311
requester: Requester) -> Dict[str, int]:
283-
schools = (await requester("addresses/schools")).json()
312+
schools = (await requester(
313+
self._wrapped_client.client.build_request(
314+
method="GET",
315+
url="addresses/schools",
316+
)
317+
)).json()
284318

285319
for school in schools:
286320
if school["name"] == school_name_or_id or school["id"] == school_name_or_id:
@@ -301,8 +335,10 @@ async def download_profile_picture(
301335
buffer.write((
302336
await self._request_with_optional_relogin(
303337
requests_timeout,
304-
"users/photo",
305-
params={"at": self._access_token, "userId": user_id},
306-
allow_redirects=True
338+
self._wrapped_client.client.build_request(
339+
method="GET",
340+
url="users/photo",
341+
params={"at": self._access_token, "userId": user_id},
342+
)
307343
)
308344
).content)

0 commit comments

Comments
 (0)