MouseTools 4.3.0__tar.gz → 4.4.0__tar.gz

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.
Files changed (31) hide show
  1. {mousetools-4.3.0 → mousetools-4.4.0}/PKG-INFO +1 -1
  2. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/menu.py +88 -82
  3. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/search.py +2 -2
  4. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/auth.py +11 -6
  5. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/__init__.py +50 -27
  6. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/calendar/__init__.py +33 -21
  7. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/characters/__init__.py +3 -3
  8. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/enums.py +11 -0
  9. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilities/__init__.py +79 -80
  10. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilitystatus/__init__.py +35 -20
  11. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/forecastedwaittimes/__init__.py +3 -3
  12. mousetools-4.4.0/mousetools/channels/today/__init__.py +121 -0
  13. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/decorators.py +23 -2
  14. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/couchbase.py +16 -7
  15. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/disney.py +4 -7
  16. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/PKG-INFO +1 -1
  17. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/SOURCES.txt +1 -0
  18. {mousetools-4.3.0 → mousetools-4.4.0}/pyproject.toml +24 -3
  19. {mousetools-4.3.0 → mousetools-4.4.0}/LICENSE +0 -0
  20. {mousetools-4.3.0 → mousetools-4.4.0}/README.md +0 -0
  21. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/__init__.py +0 -0
  22. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/api/__init__.py +0 -0
  23. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/channels/facilities/enums.py +0 -0
  24. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/enums.py +0 -0
  25. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/mixins/__init__.py +0 -0
  26. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools/resources/environments.bin +0 -0
  27. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/dependency_links.txt +0 -0
  28. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/requires.txt +0 -0
  29. {mousetools-4.3.0 → mousetools-4.4.0}/mousetools.egg-info/top_level.txt +0 -0
  30. {mousetools-4.3.0 → mousetools-4.4.0}/setup.cfg +0 -0
  31. {mousetools-4.3.0 → mousetools-4.4.0}/tests/test_mixins.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mousetools
3
- Version: 4.3.0
3
+ Version: 4.4.0
4
4
  Summary: An unofficial Python wrapper for Disney's API
5
5
  Author: Scott Caratozzolo
6
6
  License-Expression: MIT
@@ -1,5 +1,6 @@
1
- import typing
1
+ import logging
2
2
  from datetime import datetime, timedelta
3
+ from typing import Optional
3
4
  from zoneinfo import ZoneInfo
4
5
 
5
6
  from dateutil.parser import isoparse
@@ -8,11 +9,11 @@ from mousetools.auth import auth_obj
8
9
  from mousetools.decorators import disney_property, json_property
9
10
  from mousetools.mixins.disney import DisneyAPIMixin
10
11
 
11
- # menus -> menu -> menugroups -> menuitems
12
+ logger = logging.getLogger(__name__)
12
13
 
13
14
 
14
15
  class MenuItem:
15
- def __init__(self, raw_item_data: dict, parent_resturant_id: typing.Optional[str] = None):
16
+ def __init__(self, raw_item_data: dict, parent_resturant_id: Optional[str] = None) -> None:
16
17
  self._raw_item_data = raw_item_data
17
18
  self._parent_restaurant_id = parent_resturant_id
18
19
 
@@ -20,118 +21,118 @@ class MenuItem:
20
21
  return f"MenuItem(entity_id={self.entity_id}, parent_resturant_id={self._parent_restaurant_id})"
21
22
 
22
23
  @json_property
23
- def entity_id(self) -> typing.Optional[str]:
24
+ def entity_id(self) -> Optional[str]:
24
25
  """
25
26
  The entity id of the menu item.
26
27
 
27
28
  Returns:
28
- (typing.Optional[str]): The entity id of the menu item.
29
+ (Optional[str]): The entity id of the menu item.
29
30
  """
30
31
  return self._raw_item_data["id"]
31
32
 
32
33
  @json_property
33
- def pc_short_name(self) -> typing.Optional[str]:
34
+ def pc_short_name(self) -> Optional[str]:
34
35
  """
35
36
  The short name of the menu item.
36
37
 
37
38
  Returns:
38
- (typing.Optional[str]): The short name of the menu item.
39
+ (Optional[str]): The short name of the menu item.
39
40
  """
40
41
  return self._raw_item_data["names"]["PCShort"]
