python-terminusgps 33.5.0__py3-none-any.whl → 34.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-33.5.0.dist-info → python_terminusgps-34.0.0.dist-info}/METADATA +1 -1
- {python_terminusgps-33.5.0.dist-info → python_terminusgps-34.0.0.dist-info}/RECORD +12 -8
- terminusgps/authorizenet/auth.py +3 -3
- terminusgps/authorizenet/profiles/base.py +11 -4
- terminusgps/authorizenet/profiles/payments.py +7 -2
- terminusgps/aws/notifications.py +193 -0
- terminusgps/aws/tests/__init__.py +0 -0
- terminusgps/aws/tests/test_notifications.py +0 -0
- terminusgps/aws/tests/test_secrets.py +0 -0
- terminusgps/aws/tests/test_utils.py +0 -0
- terminusgps/aws/notifier.py +0 -49
- {python_terminusgps-33.5.0.dist-info → python_terminusgps-34.0.0.dist-info}/WHEEL +0 -0
- {python_terminusgps-33.5.0.dist-info → python_terminusgps-34.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: 34.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://docs.terminusgps.com
|
|
6
6
|
Project-URL: Repository, https://github.com/terminusgps/python-terminusgps
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
terminusgps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
terminusgps/authorizenet/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
terminusgps/authorizenet/auth.py,sha256=
|
|
3
|
+
terminusgps/authorizenet/auth.py,sha256=g2tJPxP9V1nXnUcKzhHSRSs6ruSIHej5_hcf8P7bod8,1262
|
|
4
4
|
terminusgps/authorizenet/constants.py,sha256=xmulPmiBLhFfZoc7Il3l-DZA9Nq5HSaJmJKU-v-5X-Y,420
|
|
5
5
|
terminusgps/authorizenet/controllers.py,sha256=9t62qdGpmAkP4tNyPefd7vBRutXvMWsxql6z_pg52Bg,2146
|
|
6
6
|
terminusgps/authorizenet/utils.py,sha256=FrKqXWrplcgiET1rDTmUaqmN_ze7j93jWgfFeJR8rlg,7073
|
|
7
7
|
terminusgps/authorizenet/profiles/__init__.py,sha256=IG4XCEEYtHKqXOatlZlob6J3ukAgF7cFR-RXxOSMS1c,161
|
|
8
8
|
terminusgps/authorizenet/profiles/addresses.py,sha256=xDlnFlIjuR7NVXwfj5aJT9E_GolnYFuYASkfenvWfm8,6292
|
|
9
|
-
terminusgps/authorizenet/profiles/base.py,sha256=
|
|
9
|
+
terminusgps/authorizenet/profiles/base.py,sha256=Pu1NGrvC5Ox2W1oZuVcPqUw3aUoSK191Evexw1U6_3k,3940
|
|
10
10
|
terminusgps/authorizenet/profiles/customers.py,sha256=ArXOHPgyBu01tgBPHHYyezb4PIeXh70IWjYCy-lHpWg,11734
|
|
11
|
-
terminusgps/authorizenet/profiles/payments.py,sha256=
|
|
11
|
+
terminusgps/authorizenet/profiles/payments.py,sha256=nhudGuJ6RzmK0MrhDVuYL2BxvyzKNpliBIfIpFU5Y-4,11038
|
|
12
12
|
terminusgps/authorizenet/profiles/subscriptions.py,sha256=m_jb9GqeD1tLmeqSnaGwJrzPcQOulEkF8K1wCaqKR24,7924
|
|
13
13
|
terminusgps/authorizenet/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
14
|
terminusgps/authorizenet/tests/test_auth.py,sha256=sdByYrcv8RKjcJckOHbyHH1z_M4qrATFI3qj_XDQXbk,1624
|
|
15
15
|
terminusgps/authorizenet/tests/test_profiles.py,sha256=tvLBY0iSAC33RlWiBP_NSnPskUQBjfrf0YHMpR-m22k,7566
|
|
16
16
|
terminusgps/authorizenet/tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
terminusgps/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
terminusgps/aws/
|
|
18
|
+
terminusgps/aws/notifications.py,sha256=N5p9EqN4wqBRJAMEFOjyseVatpwsxlB0QrHyqFDK5SI,5698
|
|
19
19
|
terminusgps/aws/secrets.py,sha256=MxQEmmBLpMUQ2tYAsHdCYf-7RZ84LiogdKcTsACX5dw,361
|
|
20
20
|
terminusgps/aws/utils.py,sha256=68GWcllu4h41qzFiKdUkWOAA4LDsTPqRY446VRMxYsY,116
|
|
21
|
+
terminusgps/aws/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
terminusgps/aws/tests/test_notifications.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
terminusgps/aws/tests/test_secrets.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
terminusgps/aws/tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
25
|
terminusgps/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
26
|
terminusgps/django/mixins.py,sha256=Q9ZJuzpk3d9lDnlVA8ZTVvnZWxB13p08EQ8yVJcztn4,1034
|
|
23
27
|
terminusgps/django/settings.py,sha256=yJIcBE0xjY60AXF_gonY5hS3ofseqPW2k9uSoELgoho,639
|
|
@@ -50,7 +54,7 @@ terminusgps/wialon/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
50
54
|
terminusgps/wialon/tests/test_items.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
55
|
terminusgps/wialon/tests/test_session.py,sha256=9mBlYchMo9NeqRIZsmxYzrM1zBHorqu4ooxqSNppLpI,1336
|
|
52
56
|
terminusgps/wialon/tests/test_utils.py,sha256=SK4PxJQGECFnzx_EQeRAQfsQ5_3FLaVcis2W9u_ibuI,1730
|
|
53
|
-
python_terminusgps-
|
|
54
|
-
python_terminusgps-
|
|
55
|
-
python_terminusgps-
|
|
56
|
-
python_terminusgps-
|
|
57
|
+
python_terminusgps-34.0.0.dist-info/METADATA,sha256=OLumu5xwbGDw-7yR3niZdmytYWiKwS80xQMazYTcy5g,1616
|
|
58
|
+
python_terminusgps-34.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
59
|
+
python_terminusgps-34.0.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
60
|
+
python_terminusgps-34.0.0.dist-info/RECORD,,
|
terminusgps/authorizenet/auth.py
CHANGED
|
@@ -10,7 +10,7 @@ if not settings.configured:
|
|
|
10
10
|
|
|
11
11
|
def get_merchant_auth() -> merchantAuthenticationType:
|
|
12
12
|
"""
|
|
13
|
-
Returns the merchant authentication information for Authorizenet API requests.
|
|
13
|
+
Returns the current merchant authentication information for Authorizenet API requests.
|
|
14
14
|
|
|
15
15
|
:returns: A merchant authentication object.
|
|
16
16
|
:rtype: :py:obj:`~authorizenet.apicontractsv1.merchantAuthenticationType`
|
|
@@ -24,7 +24,7 @@ def get_merchant_auth() -> merchantAuthenticationType:
|
|
|
24
24
|
|
|
25
25
|
def get_environment() -> str:
|
|
26
26
|
"""
|
|
27
|
-
Returns the environment for Authorizenet API requests.
|
|
27
|
+
Returns the current environment for Authorizenet API requests.
|
|
28
28
|
|
|
29
29
|
:returns: An Authorizenet API environment string.
|
|
30
30
|
:rtype: :py:obj:`str`
|
|
@@ -35,7 +35,7 @@ def get_environment() -> str:
|
|
|
35
35
|
|
|
36
36
|
def get_validation_mode() -> str:
|
|
37
37
|
"""
|
|
38
|
-
Returns the validation mode for Authorizenet API requests.
|
|
38
|
+
Returns the current validation mode for Authorizenet API requests.
|
|
39
39
|
|
|
40
40
|
:returns: An Authorizenet API validation string.
|
|
41
41
|
:rtype: :py:obj:`str`
|
|
@@ -62,6 +62,17 @@ class AuthorizenetProfileBase(AuthorizenetControllerExecutor):
|
|
|
62
62
|
"""
|
|
63
63
|
return get_merchant_auth()
|
|
64
64
|
|
|
65
|
+
@property
|
|
66
|
+
def validationMode(self) -> str:
|
|
67
|
+
"""
|
|
68
|
+
The current Authorizenet API validation mode.
|
|
69
|
+
|
|
70
|
+
:returns: An Authorizenet API validation mode string.
|
|
71
|
+
:rtype: :py:obj:`str`
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
return get_validation_mode()
|
|
75
|
+
|
|
65
76
|
|
|
66
77
|
class AuthorizenetSubProfileBase(AuthorizenetProfileBase):
|
|
67
78
|
"""Base class for Authorizenet 'sub-profiles', profiles that have an associated customer profile."""
|
|
@@ -83,10 +94,6 @@ class AuthorizenetSubProfileBase(AuthorizenetProfileBase):
|
|
|
83
94
|
self.customerProfileId = customer_profile_id
|
|
84
95
|
self.default = default
|
|
85
96
|
|
|
86
|
-
@property
|
|
87
|
-
def validationMode(self) -> str:
|
|
88
|
-
return get_validation_mode()
|
|
89
|
-
|
|
90
97
|
@property
|
|
91
98
|
def customerProfileId(self) -> str:
|
|
92
99
|
"""
|
|
@@ -8,7 +8,12 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
8
8
|
|
|
9
9
|
@property
|
|
10
10
|
def last_4(self) -> str | None:
|
|
11
|
-
"""
|
|
11
|
+
"""
|
|
12
|
+
Last 4 digits of the payment profile credit card.
|
|
13
|
+
|
|
14
|
+
:type: :py:obj:`str` | :py:obj:`None`
|
|
15
|
+
|
|
16
|
+
"""
|
|
12
17
|
if self.id:
|
|
13
18
|
response = self._authorizenet_get_payment_profile()
|
|
14
19
|
return str(response.paymentProfile.payment.creditCard.cardNumber)[-4:]
|
|
@@ -31,7 +36,7 @@ class PaymentProfile(AuthorizenetSubProfileBase):
|
|
|
31
36
|
"""
|
|
32
37
|
return int(
|
|
33
38
|
self._authorizenet_create_payment_profile(
|
|
34
|
-
address, payment
|
|
39
|
+
address=address, payment=payment
|
|
35
40
|
).customerPaymentProfileId
|
|
36
41
|
)
|
|
37
42
|
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import uuid
|
|
3
|
+
from collections.abc import Sequence
|
|
4
|
+
from contextlib import AsyncExitStack
|
|
5
|
+
|
|
6
|
+
from aiobotocore.session import AioSession
|
|
7
|
+
|
|
8
|
+
from terminusgps.django.validators import validate_e164_phone_number
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class AsyncNotificationManager:
|
|
12
|
+
def __init__(
|
|
13
|
+
self, group_id: str | None = None, region_name: str = "us-east-1"
|
|
14
|
+
) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Sets :py:attr:`group_id` and :py:attr:`region_name` if provided.
|
|
17
|
+
|
|
18
|
+
:returns: Nothing.
|
|
19
|
+
:rtype: :py:obj:`None`
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
self._exit_stack = AsyncExitStack()
|
|
23
|
+
self._sns_client = None
|
|
24
|
+
self._region_name = region_name
|
|
25
|
+
self.group_id = group_id
|
|
26
|
+
|
|
27
|
+
async def __aenter__(self) -> "AsyncNotificationManager":
|
|
28
|
+
"""
|
|
29
|
+
Creates an asyncronous session and client.
|
|
30
|
+
|
|
31
|
+
:returns: The notification manager.
|
|
32
|
+
:rtype: :py:obj:`~terminusgps.aws.notifications.AsyncNotificationManager`
|
|
33
|
+
|
|
34
|
+
"""
|
|
35
|
+
session = AioSession()
|
|
36
|
+
self._sns_client = await self._exit_stack.enter_async_context(
|
|
37
|
+
session.create_client("sns", region_name=self.region_name)
|
|
38
|
+
)
|
|
39
|
+
return self
|
|
40
|
+
|
|
41
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Destroys the asyncronous session.
|
|
44
|
+
|
|
45
|
+
:param exc_type: Exception type.
|
|
46
|
+
:param exc_val: Exception value.
|
|
47
|
+
:param exc_tb: Exception traceback.
|
|
48
|
+
:returns: Nothing.
|
|
49
|
+
:rtype: :py:obj:`None`
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb)
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def region_name(self) -> str:
|
|
56
|
+
"""
|
|
57
|
+
An AWS region name.
|
|
58
|
+
|
|
59
|
+
:type: :py:obj:`str`
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
return self._region_name
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def group_id(self) -> str:
|
|
66
|
+
"""
|
|
67
|
+
A message group id.
|
|
68
|
+
|
|
69
|
+
:type: :py:obj:`str`
|
|
70
|
+
|
|
71
|
+
"""
|
|
72
|
+
return str(self._group_id)
|
|
73
|
+
|
|
74
|
+
@group_id.setter
|
|
75
|
+
def group_id(self, other: str | None) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Sets :py:attr:`group_id` to ``other``.
|
|
78
|
+
|
|
79
|
+
:param other: A message group id.
|
|
80
|
+
:type other: :py:obj:`str` | :py:obj:`None`
|
|
81
|
+
:returns: Nothing.
|
|
82
|
+
:rtype: :py:obj:`None`
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
if not other:
|
|
86
|
+
other = str(uuid.uuid4())
|
|
87
|
+
self._group_id = other
|
|
88
|
+
|
|
89
|
+
async def send_push_batch(self, target_arns: Sequence[str], message: str) -> None:
|
|
90
|
+
"""
|
|
91
|
+
Sends a push notification to each AWS resource by ARN in ``target_arns``.
|
|
92
|
+
|
|
93
|
+
:param target_arns: A sequence of AWS resource ARNs.
|
|
94
|
+
:type target_arns: :py:obj:`~collections.abc.Sequence`
|
|
95
|
+
:param message: A message body.
|
|
96
|
+
:type message: :py:obj:`str`
|
|
97
|
+
:returns: Nothing.
|
|
98
|
+
:rtype: :py:obj:`None`
|
|
99
|
+
|
|
100
|
+
"""
|
|
101
|
+
await asyncio.gather(
|
|
102
|
+
*[
|
|
103
|
+
self.send_push(
|
|
104
|
+
target_arn=arn, message=message, message_id=str(uuid.uuid4())
|
|
105
|
+
)
|
|
106
|
+
for arn in target_arns
|
|
107
|
+
]
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
async def send_sms_batch(self, to_numbers: Sequence[str], message: str) -> None:
|
|
111
|
+
"""
|
|
112
|
+
Sends an sms message to each phone number in ``to_numbers``.
|
|
113
|
+
|
|
114
|
+
:param to_numbers: A sequence of phone numbers.
|
|
115
|
+
:type to_numbers: :py:obj:`~collections.abc.Sequence`
|
|
116
|
+
:param message: A message body.
|
|
117
|
+
:type message: :py:obj:`str`
|
|
118
|
+
:raises ValidationError: If a ``to_number`` wasn't a valid E.164 formatted phone number.
|
|
119
|
+
:returns: Nothing.
|
|
120
|
+
:rtype: :py:obj:`None`
|
|
121
|
+
|
|
122
|
+
"""
|
|
123
|
+
for to_number in to_numbers:
|
|
124
|
+
validate_e164_phone_number(to_number)
|
|
125
|
+
|
|
126
|
+
await asyncio.gather(
|
|
127
|
+
*[
|
|
128
|
+
self.send_sms(
|
|
129
|
+
to_number=num, message=message, message_id=str(uuid.uuid4())
|
|
130
|
+
)
|
|
131
|
+
for num in to_numbers
|
|
132
|
+
]
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
async def send_sms(self, to_number: str, message: str, message_id: str) -> None:
|
|
136
|
+
"""
|
|
137
|
+
Sends an sms to ``to_number``.
|
|
138
|
+
|
|
139
|
+
:param to_number: A destination phone number.
|
|
140
|
+
:type to_number: :py:obj:`str`
|
|
141
|
+
:param message: A message body.
|
|
142
|
+
:type message: :py:obj:`str`
|
|
143
|
+
:param message_id: A message deduplication id.
|
|
144
|
+
:type message_id: :py:obj:`str`
|
|
145
|
+
:raises ValidationError: If ``to_number`` wasn't a valid E.164 formatted phone number.
|
|
146
|
+
:returns: Nothing.
|
|
147
|
+
:rtype: :py:obj:`None`
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
validate_e164_phone_number(to_number)
|
|
151
|
+
|
|
152
|
+
await self._sns_client.publish(
|
|
153
|
+
**{
|
|
154
|
+
"PhoneNumber": to_number,
|
|
155
|
+
"Message": message,
|
|
156
|
+
"MessageDeduplicationId": message_id,
|
|
157
|
+
"MessageGroupId": self.group_id,
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
async def send_push(self, target_arn: str, message: str, message_id: str) -> None:
|
|
162
|
+
"""
|
|
163
|
+
Sends a push notification to ``target_arn``.
|
|
164
|
+
|
|
165
|
+
:param target_arn: An AWS resource ARN.
|
|
166
|
+
:type target_arn: :py:obj:`str`
|
|
167
|
+
:param message: A message body.
|
|
168
|
+
:type message: :py:obj:`str`
|
|
169
|
+
:param message_id: A message deduplication id.
|
|
170
|
+
:type message_id: :py:obj:`str`
|
|
171
|
+
:returns: Nothing.
|
|
172
|
+
:rtype: :py:obj:`None`
|
|
173
|
+
|
|
174
|
+
"""
|
|
175
|
+
await self._sns_client.publish(
|
|
176
|
+
**{
|
|
177
|
+
"TargetArn": target_arn,
|
|
178
|
+
"Message": message,
|
|
179
|
+
"MessageDeduplicationId": message_id,
|
|
180
|
+
"MessageGroupId": self.group_id,
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async def main() -> None:
|
|
186
|
+
async with AsyncNotificationManager(str(uuid.uuid4())) as manager:
|
|
187
|
+
await manager.send_sms_batch(
|
|
188
|
+
["+17133049421", "+18324667085", "+18322835634"], "This is a test message."
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
if __name__ == "__main__":
|
|
193
|
+
asyncio.run(main())
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
terminusgps/aws/notifier.py
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import uuid
|
|
3
|
-
from contextlib import AsyncExitStack
|
|
4
|
-
|
|
5
|
-
from aiobotocore.session import AioSession
|
|
6
|
-
|
|
7
|
-
from terminusgps.django.validators import validate_e164_phone_number
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class AWSNotifier:
|
|
11
|
-
def __init__(self, region: str = "us-east-1") -> None:
|
|
12
|
-
self._client = None
|
|
13
|
-
self._region = region
|
|
14
|
-
self._exit_stack = AsyncExitStack()
|
|
15
|
-
|
|
16
|
-
async def __aenter__(self):
|
|
17
|
-
session = AioSession()
|
|
18
|
-
self._client = await self._exit_stack.enter_async_context(
|
|
19
|
-
session.create_client("sns")
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
23
|
-
await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb)
|
|
24
|
-
|
|
25
|
-
async def send_sms(
|
|
26
|
-
self, phone_number: str, message: str, message_id: str, group_id: str
|
|
27
|
-
) -> dict:
|
|
28
|
-
validate_e164_phone_number(phone_number)
|
|
29
|
-
await self._client.publish(
|
|
30
|
-
**{
|
|
31
|
-
"PhoneNumber": phone_number,
|
|
32
|
-
"Message": message,
|
|
33
|
-
"MessageDeduplicationId": message_id,
|
|
34
|
-
"MessageGroupId": group_id,
|
|
35
|
-
}
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
async def main() -> None:
|
|
40
|
-
notifier = AWSNotifier()
|
|
41
|
-
message_id = str(uuid.uuid4())
|
|
42
|
-
await notifier.send_sms(
|
|
43
|
-
"+17133049421", "This is a test message", message_id, "message-group"
|
|
44
|
-
)
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if __name__ == "__main__":
|
|
49
|
-
asyncio.run(main())
|
|
File without changes
|
{python_terminusgps-33.5.0.dist-info → python_terminusgps-34.0.0.dist-info}/licenses/COPYING
RENAMED
|
File without changes
|