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.
- {python_terminusgps-19.2.0.dist-info → python_terminusgps-20.0.0.dist-info}/METADATA +1 -1
- {python_terminusgps-19.2.0.dist-info → python_terminusgps-20.0.0.dist-info}/RECORD +6 -6
- terminusgps/wialon/logger.py +29 -0
- terminusgps/wialon/session.py +58 -66
- terminusgps/wialon/errors.py +0 -29
- {python_terminusgps-19.2.0.dist-info → python_terminusgps-20.0.0.dist-info}/WHEEL +0 -0
- {python_terminusgps-19.2.0.dist-info → python_terminusgps-20.0.0.dist-info}/licenses/COPYING +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-terminusgps
|
|
3
|
-
Version:
|
|
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/
|
|
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-
|
|
33
|
-
python_terminusgps-
|
|
34
|
-
python_terminusgps-
|
|
35
|
-
python_terminusgps-
|
|
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
|
terminusgps/wialon/session.py
CHANGED
|
@@ -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.
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
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
|
-
|
|
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
|
-
:
|
|
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.
|
|
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.
|
|
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
|
-
|
|
122
|
-
|
|
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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()
|
terminusgps/wialon/errors.py
DELETED
|
@@ -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)
|
|
File without changes
|
{python_terminusgps-19.2.0.dist-info → python_terminusgps-20.0.0.dist-info}/licenses/COPYING
RENAMED
|
File without changes
|