41
42
 
42
43
  @json_property
43
- def pc_long_name(self) -> typing.Optional[str]:
44
+ def pc_long_name(self) -> Optional[str]:
44
45
  """
45
46
  The long name of the menu item.
46
47
 
47
48
  Returns:
48
- (typing.Optional[str]): The long name of the menu item.
49
+ (Optional[str]): The long name of the menu item.
49
50
  """
50
51
  return self._raw_item_data["names"]["PCLong"]
51
52
 
52
53
  @json_property
53
- def mobile_short_name(self) -> typing.Optional[str]:
54
+ def mobile_short_name(self) -> Optional[str]:
54
55
  """
55
56
  The short name of the menu item.
56
57
 
57
58
  Returns:
58
- (typing.Optional[str]): The short name of the menu item.
59
+ (Optional[str]): The short name of the menu item.
59
60
  """
60
61
  return self._raw_item_data["names"]["MobileShort"]
61
62
 
62
63
  @json_property
63
- def mobile_long_name(self) -> typing.Optional[str]:
64
+ def mobile_long_name(self) -> Optional[str]:
64
65
  """
65
66
  The long name of the menu item.
66
67
 
67
68
  Returns:
68
- (typing.Optional[str]): The long name of the menu item.
69
+ (Optional[str]): The long name of the menu item.
69
70
  """
70
71
  return self._raw_item_data["names"]["MobileLong"]
71
72
 
72
73
  @json_property
73
- def mickey_check(self) -> typing.Optional[bool]:
74
+ def mickey_check(self) -> Optional[bool]:
74
75
  """
75
76
  Whether the menu item is mickey check.
76
77
 
77
78
  Returns:
78
- (typing.Optional[bool]): Whether the menu item is mickey check.
79
+ (Optional[bool]): Whether the menu item is mickey check.
79
80
  """
80
81
  return self._raw_item_data["mickeyCheck"]
81
82
 
82
83
  @json_property
83
- def pc_long_description(self) -> typing.Optional[str]:
84
+ def pc_long_description(self) -> Optional[str]:
84
85
  """
85
86
  The long description of the menu item.
86
87
 
87
88
  Returns:
88
- (typing.Optional[str]): The long description of the menu item.
89
+ (Optional[str]): The long description of the menu item.
89
90
  """
90
91
  return self._raw_item_data["descriptions"]["PCLong"]["text"]
91
92
 
92
93
  @json_property
93
- def mobile_short_description(self) -> typing.Optional[str]:
94
+ def mobile_short_description(self) -> Optional[str]:
94
95
  """
95
96
  The short description of the menu item.
96
97
 
97
98
  Returns:
98
- (typing.Optional[str]): The short description of the menu item.
99
+ (Optional[str]): The short description of the menu item.
99
100
  """
100
101
  return self._raw_item_data["descriptions"]["MobileShort"]["text"]
101
102
 
102
103
  @json_property
103
- def default_selection(self) -> typing.Optional[bool]:
104
+ def default_selection(self) -> Optional[bool]:
104
105
  """
105
106
  Whether the menu item is the default selection.
106
107
 
107
108
  Returns:
108
- (typing.Optional[bool]): Whether the menu item is the default selection.
109
+ (Optional[bool]): Whether the menu item is the default selection.
109
110
  """
110
111
  return self._raw_item_data["defaultSelection"]
111
112
 
112
113
  @json_property
113
- def prices(self) -> typing.Optional[dict]:
114
+ def prices(self) -> Optional[dict]:
114
115
  """
115
116
  The prices of the menu item.
116
117
 
117
118
  Returns:
118
- (typing.Optional[dict]): The prices of the menu item.
119
+ (Optional[dict]): The prices of the menu item.
119
120
  """
120
121
  return self._raw_item_data["prices"]
121
122
 
122
123
  @json_property
123
- def per_serving_without_tax(self) -> typing.Optional[float]:
124
+ def per_serving_without_tax(self) -> Optional[float]:
124
125
  """
125
126
  The per serving without tax of the menu item.
126
127
 
127
128
  Returns:
128
- (typing.Optional[float]): The per serving without tax of the menu item.
129
+ (Optional[float]): The per serving without tax of the menu item.
129
130
  """
130
131
  return self._raw_item_data["prices"]["PerServing"]["withoutTax"]
