python-terminusgps 46.0.0__py3-none-any.whl → 47.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-terminusgps
3
- Version: 46.0.0
3
+ Version: 47.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://terminusgps.github.io/python-terminusgps
6
6
  Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
@@ -3,7 +3,7 @@ terminusgps/default_settings.py,sha256=7GLW3RlkuTbpj82KSWjcbgf-unEmrPvKCyLci14LG
3
3
  terminusgps/mixins.py,sha256=Q9ZJuzpk3d9lDnlVA8ZTVvnZWxB13p08EQ8yVJcztn4,1034
4
4
  terminusgps/validators.py,sha256=Mf0c7ku_wTQ7uv4hcLRyz0r2eRjvznIL77LLTE5uJ6E,9152
5
5
  terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- terminusgps/authorizenet/constants.py,sha256=Bat87PXB-g5_FM0pkAwX2dTHLJ05UAf_xLery4eKmr0,2723
6
+ terminusgps/authorizenet/constants.py,sha256=nz3XX2jp9icsJhbSTKi9X-TQDr6jrs35opSWpYuwePc,2757
7
7
  terminusgps/authorizenet/service.py,sha256=jjYo1vLgTZSXVNeBY6uKSma94AgEj3Q5xOAT5wUB6ko,4260
8
8
  terminusgps/authorizenet/api/__init__.py,sha256=VXR4Yco1yz5R-R7vgaH2zTP9VFqzfvvGy_XJVjyb3i0,154
9
9
  terminusgps/authorizenet/api/address_profiles.py,sha256=VouUN6dIxlnuE3qEiacFqqDBi_VtwvSbsELqTqFZ0BE,4746
@@ -14,7 +14,7 @@ terminusgps/authorizenet/api/transactions.py,sha256=zwbUXGxI1wkTXSPG4L4O5Y2fdNgx
14
14
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  terminusgps/wialon/constants.py,sha256=p2BhopeE6lXzjzdzb4ZKOz0rhJQIMUbXLrBy1Yzf57s,13730
16
16
  terminusgps/wialon/flags.py,sha256=M50EdhxQ8IMnJnU0mrHK7-h8Asc6tvNiTOOfd1dBW6A,12815
17
- terminusgps/wialon/session.py,sha256=GdgPvhNbUrvx_-vPRWsjY5TeuI3HgjlHcy315LBpZ7o,5646
17
+ terminusgps/wialon/session.py,sha256=lvxQ2uh0XSrK7DiSlkeMTfplR56111pVPK5tPCd_13U,6761
18
18
  terminusgps/wialon/utils.py,sha256=E7J9s4p7P-OePtttxcBogxu3WiXqf4xxr_Tksbisl60,9957
19
19
  terminusgps/wialon/validators.py,sha256=o5__H9HHnGYth8QAKErJG5rEub7FnT8ue0S3IQ8b67o,4232
20
20
  terminusgps/wialon/items/__init__.py,sha256=RTiY9ziXqKCB8VWGoExOIErDlUMBBfzzsA7nlOlCZ2w,41
@@ -27,7 +27,7 @@ terminusgps/wialon/items/route.py,sha256=9hmRBEFRJF3lKukv_y3blZxqxv75YgFCcRALrU6
27
27
  terminusgps/wialon/items/unit.py,sha256=B5iuGEghu89SL8KzYLUytYNRa8cogsVtf-bJ_RybPTA,5522
28
28
  terminusgps/wialon/items/unit_group.py,sha256=MIR0x5IlTjcnwx8Y9wXLNTql-wwVVj7NCe7dL2vOw4c,2131
29
29
  terminusgps/wialon/items/user.py,sha256=CRSICiJ-qzybEO_gXuKyzW5oa2RQeIp0SzX9ARcdME4,5151
30
- python_terminusgps-46.0.0.dist-info/METADATA,sha256=FEQ3DDBwtUI1T9NTyNl0Az-9M2ecIW8ihK4v8Ynftns,938
31
- python_terminusgps-46.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
- python_terminusgps-46.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
33
- python_terminusgps-46.0.0.dist-info/RECORD,,
30
+ python_terminusgps-47.0.0.dist-info/METADATA,sha256=x73rSYGD1RfEUhMbYqZbpxUI7pv2j4dd_y-7pmutVUY,938
31
+ python_terminusgps-47.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ python_terminusgps-47.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
33
+ python_terminusgps-47.0.0.dist-info/RECORD,,
@@ -46,15 +46,17 @@ class SubscriptionStatus(models.TextChoices):
46
46
  """An Authorizenet subscription status."""
47
47
 
48
48
  ACTIVE = "active", _("Active")
49
- """Active subscription."""
49
+ """Active status."""
50
50
  EXPIRED = "expired", _("Expired")
51
- """Expired subscription."""
51
+ """Expired status."""
52
52
  SUSPENDED = "suspended", _("Suspended")
53
- """Suspended subscription."""
53
+ """Suspended status."""
54
54
  CANCELED = "canceled", _("Canceled")
55
- """Canceled subscription."""
55
+ """Canceled status."""
56
56
  TERMINATED = "terminated", _("Terminated")
