python-terminusgps 45.2.0__py3-none-any.whl → 45.4.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: 45.2.0
3
+ Version: 45.4.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,14 +3,14 @@ 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/auth.py,sha256=ZWb9ebJp22o-ImiMLQIzSMENICnbPZOlbX5RO0IEyRU,2199
6
+ terminusgps/authorizenet/auth.py,sha256=T4lPm6eq2ZRoPffLg6GrLZn7wUZ-RTBNi0epyw6ph_w,1035
7
7
  terminusgps/authorizenet/constants.py,sha256=eukAZQVuv3XHL-Kd1gqxf8IYUqNC67ClTz4ZU7JPNYE,1459
8
- terminusgps/authorizenet/controllers.py,sha256=ohRm4tTrGcZGxU9YmELDMdRgOM57w43fPrXZCKhrQF8,1994
9
- terminusgps/authorizenet/validators.py,sha256=Wq4rqEuqG3JzOO7O1wM6oQ0FciNxxOK0HnJqTuLa8CY,3916
8
+ terminusgps/authorizenet/controllers.py,sha256=wuyKDLTpBmnfyPsHnN9uVnWlrMDUF059ctW-OiZQL-I,2055
9
+ terminusgps/authorizenet/services.py,sha256=IGW1xuc7uZBAZ4KHJGEp7dFlMb-u7Q3SmSpNmAmrkTY,2344
10
10
  terminusgps/authorizenet/api/__init__.py,sha256=VXR4Yco1yz5R-R7vgaH2zTP9VFqzfvvGy_XJVjyb3i0,154
11
11
  terminusgps/authorizenet/api/address_profiles.py,sha256=VouUN6dIxlnuE3qEiacFqqDBi_VtwvSbsELqTqFZ0BE,4746
12
12
  terminusgps/authorizenet/api/customer_profiles.py,sha256=oya9KMRE10nKLjECTIdanfV_P8-gnNZLE0sYmRYVkgM,4505
13
- terminusgps/authorizenet/api/payment_profiles.py,sha256=vSMCEJNm75ZjBex4S9wLuHn9omj_nMpQ4JtU8rj_zQc,6498
13
+ terminusgps/authorizenet/api/payment_profiles.py,sha256=r9qAPWRsUbFx0aG_ODOHz9FPVe_TlfGcliSMnx_ezhM,6082
14
14
  terminusgps/authorizenet/api/subscriptions.py,sha256=VAXKjOHLOfifrixObK6XbiJCmPobkYBzXJQrjtos9LE,4542
15
15
  terminusgps/authorizenet/api/transactions.py,sha256=drymc7uplWHOoaMmatz8nP1gDN_GDef0QVJBqB9oIfE,20
16
16
  terminusgps/wialon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -29,7 +29,7 @@ terminusgps/wialon/items/route.py,sha256=9hmRBEFRJF3lKukv_y3blZxqxv75YgFCcRALrU6
29
29
  terminusgps/wialon/items/unit.py,sha256=B5iuGEghu89SL8KzYLUytYNRa8cogsVtf-bJ_RybPTA,5522
30
30
  terminusgps/wialon/items/unit_group.py,sha256=MIR0x5IlTjcnwx8Y9wXLNTql-wwVVj7NCe7dL2vOw4c,2131
31
31
  terminusgps/wialon/items/user.py,sha256=CRSICiJ-qzybEO_gXuKyzW5oa2RQeIp0SzX9ARcdME4,5151
32
- python_terminusgps-45.2.0.dist-info/METADATA,sha256=gE5fkjeU-YUxEa_MYu7QnUF4J2brjvYRf8X_yDvmYFg,938
33
- python_terminusgps-45.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
- python_terminusgps-45.2.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
- python_terminusgps-45.2.0.dist-info/RECORD,,
32
+ python_terminusgps-45.4.0.dist-info/METADATA,sha256=K_79eu9aAP0TtWncKoZl54hH4kocEN3iqOVSklWzQBI,938
33
+ python_terminusgps-45.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
34
+ python_terminusgps-45.4.0.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
35
+ python_terminusgps-45.4.0.dist-info/RECORD,,
@@ -2,8 +2,6 @@ from authorizenet import apicontractsv1, apicontrollers
2
2
  from authorizenet.apicontrollersbase import APIOperationBase
3
3
  from lxml.objectify import ObjectifiedElement
4
4
 