131
132
 
132
133
 
133
134
  class MenuGroup:
134
- def __init__(self, raw_menu_group_data: dict, parent_restaurant_id: typing.Optional[str] = None):
135
+ def __init__(self, raw_menu_group_data: dict, parent_restaurant_id: Optional[str] = None) -> None:
135
136
  self._raw_menu_group_data = raw_menu_group_data
136
137
  self._parent_restaurant_id = parent_restaurant_id
137
138
 
@@ -139,92 +140,92 @@ class MenuGroup:
139
140
  return f"MenuGroup(menu_group_type={self.menu_group_type}, parent_restaurant_id={self._parent_restaurant_id})"
140
141
 
141
142
  @json_property
142
- def menu_group_type(self) -> typing.Optional[str]:
143
+ def menu_group_type(self) -> Optional[str]:
143
144
  """
144
145
  The type of the menu group.
145
146
 
146
147
  Returns:
147
- (typing.Optional[str]): The type of the menu group.
148
+ (Optional[str]): The type of the menu group.
148
149
  """
149
150
  return self._raw_menu_group_data["menuGroupType"]
150
151
 
151
152
  @json_property
152
- def multiple_price_types(self) -> typing.Optional[bool]:
153
+ def multiple_price_types(self) -> Optional[bool]:
153
154
  """
154
155
  Whether the menu group has multiple price types.
155
156
 
156
157
  Returns:
157
- (typing.Optional[bool]): Whether the menu group has multiple price types.
158
+ (Optional[bool]): Whether the menu group has multiple price types.
158
159
  """
159
160
  return self._raw_menu_group_data["multiplePriceTypes"]
160
161
 
161
162
  @json_property
162
- def mickey_check_items(self) -> typing.Optional[bool]:
163
+ def mickey_check_items(self) -> Optional[bool]:
163
164
  """
164
165
  Whether the menu group has mickey check items.
165
166
 
166
167
  Returns:
167
- (typing.Optional[bool]): Whether the menu group has mickey check items.
168
+ (Optional[bool]): Whether the menu group has mickey check items.
168
169
  """
169
170
  return self._raw_menu_group_data["mickeyCheckItems"]
170
171
 
171
172
  @json_property
172
- def names(self) -> typing.Optional[dict]:
173
+ def names(self) -> Optional[dict]:
173
174
  """
174
175
  The names of the menu group.
175
176
 
176
177
  Returns:
177
- (typing.Optional[dict]): The names of the menu group.
178
+ (Optional[dict]): The names of the menu group.
178
179
  """
179
180
  return self._raw_menu_group_data["names"]
180
181
 
181
182
  @json_property
182
- def pc_short_name(self) -> typing.Optional[str]:
183
+ def pc_short_name(self) -> Optional[str]:
183
184
  """
184
185
  The short name of the menu group.
185
186
 
186
187
  Returns:
187
- (typing.Optional[str]): The short name of the menu group.
188
+ (Optional[str]): The short name of the menu group.
188
189
  """
189
190
  return self._raw_menu_group_data["names"]["PCShort"]
190
191
 
191
192
  @json_property
192
- def pc_long_name(self) -> typing.Optional[str]:
193
+ def pc_long_name(self) -> Optional[str]:
193
194
  """
194
195
  The long name of the menu group.
195
196
 
196
197
  Returns:
197
- (typing.Optional[str]): The long name of the menu group.
198
+ (Optional[str]): The long name of the menu group.
198
199
  """
199
200
  return self._raw_menu_group_data["names"]["PCLong"]
200
201
 
201
202
  @json_property
202
- def mobile_short_name(self) -> typing.Optional[str]:
203
+ def mobile_short_name(self) -> Optional[str]:
203
204
  """
204
205
  The short name of the menu group.
205
206
 
206
207
  Returns:
207
- (typing.Optional[str]): The short name of the menu group.
208
+ (Optional[str]): The short name of the menu group.
208
209
  """
209
210
  return self._raw_menu_group_data["names"]["MobileShort"]
210
211
 
211
212
  @json_property
212
- def mobile_long_name(self) -> typing.Optional[str]:
213
+ def mobile_long_name(self) -> Optional[str]:
213
214
  """
214
215
  The long name of the menu group.
215
216
 
216
217
  Returns:
217
- (typing.Optional[str]): The long name of the menu group.
218
+ (Optional[str]): The long name of the menu group.
218
219
  """