57
- """Terminated subscription."""
57
+ """Terminated status."""
58
+ UNKNOWN = "unknown", _("Unknown")
59
+ """Unknown status."""
58
60
 
59
61
 
60
62
  class SubscriptionIntervalUnit(models.TextChoices):
@@ -1,8 +1,11 @@
1
+ import logging
1
2
  import os
2
3
  import typing
3
4
 
4
5
  import wialon.api
5
6
 
7
+ logger = logging.getLogger(__name__)
8
+
6
9
 
7
10
  class WialonAPIError(Exception):
8
11
  """Raised when a Wialon API call fails."""
@@ -19,46 +22,56 @@ class WialonAPIError(Exception):
19
22
 
20
23
 
21
24
  class Wialon(wialon.api.Wialon):
22
- def call(self, *argc, **kwargs) -> dict[str, typing.Any]:
25
+ def call(self, action_name, *argc, **kwargs) -> dict[str, typing.Any]:
23
26
  try:
24
- return super().call(*argc, **kwargs)
27
+ return super().call(action_name, *argc, **kwargs)
25
28
  except wialon.api.WialonError as e:
29
+ logger.warning(f"Failed to execute '{action_name}': '{e}'")
26
30
  raise WialonAPIError(e)
27
31
 
28
32
 
29
33
  class WialonSession:
30
34
  def __init__(
31
35
  self,
32
- token: str | None = None,
33
- sid: str | None = None,
34
36
  scheme: str = "https",
35
37
  host: str = "hst-api.wialon.com",
36
38
  port: int = 443,
39
+ sid: str | None = None,
40
+ token: str | None = None,
41
+ auth_hash: str | None = None,
42
+ username: str | None = None,
43
+ check_service: str | None = None,
37
44
  ) -> None:
38
45
  """
39
46
  Starts or continues a Wialon API session.
40
47
 
41
- :param token: A Wialon API token. If not provided, the environment variable ``"WIALON_TOKEN"`` is used.
42
- :type token: str | None
43
- :param sid: An optional Wialon API session id. If provided, the session is continued.
44
- :type sid: str | None
45
48
  :param scheme: HTTP request scheme to use. Default is ``"https"``.
46
49
  :type scheme: str
47
50
  :param host: Wialon API host url. Default is ``"hst-api.wialon.com"``.
48
51
  :type host: str
49
52
  :param port: Wialon API port. Default is ``443``.
50
53
  :type port: int
54
+ :param sid: A Wialon API session id. Default is :py:obj:`None`.
55
+ :type sid: str | None
56
+ :param token: A Wialon API token. Default is :py:obj:`None`.
57
+ :type token: str | None
58
+ :param auth_hash: A Wialon API authentication hash. Default is environment variable ``"WIALON_TOKEN"``.
59
+ :type auth_hash: str | None
60
+ :param username: A Wialon user id to operate as during the session. Default is :py:obj:`None`.
61
+ :type username: str | None
62
+ :param check_service: A Wialon service name to check before calling the Wialon API. Default is :py:obj:`None`.
63
+ :type check_service: str | None
51
64
  :returns: Nothing.
52
65
  :rtype: None
53
66
 
54
67
  """
68
+ self._uid = None
69
+ self._wialon_api = Wialon(scheme=scheme, host=host, port=port, sid=sid)
55
70
 
56
71
  self._token = token if token else os.getenv("WIALON_TOKEN")
57
- self._username = None
58
- self._uid = None
59
- self._wialon_api = Wialon(
60
- scheme=scheme, host=host, port=port, sid=sid, token=self.token
61
- )
72
+ self._username = username
73
+ self._auth_hash = auth_hash
74
+ self._check_service = check_service
62
75
 
63
76
  def __str__(self) -> str:
64
77
  return f"Session #{self.id}"
@@ -67,27 +80,89 @@ class WialonSession:
67
80
  return f"{self.__class__}(sid={self.id})"
68
81
 
69
82
  def __enter__(self) -> "WialonSession":
83
+ """Logs into the Wialon API session if it wasn't already active before returning it."""
84
+ if self.id is None:
85
+ if self._token:
86
+ self.token_login(token=self._token, username=self._username)
87
+ elif self._auth_hash and self._username:
88
+ self.auth_hash_login(
89
+ auth_hash=self._auth_hash,
90
+ username=self._username,
91
+ check_service=self._check_service,
92
+ )
93
+ else:
94
+ raise WialonAPIError(
95
+ message="Failed to login to the Wialon API", code=9001
96
+ )
97
+ return self
98
+
99
+ def __exit__(self, *args, **kwargs) -> None:
100
+ """Logs out of the Wialon API session if :py:attr:`id` was set."""
101
+ if self.id is not None:
102
+ self.logout()
103
+
104
+ def token_login(self, token: str, username: str | None = None) -> None:
70
105
  """
71
- Logs into the Wialon API using :py:meth:`login`.
106
+ Logs in to a Wialon API session using a token.
72
107
 
73
- :raises AssertionError: If the session's Wialon API :py:attr:`token` wasn't set.
74
- :returns: A valid Wialon API session.
75
- :rtype: ~terminusgps.wialon.session.WialonSession
108
+ :param token: A Wialon API token.
109
+ :type token: str
110
+ :param username: Wialon user to operate as during the Wialon API session. Default is :py:obj:`None`.
111
+ :type username: str
112
+ :returns: Nothing.
113
+ :rtype: None
76
114
 
77
115
  """
