python-terminusgps 19.2.0__py3-none-any.whl → 20.0.0__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.

Potentially problematic release.


This version of python-terminusgps might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 19.2.0
3
+ Version: 20.0.0
4
4
  Summary: Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more.
5
5
  Project-URL: Documentation, https://app.terminusgps.com/docs/apps/python-terminusgps/index.html
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -15,9 +15,9 @@ terminusgps/twilio/__init__.py,sha256=dYo41F2jft_eHDWSUtSpKGSRG1bewq_qClqilUJZkY
15
15
  terminusgps/twilio/caller.py,sha256=nHCIwUulo-C_v2orsp6OY0nuJA6YetSkxpMTwrRQ-uA,1831
16
16
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  terminusgps/wialon/constants.py,sha256=u7y9MsA5LYvjPjxJnCMQdprTF3QhPPR9j4MvzoSNBaw,1628
18
- terminusgps/wialon/errors.py,sha256=Fl8A0peF5HpDdR3y0r3g86-iQ4kQgye3FYQZKGe3T7Y,984
19
18
  terminusgps/wialon/flags.py,sha256=-OoH-eZM54yjRqxsAXL8VImdQu_7C0OAxCrFqaCEuko,13510
20
- terminusgps/wialon/session.py,sha256=kgBFOB_gMmQS35mcmNOVIAnMvy9smrA2cUoD3QM3-3U,10857
19
+ terminusgps/wialon/logger.py,sha256=nUBsaLMaffSaAHGHAM6mFXDzix9hbNecVtA3INVtii8,968
20
+ terminusgps/wialon/session.py,sha256=47Cq3cM4sF-lySPtafzizKHeHbfuDuK1CnR0Jrmwk-Q,10634
21
21
  terminusgps/wialon/utils.py,sha256=KeZmV-MEdGOHXrsyn6IIoyX0EgVYiWYjvacXyZVr1u8,6501
22
22
  terminusgps/wialon/items/__init__.py,sha256=cfUC5sfVsTwmpgsR-w9wA4ay6_EZYAPgEeuw2k06RJM,256
23
23
  terminusgps/wialon/items/base.py,sha256=EAtzlnCvB7WTu3iX1bV1-S9TvwXc-Eez7e0X4TMiK9U,6943
@@ -29,7 +29,7 @@ terminusgps/wialon/items/route.py,sha256=PTJx1gmT_PGz7nlSSUS2VzjYD-aAuvkEOIdIFne
29
29
  terminusgps/wialon/items/unit.py,sha256=PwF7xlpDWI5MpM_u6TmYZjNHWk6TSKM4rJ4OB9CIn4A,7533
30
30
  terminusgps/wialon/items/unit_group.py,sha256=xc7zYitPE59_WYS-G857jeIQnQcUAxLBH3X6Y1VDg_8,4089
31
31
  terminusgps/wialon/items/user.py,sha256=INwAibQVmjNNelepQXMfDevgJqMvIjHHgEjAMLRvhB0,7082
32
- python_terminusgps-19.2.0.dist-info/METADATA,sha256=t4uVsM26NzgtvX98ma1Ps1ZpG01K12isrW2PLh7urBo,912
33
- python_terminusgps-19.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
- python_terminusgps-19.2.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
- python_terminusgps-19.2.0.dist-info/RECORD,,
32
+ python_terminusgps-20.0.0.dist-info/METADATA,sha256=ufm3V1VjwT2xa_damT1cBxAoOmoCcYRmH2ZtNHYLKG8,912
33
+ python_terminusgps-20.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
+ python_terminusgps-20.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
+ python_terminusgps-20.0.0.dist-info/RECORD,,
@@ -0,0 +1,29 @@
1
+ import logging
2
+
3
+
4
+ class WialonLogger:
5
+ def __init__(
6
+ self,
7
+ logger: logging.Logger,
8
+ level: int = logging.DEBUG,
9
+ format: str = "%(name)s - %(levelname)s - %(asctime)s - %(message)s",
10
+ use_stream_handler: bool = True,
11
+ use_file_handler: bool = False,
12
+ filename: str = "wialon_debug.log",
13
+ ) -> None:
14
+ self.logger = logger
15
+ self.logger.setLevel(level)
16
+ formatter = logging.Formatter(format)
17
+
18
+ if use_stream_handler and not self.logger.handlers:
19
+ stream_handler = logging.StreamHandler()
20
+ stream_handler.setFormatter(formatter)
21
+ self.logger.addHandler(stream_handler)
22
+
23
+ if use_file_handler and not self.logger.handlers:
24
+ file_handler = logging.FileHandler(filename)
25
+ file_handler.setFormatter(formatter)
26
+ self.logger.addHandler(file_handler)
27
+
28
+ def get_logger(self) -> logging.Logger:
29
+ return self.logger
@@ -1,15 +1,15 @@
1
- import threading
2
- import logging
3
- import typing
4
1
  import dataclasses
5
2
  import datetime
3
+ import logging
4
+ import threading
5
+ import typing
6
6
 
7
- from wialon.api import WialonError
8
- from wialon.api import Wialon as WialonAPI
9
7
  from django.conf import settings