219
220
  return self._raw_menu_group_data["names"]["MobileLong"]
220
221
 
221
222
  @property
222
- def menu_items(self) -> typing.Optional[list[MenuItem]]:
223
+ def menu_items(self) -> Optional[list[MenuItem]]:
223
224
  """
224
225
  The menu items of the menu group.
225
226
 
226
227
  Returns:
227
- (typing.Optional[list[MenuItem]]): The menu items of the menu group.
228
+ (Optional[list[MenuItem]]): The menu items of the menu group.
228
229
  """
229
230
  try:
230
231
  return [MenuItem(i, self._parent_restaurant_id) for i in self._raw_menu_group_data["menuItems"]]
@@ -233,80 +234,80 @@ class MenuGroup:
233
234
 
234
235
 
235
236
  class Menu:
236
- def __init__(self, raw_menu_data: dict, parent_restaurant_id: typing.Optional[str] = None):
237
+ def __init__(self, raw_menu_data: dict, parent_restaurant_id: Optional[str] = None) -> None:
237
238
  self._raw_menu_data = raw_menu_data
238
239
  self._parent_restaurant_id = parent_restaurant_id
239
240
 
240
- def __str__(self):
241
+ def __str__(self) -> str:
241
242
  return f"Menu(entity_id={self.entity_id}, menu_type={self.menu_type}, parent_restaurant_id={self._parent_restaurant_id})"
242
243
 
243
244
  @json_property
244
- def entity_id(self) -> typing.Optional[str]:
245
+ def entity_id(self) -> Optional[str]:
245
246
  """
246
247
  The entity id of the menu.
247
248
 
248
249
  Returns:
249
- (typing.Optional[str]): The entity id of the menu.
250
+ (Optional[str]): The entity id of the menu.
250
251
  """
251
252
  return self._raw_menu_data["id"]
252
253
 
253
254
  @json_property
254
- def menu_type(self) -> typing.Optional[str]:
255
+ def menu_type(self) -> Optional[str]:
255
256
  """
256
257
  The type of the menu.
257
258
 
258
259
  Returns:
259
- (typing.Optional[str]): The type of the menu.
260
+ (Optional[str]): The type of the menu.
260
261
  """
261
262
  return self._raw_menu_data["menuType"]
262
263
 
263
264
  @json_property
264
- def localized_menu_type(self) -> typing.Optional[str]:
265
+ def localized_menu_type(self) -> Optional[str]:
265
266
  """
266
267
  The localized type of the menu.
267
268
 
268
269
  Returns:
269
- (typing.Optional[str]): The localized type of the menu.
270
+ (Optional[str]): The localized type of the menu.
270
271
  """
271
272
  return self._raw_menu_data["localizedMenuType"]
272
273
 
273
274
  @json_property
274
- def experience_type(self) -> typing.Optional[str]:
275
+ def experience_type(self) -> Optional[str]:
275
276
  """
276
277
  The experience type of the menu.
277
278
 
278
279
  Returns:
279
- (typing.Optional[str]): The experience type of the menu.
280
+ (Optional[str]): The experience type of the menu.
280
281
  """
281
282
  return self._raw_menu_data["experienceType"]
282
283
 
283
284
  @json_property
284
- def service_style(self) -> typing.Optional[str]:
285
+ def service_style(self) -> Optional[str]:
285
286
  """
286
287
  The service style of the menu.
287
288
 
288
289
  Returns:
289
- (typing.Optional[str]): The service style of the menu.
290
+ (Optional[str]): The service style of the menu.
290
291
  """
291
292
  return self._raw_menu_data["serviceStyle"]
292
293
 
293
294
  @json_property
294
- def primary_cuisine_type(self) -> typing.Optional[str]:
295
+ def primary_cuisine_type(self) -> Optional[str]:
295
296
  """
296
297
  The primary cuisine type of the menu.
297
298
 
298
299
  Returns:
299
- (typing.Optional[str]): The primary cuisine type of the menu.
300
+ (Optional[str]): The primary cuisine type of the menu.
300
301
  """
301
302
  return self._raw_menu_data["primaryCuisineType"]
302
303
 
303
304
  @json_property