78
- assert self.token, "Wialon API token wasn't set."
79
- self.login(self.token)
80
- return self
116
+ params = {"token": token, "flags": 0x3 if username else 0x1}
117
+ if username is not None:
118
+ params.update({"operateAs": username})
119
+ response = self.wialon_api.token_login(**params)
120
+ self.wialon_api.sid = response.get("eid")
121
+ self._username = response.get("au")
122
+ self._uid = response.get("user", {}).get("id")
123
+
124
+ def auth_hash_login(
125
+ self, auth_hash: str, username: str, check_service: str | None = None
126
+ ) -> None:
127
+ """
128
+ Logs in to a Wialon API session using an auth hash.
129
+
130
+ :param auth_hash: An authorization hash.
131
+ :type auth_hash: str
132
+ :param username: Wialon user to operate as during the Wialon API session.
133
+ :type username: str
134
+ :param check_service: Name of a Wialon service to check if the user has access to. Default is :py:obj:`None` (no service check).
135
+ :type check_service: str | None
136
+ :returns: Nothing.
137
+ :rtype: None
81
138
 
82
- def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
83
139
  """
84
- Logs out of the session by calling :py:meth:`logout`.
140
+ params = {"authHash": auth_hash, "operateAs": username}
141
+ if check_service is not None:
142
+ params.update({"checkService": check_service})
143
+ response = self.wialon_api.core_use_auth_hash(**params)
144
+ self.wialon_api.sid = response.get("eid")
145
+ self._username = response.get("au")
146
+ self._uid = response.get("user", {}).get("id")
85
147
 
148
+ def logout(self) -> None:
149
+ """
150
+ Logs out of the Wialon API session.
151
+
152
+ :raises WialonAPIError: If the Wialon API session logout failed.
86
153
  :returns: Nothing.
87
154
  :rtype: None
88
155
 
89
156
  """
90
- self.logout()
157
+ session_id = self.wialon_api.sid
158
+ if session_id is not None:
159
+ response = self.wialon_api.core_logout({})
160
+ if not int(response.get("error")) == 0:
161
+ raise WialonAPIError(
162
+ message=f"Failed to logout of the Wialon API session #{session_id}",
163
+ code=int(response.get("error")),
164
+ )
165
+ self.wialon_api.sid = None
91
166
 
92
167
  @property
93
168
  def wialon_api(self) -> Wialon:
@@ -128,74 +203,3 @@ class WialonSession:
128
203
 
129
204
  """
130
205
  return self.wialon_api.sid
131
-
132
- @property
133
- def token(self) -> str:
134
- """
135
- Wialon API token set during :py:meth:`WialonSession.__init__`.
136
-
137
- :type: str
138
-
139
- """
140
- return str(self._token)
141
-
142
- def login(self, token: str, flags: int | None = None) -> str:
143
- """
144
- Logs into the Wialon API, starts a new session then returns its id.
145
-
146
- :param token: An active Wialon API token.
147
- :type token: str
148
- :param flags: A login response flag integer.
149
- :type flags: int
150
- :raises WialonError: If the login fails.
151
- :raises AssertionError: If the login token was not set.
152
- :returns: The new session id.
153
- :rtype: str
154
-
155
- """
156
- try:
157
- response = self.wialon_api.token_login(
158
- **{"token": token, "fl": flags if flags else 0x2}
159
- )
160
- self._set_login_response(response)
161
- return response.get("eid", "")
162
- except (wialon.api.WialonError, ValueError):
163
- print("Failed to login to the Wialon API.")
164
- raise
165
-
166
- def logout(self) -> None:
167
- """
168
- Logs out of the Wialon API session.
169
-
170
- :returns: Nothing.
171
- :rtype: None
172
-
173
- """
174
- sid = self.wialon_api.sid
175
- response = self.wialon_api.core_logout({})
176
-
177
- if response.get("error") != 0:
178
- print(
179
- f"Failed to properly logout of session #{sid}: '{response.get('message')}'"
180
- )
181
- self.wialon_api.sid = None
182
-
183
- def _set_login_response(self, login_response: dict | None = None) -> None:
184
- """
185
- Sets the Wialon API session's attributes based on a login response.
186
-
187
- :param login_response: A dictionary returned from :py:meth:`login`.
188
- :type login_response: dict
189
- :raises ValueError: If ``login_response`` wasn't provided.
190
- :returns: Nothing.
191
- :rtype: None
192
-
193
- """
194
- if login_response is None:
195
- raise ValueError(
196
- f"Login response is required, got '{login_response}'"
197
- )
198
-
199
- self.wialon_api.sid = login_response.get("eid")
200
- self._uid = login_response.get("user", {}).get("id")
201
- self._username = login_response.get("au")