10
8
  from django.utils import timezone
9
+ from wialon.api import Wialon as WialonBase
10
+ from wialon.api import WialonError
11
11
 
12
- from terminusgps.wialon.errors import WialonLogoutError, WialonLoginError
12
+ from terminusgps.wialon.logger import WialonLogger
13
13
 
14
14
 
15
15
  @dataclasses.dataclass
@@ -22,27 +22,21 @@ class WialonAPICall:
22
22
  error: Exception | None = None
23
23
 
24
24
 
25
- class Wialon(WialonAPI):
25
+ class Wialon(WialonBase):
26
26
  def __init__(self, log_level: int = logging.INFO, *args, **kwargs) -> None:
27
27
  super().__init__(*args, **kwargs)
28
28
  self.call_history: list[WialonAPICall] = []
29
- self.logger = self.create_logger(log_level)
29
+ self.logger = WialonLogger(
30
+ logging.getLogger(self.__class__.__name__), level=log_level
31
+ ).get_logger()
30
32
 
31
33
  @property
32
34
  def total_calls(self) -> int:
33
35
  return len(self.call_history)
34
36
 
35
- @property
36
- def successful_calls(self) -> list[WialonAPICall | None]:
37
- return [call for call in self.call_history if not call.error]
38
-
39
- @property
40
- def failed_calls(self) -> list[WialonAPICall | None]:
41
- return [call for call in self.call_history if call.error]
42
-
43
- @property
44
- def failure_rate(self) -> float:
45
- return len(self.failed_calls) / self.total_calls
37
+ def token_login(self, *args, **kwargs) -> typing.Any:
38
+ kwargs["appName"] = "python-terminusgps"
39
+ return self.call("token_login", *args, **kwargs)
46
40
 
47
41
  def call(self, action_name: str, *argc, **kwargs) -> typing.Any:
48
42
  self.logger.debug(f"Executing '{action_name}'...")
@@ -56,31 +50,18 @@ class Wialon(WialonAPI):
56
50
  self.logger.debug(f"Executed '{action_name}' successfully.")
57
51
  return result
58
52
  except WialonError as e:
59
- self.logger.warning(f"Failed to execute '{action_name}': '{e}'")
60
53
  call_record.error = e
61
- raise
54
+ self.logger.warning(f"Failed to execute '{action_name}': '{e}'")
55
+ return
62
56
  finally:
63
57
  self.call_history.append(call_record)
64
58
 
65
- def create_logger(self, log_level: int) -> logging.Logger:
66
- logger = logging.getLogger(self.__class__.__name__)
67
- handler = logging.StreamHandler()
68
- formatter = logging.Formatter(
69
- "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
70
- )
71
-
72
- logger.setLevel(log_level)
73
- handler.setFormatter(formatter)
74
- logger.addHandler(handler)
75
- return logger
76
-
77
59
 
78
60
  class WialonSession:
79
61
  def __init__(
80
62
  self,
81
63
  token: str | None = None,
82
64
  sid: str | None = None,
83
- uid: str | None = None,
84
65
  scheme: str = "https",
85
66
  host: str = "hst-api.wialon.com",
86
67
  port: int = 443,
@@ -93,35 +74,31 @@ class WialonSession:
93
74
  :type token: :py:obj:`str` | :py:obj:`None`
94
75
  :param sid: An optional Wialon API session id. If provided, the session is continued.
95
76
  :type sid: :py:obj:`str` | :py:obj:`None`
96
- :raises ImproperlyConfigured: If either :confval:`WIALON_TOKEN` or :confval:`WIALON_ADMIN_ID` is not set.
77
+ :param scheme: HTTP request scheme to use. Default is ``"https"``.
78
+ :type scheme: :py:obj:`str`
79
+ :param host: Wialon API host url. Default is ``"hst-api.wialon.com"``.
80
+ :type host: :py:obj:`str`
81
+ :param port: Wialon API host port. Default is ``443``.
82
+ :type port: :py:obj:`int`
83
+ :param log_level: Severity level at which log messages should be handled. Default is ``20`` (logging.INFO).
84
+ :type log_level: :py:obj:`int`
97
85
  :returns: Nothing.
98
86
  :rtype: :py:obj:`None`
99
87
 
100
88
  """
101
89
 
102
- self.wialon_api = Wialon(
103
- scheme=scheme, host=host, port=port, sid=sid, log_level=log_level
104
- )
105
- self.token = token
106
- self.login_id = uid
90
+ self._token = token or settings.WIALON_TOKEN
107
91
  self._username = None
108
92
  self._gis_sid = None
109
93
  self._hw_gp_ip = None
110
94
  self._wsdk_version = None
111
95
  self._uid = None
112
- self.logger = self.create_logger(log_level)
113
-
114
- def create_logger(self, log_level: int) -> logging.Logger:
115
- logger = logging.getLogger(self.__class__.__name__)
116
- handler = logging.StreamHandler()
117
- formatter = logging.Formatter(
118
- "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
96
+ self.wialon_api = Wialon(
97
+ scheme=scheme, host=host, port=port, sid=sid, log_level=log_level
119
98
  )
120
-
121
- logger.setLevel(log_level)
122
- handler.setFormatter(formatter)
123
- logger.addHandler(handler)
124
- return logger
99
+ self.logger = WialonLogger(
100
+ logging.getLogger(self.__class__.__name__), level=log_level
101
+ ).get_logger()
125
102
 
126
103
  def __enter__(self) -> "WialonSession":
127
104
  assert self.token, "Wialon API token was not set"
@@ -275,11 +252,7 @@ class WialonSession:
275
252
  :value: :confval:`WIALON_TOKEN`
276
253
 
277
254
  """
278
- return self._token
279
-
280
- @token.setter
281
- def token(self, value: str | None = None) -> None:
282
- self._token = value if value else settings.WIALON_TOKEN
255
+ return str(self._token)
283
256
 
284
257
  def login(self, token: str, flags: int = sum([0x1, 0x2, 0x20])) -> str:
285
258
  """
@@ -289,39 +262,41 @@ class WialonSession:
289
262
  :type token: :py:obj:`str`
290
263
  :param flags: A login response flag integer.
291
264
  :type flags: :py:obj:`int`
292
- :raises WialonLoginError: If the login fails.
265
+ :raises WialonError: If the login fails.
266
+ :raises AssertionError: If the login token was not set.
293
267
  :returns: The new session id.
294
268
  :rtype: :py:obj:`str`
295
269
 
296
270
  """
297
271
  try:
272
+ self.logger.info("Logging into Wialon API session...")
298
273
  response = self.wialon_api.token_login(**{"token": token, "fl": flags})
299
274
  self._set_login_response(response)
300
- self.logger.info(f"Logged into Wialon API session '{response.get('eid')}'")
275
+ self.logger.debug(f"Logged into Wialon API session '{response.get('eid')}'")
301
276
  return response.get("eid")
302
277
  except (WialonError, AssertionError) as e:
303
278
  self.logger.critical(f"Failed to login to Wialon API: '{e}'")
304
- raise WialonLoginError(token, e)
279
+ raise
305
280
 
306
281
  def logout(self) -> None:
307
282
  """
308
283
  Logs out of the Wialon API session.
309
284
 
310
- :raises WialonLogoutError: If the logout fails.
311
285
  :returns: Nothing.
312
286
  :rtype: :py:obj:`None`
313
287
 
314
288
  """
289
+ self.logger.info("Logging out of Wialon API session...")
315
290
  response: dict = self.wialon_api.core_logout({})
316
- self.logger.info(
317
- f"Logged out of session '{self.id}' after {self.wialon_api.total_calls} Wialon API calls."
318
- )
319
- self.logger.debug(f"Failure rate: {self.wialon_api.failure_rate}%")
291
+
320
292
  if response.get("error") != 0:
321
293
  self.logger.warning(
322
294
  f"Failed to logout of session: '{response.get('message')}'"
323
295
  )
324
- raise WialonLogoutError(str(self.id))
296
+ else:
297
+ self.logger.debug(
298
+ f"Logged out after {self.wialon_api.total_calls} Wialon API calls."
299
+ )
325
300
 
326
301
  def _set_login_response(self, login_response: dict) -> None:
327
302
  """
@@ -367,3 +342,20 @@ class WialonSessionManager:
367
342
  if not self._session:
368
343
  self._session = WialonSession(sid=sid, log_level=log_level)
369
344
  return self._session
345
+
346
+
347
+ def main() -> None:
348
+ # Usage example
349
+ session = WialonSession(log_level=logging.DEBUG) # Instantiate session
350
+ session.login(settings.WIALON_TOKEN) # Login to session
351
+ session.wialon_api.avl_evts() # Call Wialon API
352
+ session.logout() # Logout of session
353
+
354
+ # Alternatively, use a context manager to handle logging in and out
355
+ with WialonSession() as session:
356
+ session.wialon_api.avl_evts() # Call Wialon API, logout when scope ends
357
+ return
358
+
359
+
360
+ if __name__ == "__main__":
361
+ main()
@@ -1,29 +0,0 @@
1
- from wialon.api import WialonError
2
-
3
-
4
- class WialonBaseError(Exception):
5
- def __init__(
6
- self, message: str, wialon_err: WialonError | AssertionError | None = None
7
- ) -> None:
8
- self.wialon_err = wialon_err
9
- return super().__init__(message)
10
-
11
-
12
- class WialonLoginError(WialonBaseError):
13
- def __init__(
14
- self, token: str | None, wialon_err: WialonError | AssertionError | None = None
15
- ) -> None:
16
- message = f"Failed to login to the Wialon API using token: '{token}'\n"
17
- if wialon_err:
18
- message += str(wialon_err)
19
- return super().__init__(message, wialon_err)
20
-
21
-
22
- class WialonLogoutError(WialonBaseError):
23
- def __init__(
24
- self, session_id: str, wialon_err: WialonError | AssertionError | None = None
25
- ) -> None:
26
- message = f"Failed to logout of the Wialon API session: '{session_id}'\n"
27
- if wialon_err:
28
- message += str(wialon_err)
29
- return super().__init__(message, wialon_err)