5
- from terminusgps.authorizenet.auth import get_validation_mode
6
-
7
5
  __all__ = [
8
6
  "create_customer_payment_profile",
9
7
  "get_customer_payment_profile",
@@ -16,7 +14,6 @@ __all__ = [
16
14
  def create_customer_payment_profile(
17
15
  customer_profile_id: int,
18
16
  payment_profile: apicontractsv1.customerPaymentProfileType,
19
- validate: bool = True,
20
17
  ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
21
18
  """
22
19
  `createCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-create-customer-payment-profile>`_.
@@ -33,8 +30,6 @@ def create_customer_payment_profile(
33
30
  request = apicontractsv1.createCustomerPaymentProfileRequest()
34
31
  request.customerProfileId = str(customer_profile_id)
35
32
  request.paymentProfile = payment_profile
36
- if validate:
37
- request.validationMode = get_validation_mode()
38
33
  return request, apicontrollers.createCustomerPaymentProfileController
39
34
 
40
35
 
@@ -80,7 +75,6 @@ def validate_customer_payment_profile(
80
75
  request = apicontractsv1.validateCustomerPaymentProfileRequest()
81
76
  request.customerProfileId = str(customer_profile_id)
82
77
  request.customerPaymentProfileId = str(payment_profile_id)
83
- request.validationMode = get_validation_mode()
84
78
  return request, apicontrollers.validateCustomerPaymentProfileController
85
79
 
86
80
 
@@ -88,7 +82,6 @@ def update_customer_payment_profile(
88
82
  customer_profile_id: int,
89
83
  payment_profile_id: int,
90
84
  payment_profile: apicontractsv1.customerPaymentProfileType,
91
- validate: bool = True,
92
85
  ) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
93
86
  """
94
87
  `updateCustomerPaymentProfileRequest <https://developer.authorize.net/api/reference/index.html#customer-profiles-update-customer-payment-profile>`_.
@@ -99,8 +92,6 @@ def update_customer_payment_profile(
99
92
  :type payment_profile_id: int
100
93
  :param payment_profile: An Authorizenet payment profile element.
101
94
  :type payment_profile: ~authorizenet.apicontractsv1.customerPaymentProfileType
102
- :param validate: Whether to validate the payment profile. Default is True.
103
- :type validate: bool
104
95
  :returns: A tuple containing an Authorizenet API request element and controller class.
105
96
  :rtype: tuple[~lxml.objectify.ObjectifiedElement, type[~authorizenet.apicontrollersbase.APIOperationBase]]
106
97
 
@@ -111,8 +102,6 @@ def update_customer_payment_profile(
111
102
  request = apicontractsv1.updateCustomerPaymentProfileRequest()
112
103
  request.customerProfileId = str(customer_profile_id)
113
104
  request.paymentProfile = payment_profile
114
- if validate:
115
- request.validationMode = get_validation_mode()
116
105
  return request, apicontrollers.updateCustomerPaymentProfileController
117
106
 
118
107
 
@@ -1,25 +1,15 @@
1
1
  from authorizenet.apicontractsv1 import merchantAuthenticationType
2
2
  from django.conf import settings
3
- from django.core.exceptions import ImproperlyConfigured
4
3
 
5
4
 
6
5
  def get_merchant_auth() -> merchantAuthenticationType:
7
6
  """
8
7
  Returns the merchant authentication information for Authorizenet API controller execution.
9
8
 
10
- :raises ~django.core.exceptions.ImproperlyConfigured: If the :py:data:`MERCHANT_AUTH_LOGIN_ID` or the :py:data:`MERCHANT_AUTH_TRANSACTION_KEY` settings weren't set.
11
9
  :returns: A merchant authentication object.
12
10
  :rtype: ~authorizenet.apicontractsv1.merchantAuthenticationType
13
11
 
14
12
  """
15
- if not all(
16
- [
17
- hasattr(settings, "MERCHANT_AUTH_LOGIN_ID"),
18
- hasattr(settings, "MERCHANT_AUTH_TRANSACTION_KEY"),
19
- ]
20
- ):
21
- error_msg: str = "'MERCHANT_AUTH_LOGIN_ID' and 'MERCHANT_AUTH_TRANSACTION_KEY' settings are required."
22
- raise ImproperlyConfigured(error_msg)
23
13
  return merchantAuthenticationType(
24
14
  name=str(settings.MERCHANT_AUTH_LOGIN_ID),
25
15
  transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
@@ -30,14 +20,10 @@ def get_environment() -> str:
30
20
  """
31
21
  Returns the environment for Authorizenet API controller execution.
32
22
 
33
- :raises ~django.core.exceptions.ImproperlyConfigured: If the :py:data:`MERCHANT_AUTH_ENVIRONMENT` setting wasn't set.
34
23
  :returns: An Authorizenet API environment string.
35
24
  :rtype: str
36
25
 
37
26
  """
38
- if not hasattr(settings, "MERCHANT_AUTH_ENVIRONMENT"):
39
- error_msg: str = "'MERCHANT_AUTH_ENVIRONMENT' setting is required."
40
- raise ImproperlyConfigured(error_msg)
41
27
  return settings.MERCHANT_AUTH_ENVIRONMENT
42
28
 
43
29
 
@@ -45,12 +31,8 @@ def get_validation_mode() -> str:
45
31
  """
46
32
  Returns the validation mode for Authorizenet API controller execution.
47
33
 
48
- :raises ~django.core.exceptions.ImproperlyConfigured: If the :py:data:`MERCHANT_AUTH_VALIDATION_MODE` setting wasn't set.
49
34
  :returns: An Authorizenet API validation string.
50
35
  :rtype: str
51
36
 
52
37
  """
53
- if not hasattr(settings, "MERCHANT_AUTH_VALIDATION_MODE"):
54
- error_msg: str = "'MERCHANT_AUTH_VALIDATION_MODE' setting is required."
55
- raise ImproperlyConfigured(error_msg)
56
38
  return settings.MERCHANT_AUTH_VALIDATION_MODE
@@ -3,7 +3,7 @@ from lxml.objectify import ObjectifiedElement
3
3
 
4
4
 
5
5
  def execute_controller(
6
- controller: APIOperationBase,
6
+ controller: APIOperationBase, environment: str
7
7
  ) -> ObjectifiedElement | None:
8
8
  """
9
9
  Executes an Authorizenet API controller and returns its response.
@@ -19,8 +19,10 @@ def execute_controller(
19
19
  :rtype: ~lxml.objectify.ObjectifiedElement | None
20
20
 
21
21
  """
22
+ controller.setenvironment(environment)
22
23
  controller.execute()
23
24
  response = controller.getresponse()
25
+
24
26
  if response is None:
25
27
  raise AuthorizenetControllerExecutionError(
26
28
  message="Authorizenet controller response didn't exist.", code="1"
@@ -0,0 +1,60 @@
1
+ from abc import ABC
2
+ from functools import cached_property
3
+ from typing import Callable
4
+
5
+ from authorizenet.apicontractsv1 import merchantAuthenticationType
6
+ from django.conf import settings
7
+ from django.core.exceptions import ImproperlyConfigured
8
+ from lxml.objectify import ObjectifiedElement
9
+
10
+ from .auth import get_environment, get_merchant_auth, get_validation_mode
11
+ from .controllers import execute_controller
12
+
13
+
14
+ class AuthorizenetService(ABC):
15
+ """Base class for services that interact with the Authorizenet API."""
16
+
17
+ REQUIRED_SETTINGS = (
18
+ "MERCHANT_AUTH_ENVIRONMENT",
19
+ "MERCHANT_AUTH_LOGIN_ID",
20
+ "MERCHANT_AUTH_TRANSACTION_KEY",
21
+ "MERCHANT_AUTH_VALIDATION_MODE",
22
+ )
23
+
24
+ def __init__(self) -> None:
25
+ """Raises :py:exc:`~django.core.exceptions.ImproperlyConfigured` if required settings weren't set."""
26
+ for setting in self.REQUIRED_SETTINGS:
27
+ if not hasattr(settings, setting):
28
+ raise ImproperlyConfigured(f"'{setting}' setting is required.")
29
+
30
+ def call_api(self, func: Callable, *args, **kwargs) -> ObjectifiedElement:
31
+ """
32
+ Calls the Authorizenet API function with arguments and returns the result.
33
+
34
+ :param func: An Authorizenet API function.
35
+ :type func: ~typing.Callable
36
+ :param args: Positional arguments for the API call.
37
+ :param kwargs: Keyword arguments for the API call.
38
+ :raises ~terminusgps.authorizenet.controllers.AuthorizenetControllerExecutionError: If the API call failed.
39
+ :returns: The Authorizenet API call response.
40
+ :rtype: ~lxml.objectify.ObjectifiedElement
41
+
42
+ """
43
+ request, controller_cls = func(*args, **kwargs)
44
+ request.merchantAuthentication = self.merchantAuthentication
45
+ return execute_controller(controller_cls(request), self.environment)
46
+
47
+ @cached_property
48
+ def merchantAuthentication(self) -> merchantAuthenticationType:
49
+ """Merchant authentication element for Authorizenet API requests."""
50
+ return get_merchant_auth()
51
+
52
+ @cached_property
53
+ def environment(self) -> str:
54
+ """Environment for Authorizenet API requests."""
55
+ return get_environment()
56
+
57
+ @cached_property
58
+ def validationMode(self) -> str:
59
+ """Validation mode for Authorizenet API requests."""
60
+ return get_validation_mode()
@@ -1,120 +0,0 @@
1
- import calendar
2
- import datetime
3
-
4
- from django.core.exceptions import ValidationError
5
- from django.utils.translation import gettext_lazy as _
6
-
7
-
8
- def validate_credit_card_number(value: str) -> None:
9
- """
10
- Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card number.
11
-
12
- Uses the `Luhn algorithm <https://en.wikipedia.org/wiki/Luhn_algorithm>`_ to validate the credit card number.
13
-
14
- :param value: A credit card number string.
15
- :type value: :py:obj:`str`
16
- :raises ValidationError: If the value contains non-digit characters.
17
- :raises ValidationError: If the value fails the Luhn algorithm.
18
- :returns: Nothing.
19
- :rtype: :py:obj:`None`
20
-
21
- """
22
- if not value.isdigit():
23
- raise ValidationError(
24
- _("Credit card number can only contain digits. Got '%(value)s'."),
25
- code="invalid",
26
- params={"value": value},
27
- )
28
-
29
- card_number = [int(num) for num in reversed(value)]
30
- even_digits = card_number[1::2]
31
- odd_digits = card_number[0::2]
32
-
33
- checksum = 0
34
- checksum += sum(
35
- [
36
- digit * 2 if digit * 2 <= 9 else (digit * 2) % 9 or 9
37
- for digit in even_digits
38
- ]
39
- )
40
- checksum += sum([digit for digit in odd_digits])
41
-
42
- if checksum % 10 != 0:
43
- raise ValidationError(_("Invalid credit card number."), code="invalid")
44
-
45
-
46
- def validate_credit_card_expiry_month(value: str) -> None:
47
- """
48
- Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card expiration date month.
49
-
50
- :param value: A credit card expiration year string.
51
- :type value: :py:obj:`str`
52
- :raises ValidationError: If the value contains non-digit characters.
53
- :raises ValidationError: If the value is negative.
54
- :raises ValidationError: If the value isn't between 1-12.
55
- :returns: Nothing.
56
- :rtype: :py:obj:`None`
57
-
58
- """
59
- if not value.isdigit():
60
- raise ValidationError(
61
- _("Expiration month can only contain digits, got '%(value)s'."),
62
- code="invalid",
63
- params={"value": value},
64
- )
65
- if not int(value) > 0:
66
- raise ValidationError(
67
- _(
68
- "Expiration month can only be a positive value, got '%(value)s'."
69
- ),
70
- code="invalid",
71
- params={"value": value},
72
- )
73
-
74
- try:
75
- calendar.Month(int(value))
76
- except ValueError:
77
- raise ValidationError(
78
- _("Expiration month must be between 1-12, got '%(value)s'."),
79
- code="invalid",
80
- params={"value": value},
81
- )
82
-
83
-
84
- def validate_credit_card_expiry_year(value: str) -> None:
85
- """
86
- Raises :py:exc:`~django.core.exceptions.ValidationError` if the value is an invalid credit card expiration date year.
87
-
88
- :param value: A credit card expiration year string.
89
- :type value: :py:obj:`str`
90
- :raises ValidationError: If the value contains non-digit characters.
91
- :raises ValidationError: If the value is negative.
92
- :raises ValidationError: If the value is a year in the past.
93
- :returns: Nothing.
94
- :rtype: :py:obj:`None`
95
-
96
- """
97
- if not value.isdigit():
98
- raise ValidationError(
99
- _("Expiration year can only contain digits, got '%(value)s'."),
100
- code="invalid",
101
- params={"value": value},
102
- )
103
- if not int(value) > 0:
104
- raise ValidationError(
105
- _(
106
- "Expiration year can only be a positive value, got '%(value)s'."
107
- ),
108
- code="invalid",
109
- params={"value": value},
110
- )
111
-
112
- input_year = datetime.datetime.strptime(value, "%y").year
113
- this_year = datetime.datetime.now().year
114
-
115
- if not input_year >= this_year:
116
- raise ValidationError(
117
- _("Expiration year cannot be in the past, got '%(value)s'."),
118
- code="invalid",
119
- params={"value": value},
120
- )