304
- def secondary_cuisine_type(self) -> typing.Optional[str]:
305
+ def secondary_cuisine_type(self) -> Optional[str]:
305
306
  """
306
307
  The secondary cuisine type of the menu.
307
308
 
308
309
  Returns:
309
- (typing.Optional[str]): The secondary cuisine type of the menu.
310
+ (Optional[str]): The secondary cuisine type of the menu.
310
311
  """
311
312
  return self._raw_menu_data["secondaryCuisineType"]
312
313
 
@@ -329,7 +330,7 @@ class Menus(DisneyAPIMixin):
329
330
 
330
331
  _menu_service_base = f"{auth_obj._environments['serviceMenuUrl']}/diningMenuSvc/orchestration/menus"
331
332
 
332
- def __init__(self, restaurant_channel_id: str, lazy_load: bool = True):
333
+ def __init__(self, restaurant_channel_id: str, lazy_load: bool = True) -> None:
333
334
  self.entity_id = restaurant_channel_id.rsplit(".", 1)[-1]
334
335
  self._menu_service_url = f"{self._menu_service_base}/{self.entity_id}"
335
336
 
@@ -338,20 +339,30 @@ class Menus(DisneyAPIMixin):
338
339
  ) # properties are rarely updated, no need to spam the API
339
340
  self._tz = ZoneInfo("UTC")
340
341
 
341
- self._disney_data: typing.Optional[dict] = None
342
+ self._disney_data: Optional[dict] = None
342
343
  self._disney_data_pull_time: datetime = datetime.now(tz=self._tz)
343
344
  if not lazy_load:
344
345
  self.refresh()
345
346
 
346
- def __str__(self):
347
+ def __str__(self) -> str:
347
348
  return f"Menus(entity_id={self.entity_id})"
348
349
 
349
- def __repr__(self):
350
+ def __repr__(self) -> str:
350
351
  return f"Menus(restaurant_channel_id={self.entity_id})"
351
352
 
352
353
  def refresh(self) -> None:
353
354
  """Pulls initial data if none exists or if it is older than the refresh interval"""
354
- if self._disney_data is None or datetime.now(tz=self._tz) - self.last_refresh > self._refresh_interval:
355
+ no_data_check = self._disney_data is None
356
+ time_since_pull = datetime.now(tz=self._tz) - self._disney_data_pull_time
357
+ old_data_check = time_since_pull > self._refresh_interval
358
+ logger.debug(
359
+ "No data check: %s, Time since last update: %s, Old data check: %s",
360
+ no_data_check,
361
+ time_since_pull,
362
+ old_data_check,
363
+ )
364
+ if no_data_check or old_data_check:
365
+ logger.info("Refreshing menu data %s", self.entity_id)
355
366
  self._disney_data = self.get_disney_data(self._menu_service_url)
356
367
  self._disney_data_pull_time = datetime.now(tz=self._tz)
357
368
 
@@ -367,48 +378,43 @@ class Menus(DisneyAPIMixin):
367
378
  return [Menu(i, self.entity_id) for i in self._disney_data["menus"]]
368
379
 
369
380
  @disney_property()
370
- def facility_name(self) -> typing.Optional[str]:
381
+ def facility_name(self) -> Optional[str]:
371
382
  """
372
383
  The name of the facility.
373
384
 
374
385
  Returns:
375
- (typing.Optional[str]): The name of the facility.
386
+ (Optional[str]): The name of the facility.
376
387
  """
377
388
  return self._disney_data["facilityName"]
378
389
 
379
390
  @disney_property()
380
- def ancestor_location_park_resort(self) -> typing.Optional[str]:
391
+ def ancestor_location_park_resort(self) -> Optional[str]:
381
392
  """
382
393
  The name of the ancestor location.
383
394
 
384
395
  Returns:
385
- (typing.Optional[str]): The name of the ancestor location.
396
+ (Optional[str]): The name of the ancestor location.
386
397
  """
387
398
  return self._disney_data["ancestorLocationParkResort"]
388
399
 
389
400
  @disney_property()
390
- def ancestor_location_land_area(self) -> typing.Optional[str]:
401
+ def ancestor_location_land_area(self) -> Optional[str]:
391
402
  """
392
403
  The name of the ancestor location.
393
404
 
394
405
  Returns:
395
- (typing.Optional[str]): The name of the ancestor location.
406
+ (Optional[str]): The name of the ancestor location.
396
407
  """
397
408
  return self._disney_data["ancestorLocationLandArea"]
398
409
 
399
- @property
400
- def last_refresh(self) -> datetime:
410
+ @disney_property()
411
+ def last_refresh(self) -> Optional[datetime]:
401
412
  """
402
413
  The last time the menus were refreshed.
403
414
 
404
415
  Returns:
405
- (datetime): The last time the menus were refreshed.
416
+ (Optional[datetime]): The last time the menus were refreshed.
406
417
  """
407
- if self._disney_data is None:
408
- self._disney_data = self.get_disney_data(self.entity_id)
409
- try:
410
- refresh_time = isoparse(self._disney_data["lastRefresh"])
411
- refresh_time = refresh_time.replace(tzinfo=self._tz)
412
- return refresh_time
413
- except (KeyError, TypeError, ValueError):
414
- return self._disney_data_pull_time
418
+ refresh_time = isoparse(self._disney_data["lastRefresh"])
419
+ refresh_time = refresh_time.replace(tzinfo=self._tz)
420
+ return refresh_time
@@ -9,7 +9,7 @@ from mousetools.mixins.disney import DisneyAPIMixin
9
9
  class Search(DisneyAPIMixin):
10
10
  _search_service_base = auth_obj._environments["searchServiceUrl"]
11
11
 
12
- def __init__(self, destination: Union[DestinationShort, str]):
12
+ def __init__(self, destination: Union[DestinationShort, str]) -> None:
13
13
  """
14
14
  Args:
15
15
  destination (Union[DestinationShort, str]): Search the facilities for this destination
@@ -54,5 +54,5 @@ class Search(DisneyAPIMixin):
54
54
  """
55
55
  return self.search(*args, **kwargs)
56
56
 
57
- def __repr__(self):
57
+ def __repr__(self) -> str:
58
58
  return f"Search(destination='{self.destination}')"
@@ -1,17 +1,20 @@
1
1
  import base64
2
2
  import json
3
- import typing
3
+ import logging
4
4
  from datetime import datetime, timedelta
5
5
  from importlib.resources import as_file, files
6
+ from typing import Optional
6
7
 
7
8
  import httpx
8
9
  from Crypto.Cipher import AES
9
10
 
11
+ logger = logging.getLogger(__name__)
12
+
10
13
 
11
14
  class Authentication:
12
- def __init__(self):
13
- self.time_of_expire: typing.Optional[datetime] = None
14
- self.access_token: typing.Optional[str] = None
15
+ def __init__(self) -> None:
16
+ self.time_of_expire: Optional[datetime] = None
17
+ self.access_token: Optional[str] = None
15
18
  self._environments = self._decrypt_file("resources/environments.bin").get("production", {})
16
19
 
17
20
  def authenticate(self) -> tuple[str, int]:
@@ -38,6 +41,7 @@ class Authentication:
38
41
  "client_id": self._environments["authzClientId"],
39
42
  }
40
43
 
44
+ logger.debug("Sending request for authentication token")
41
45
  response = httpx.post(
42
46
  f"{self._environments['authzServiceUrl']}/token",
43
47
  headers=headers,
@@ -57,6 +61,7 @@ class Authentication:
57
61
  """
58
62
 
59
63
  if self.time_of_expire is None or (datetime.now() > self.time_of_expire):
64
+ logger.info("Requesting new authentication token")
60
65
  access_token, expires_in = self.authenticate()
61
66
  self.time_of_expire = datetime.now() + timedelta(seconds=(expires_in - 10))
62
67
  self.access_token = access_token
@@ -95,7 +100,7 @@ class Authentication:
95
100
  decrypted = cipher.decrypt(file.read())
96
101
  return json.loads(decrypted.decode("Windows-1252")[:-16])
97
102
 
98
- def _e(self):
103
+ def _e(self) -> bytes:
99
104
  s = ""
100
105
  for i in range(1, 17):
101
106
  if i % 2 != 0 or i >= 16:
@@ -105,7 +110,7 @@ class Authentication:
105
110
  bytes_ = s.encode("utf-8")
106
111
  return bytes_
107
112
 
108
- def _b(self):
113
+ def _b(self) -> bytes:
109
114
  return bytes(reversed(self._e()))
110
115
 
111
116