python-terminusgps 45.6.0__tar.gz → 45.7.0__tar.gz
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.
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/.github/workflows/sphinx.yml +19 -2
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/PKG-INFO +1 -1
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/requirements.txt +2 -1
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/authorizenet/constants.rst +4 -1
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/authorizenet/index.rst +4 -5
- python_terminusgps-45.7.0/docs/source/authorizenet/service.rst +9 -0
- python_terminusgps-45.7.0/docs/source/authorizenet/usage.rst +6 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/conf.py +1 -2
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/pyproject.toml +1 -1
- python_terminusgps-45.7.0/terminusgps/authorizenet/api/transactions.py +100 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/constants.py +23 -0
- python_terminusgps-45.7.0/terminusgps/authorizenet/service.py +112 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/uv.lock +1 -1
- python_terminusgps-45.6.0/docs/source/authorizenet/auth.rst +0 -22
- python_terminusgps-45.6.0/docs/source/authorizenet/exceptions.rst +0 -4
- python_terminusgps-45.6.0/docs/source/authorizenet/usage.rst +0 -20
- python_terminusgps-45.6.0/terminusgps/authorizenet/api/transactions.py +0 -2
- python_terminusgps-45.6.0/terminusgps/authorizenet/auth.py +0 -38
- python_terminusgps-45.6.0/terminusgps/authorizenet/controllers.py +0 -57
- python_terminusgps-45.6.0/terminusgps/authorizenet/services.py +0 -67
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/.gitignore +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/.python-version +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/COPYING +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/README.md +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/Makefile +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/make.bat +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/authorizenet/api.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/index.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/mixins.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/validators.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/constants.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/exceptions.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/index.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/items.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/session.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/wialon/usage.rst +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/__init__.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/__init__.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/__init__.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/address_profiles.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/customer_profiles.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/payment_profiles.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/subscriptions.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/default_settings.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/mixins.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/validators.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/__init__.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/constants.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/flags.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/__init__.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/account.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/base.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/factory.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/resource.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/retranslator.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/route.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/unit.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/unit_group.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/user.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/session.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/utils.py +0 -0
- {python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/validators.py +0 -0
|
@@ -12,8 +12,25 @@ jobs:
|
|
|
12
12
|
with:
|
|
13
13
|
persist-credentials: false
|
|
14
14
|
|
|
15
|
-
- name:
|
|
16
|
-
uses:
|
|
15
|
+
- name: Install uv
|
|
16
|
+
uses: astral-sh/setup-uv@v6
|
|
17
|
+
with:
|
|
18
|
+
version: "0.8.17"
|
|
19
|
+
|
|
20
|
+
- name: Set up python
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version-file: ".python-version"
|
|
24
|
+
|
|
25
|
+
- name: Install project
|
|
26
|
+
run: uv sync --locked --group docs
|
|
27
|
+
|
|
28
|
+
- name: Build docs
|
|
29
|
+
run: |
|
|
30
|
+
source .venv/bin/activate
|
|
31
|
+
cd docs
|
|
32
|
+
make html
|
|
33
|
+
deactivate
|
|
17
34
|
|
|
18
35
|
- name: Upload artifacts
|
|
19
36
|
uses: actions/upload-artifact@v4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-terminusgps
|
|
3
|
-
Version: 45.
|
|
3
|
+
Version: 45.7.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
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/docs/source/authorizenet/constants.rst
RENAMED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
Constants
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
-
These constants inherit from :py:obj
|
|
4
|
+
These constants inherit from :py:obj:`django.db.models.TextChoices`, not the built-in Python :py:obj:`~enum.StrEnum` type.
|
|
5
5
|
|
|
6
6
|
Django :py:obj:`~django.db.models.TextChoices` provides attributes such as :py:attr:`~django.db.models.TextChoices.choices`, :py:attr:`~django.db.models.TextChoices.values`, :py:attr:`~django.db.models.TextChoices.labels` and more.
|
|
7
7
|
|
|
8
8
|
.. py:currentmodule:: terminusgps.authorizenet.constants
|
|
9
9
|
|
|
10
|
+
.. autoclass:: CurrencyCode
|
|
11
|
+
:members:
|
|
12
|
+
|
|
10
13
|
.. autoclass:: Environment
|
|
11
14
|
:members:
|
|
12
15
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Authorizenet
|
|
2
2
|
============
|
|
3
3
|
|
|
4
|
-
The :py:mod:`terminusgps.authorizenet` package provides
|
|
4
|
+
The :py:mod:`terminusgps.authorizenet` package provides a Pythonic interface for interacting with the Authorizenet API.
|
|
5
5
|
|
|
6
6
|
Most `Authorizenet API endpoints <https://developer.authorize.net/api/reference/index.html>`_ are represented as plain Python functions.
|
|
7
7
|
|
|
8
|
-
.. attention::
|
|
8
|
+
.. attention:: :py:mod:`terminusgps.authorizenet` requires the following settings to be present in your Django project's ``settings.py`` module.
|
|
9
9
|
|
|
10
|
-
Using
|
|
10
|
+
Using the package without setting these settings will raise :py:exc:`~django.core.exceptions.ImproperlyConfigured`.
|
|
11
11
|
|
|
12
12
|
+-----------------------------------+---------------+
|
|
13
13
|
| setting | type |
|
|
@@ -25,8 +25,7 @@ Most `Authorizenet API endpoints <https://developer.authorize.net/api/reference/
|
|
|
25
25
|
:maxdepth: 2
|
|
26
26
|
:caption: Contents:
|
|
27
27
|
|
|
28
|
-
auth.rst
|
|
29
28
|
constants.rst
|
|
30
|
-
exceptions.rst
|
|
31
29
|
api.rst
|
|
30
|
+
service.rst
|
|
32
31
|
usage.rst
|
|
@@ -12,7 +12,7 @@ sys.path.insert(0, os.path.abspath("../../"))
|
|
|
12
12
|
project = "python-terminusgps"
|
|
13
13
|
copyright = "2025, Terminus GPS, LLC"
|
|
14
14
|
author = "Terminus GPS, LLC"
|
|
15
|
-
release = "45.6.
|
|
15
|
+
release = "45.6.1"
|
|
16
16
|
|
|
17
17
|
# -- General configuration ---------------------------------------------------
|
|
18
18
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
|
@@ -33,7 +33,6 @@ intersphinx_mapping = {
|
|
|
33
33
|
),
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
templates_path = ["_templates"]
|
|
37
36
|
exclude_patterns = []
|
|
38
37
|
|
|
39
38
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "python-terminusgps"
|
|
3
|
-
version = "45.
|
|
3
|
+
version = "45.7.0"
|
|
4
4
|
description = "Provides abstractions/utilities for working with Wialon API, Authorize.NET API, AWS API, and more."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [ {name = "Blake Nall", email = "blake@terminusgps.com" } ]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from authorizenet import apicontractsv1, apicontrollers
|
|
4
|
+
from authorizenet.apicontrollersbase import APIOperationBase
|
|
5
|
+
from lxml.objectify import ObjectifiedElement
|
|
6
|
+
|
|
7
|
+
__all__ = []
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def build_transaction_request(
|
|
11
|
+
transaction_type: str,
|
|
12
|
+
amount: Decimal,
|
|
13
|
+
payment: apicontractsv1.paymentType | None = None,
|
|
14
|
+
order: apicontractsv1.orderType | None = None,
|
|
15
|
+
address: apicontractsv1.customerAddressType | None = None,
|
|
16
|
+
customer_data: apicontractsv1.customerDataType | None = None,
|
|
17
|
+
settings: apicontractsv1.settingType | None = None,
|
|
18
|
+
line_items: apicontractsv1.ArrayOfLineItem | None = None,
|
|
19
|
+
) -> apicontractsv1.transactionRequestType:
|
|
20
|
+
request = apicontractsv1.transactionRequestType()
|
|
21
|
+
request.transactionType = transaction_type
|
|
22
|
+
request.amount = amount
|
|
23
|
+
|
|
24
|
+
if payment is not None:
|
|
25
|
+
request.payment = payment
|
|
26
|
+
if order is not None:
|
|
27
|
+
request.order = order
|
|
28
|
+
if address is not None:
|
|
29
|
+
request.billTo = address
|
|
30
|
+
if customer_data is not None:
|
|
31
|
+
request.customer = customer_data
|
|
32
|
+
if settings is not None:
|
|
33
|
+
request.transactionSettings = settings
|
|
34
|
+
if line_items is not None:
|
|
35
|
+
request.lineItems = line_items
|
|
36
|
+
return request
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def charge_credit_card(
|
|
40
|
+
amount: Decimal,
|
|
41
|
+
credit_card: apicontractsv1.creditCardType,
|
|
42
|
+
address: apicontractsv1.customerAddressType,
|
|
43
|
+
order: apicontractsv1.orderType | None = None,
|
|
44
|
+
customer_data: apicontractsv1.customerDataType | None = None,
|
|
45
|
+
settings: apicontractsv1.settingType | None = None,
|
|
46
|
+
) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
|
|
47
|
+
request = apicontractsv1.createTransactionRequest()
|
|
48
|
+
request.transactionRequest = build_transaction_request(
|
|
49
|
+
transaction_type="authCaptureTransaction",
|
|
50
|
+
amount=amount,
|
|
51
|
+
payment=apicontractsv1.paymentType(creditCard=credit_card),
|
|
52
|
+
address=address,
|
|
53
|
+
order=order,
|
|
54
|
+
customer_data=customer_data,
|
|
55
|
+
settings=settings,
|
|
56
|
+
)
|
|
57
|
+
return request, apicontrollers.createTransactionController
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def authorize_credit_card(
|
|
61
|
+
amount: Decimal,
|
|
62
|
+
credit_card: apicontractsv1.creditCardType,
|
|
63
|
+
address: apicontractsv1.customerAddressType,
|
|
64
|
+
order: apicontractsv1.orderType | None = None,
|
|
65
|
+
customer_data: apicontractsv1.customerDataType | None = None,
|
|
66
|
+
settings: apicontractsv1.settingType | None = None,
|
|
67
|
+
) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
|
|
68
|
+
request = apicontractsv1.createTransactionRequest()
|
|
69
|
+
request.transactionRequest = build_transaction_request(
|
|
70
|
+
transaction_type="authOnlyTransaction",
|
|
71
|
+
amount=amount,
|
|
72
|
+
payment=apicontractsv1.paymentType(creditCard=credit_card),
|
|
73
|
+
address=address,
|
|
74
|
+
order=order,
|
|
75
|
+
customer_data=customer_data,
|
|
76
|
+
settings=settings,
|
|
77
|
+
)
|
|
78
|
+
return request, apicontrollers.createTransactionController
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def capture_authorized_amount(
|
|
82
|
+
amount: Decimal,
|
|
83
|
+
) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
|
|
84
|
+
request = apicontractsv1.createTransactionRequest()
|
|
85
|
+
request.transactionRequest = build_transaction_request(
|
|
86
|
+
transaction_type="priorAuthCaptureTransaction", amount=amount
|
|
87
|
+
)
|
|
88
|
+
return request, apicontrollers.createTransactionController
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def refund_credit_card(
|
|
92
|
+
amount: Decimal, credit_card: apicontractsv1.creditCardType
|
|
93
|
+
) -> tuple[ObjectifiedElement, type[APIOperationBase]]:
|
|
94
|
+
request = apicontractsv1.createTransactionRequest()
|
|
95
|
+
request.transactionRequest = build_transaction_request(
|
|
96
|
+
transaction_type="refundTransaction",
|
|
97
|
+
amount=amount,
|
|
98
|
+
payment=apicontractsv1.paymentType(creditCard=credit_card),
|
|
99
|
+
)
|
|
100
|
+
return request, apicontrollers.createTransactionController
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/constants.py
RENAMED
|
@@ -4,6 +4,29 @@ from django.db import models
|
|
|
4
4
|
from django.utils.translation import gettext_lazy as _
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
class CurrencyCode(models.TextChoices):
|
|
8
|
+
USD = "USD", _("United States Dollar")
|
|
9
|
+
"""US dollar."""
|
|
10
|
+
CAD = "CAD", _("Canadian Dollar")
|
|
11
|
+
"""Canadian dollar."""
|
|
12
|
+
GBP = "GBP", _("Great British Pound")
|
|
13
|
+
"""Great British pound."""
|
|
14
|
+
DKK = "DKK", _("Danish Krone")
|
|
15
|
+
"""Danish krone."""
|
|
16
|
+
NOK = "NOK", _("Norwegian Krone")
|
|
17
|
+
"""Norwegian krone."""
|
|
18
|
+
PLN = "PLN", _("Polish Złoty")
|
|
19
|
+
"""Polish zloty."""
|
|
20
|
+
SEK = "SEK", _("Swedish Krona")
|
|
21
|
+
"""Swedish krona."""
|
|
22
|
+
EUR = "EUR", _("Euro")
|
|
23
|
+
"""Euro."""
|
|
24
|
+
AUD = "AUD", _("Australian Dollar")
|
|
25
|
+
"""Australian dollar."""
|
|
26
|
+
NZD = "NZD", _("New Zealand Dollar")
|
|
27
|
+
"""New Zealand dollar."""
|
|
28
|
+
|
|
29
|
+
|
|
7
30
|
class SubscriptionStatus(models.TextChoices):
|
|
8
31
|
"""An Authorizenet subscription status."""
|
|
9
32
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from functools import cached_property
|
|
2
|
+
|
|
3
|
+
from authorizenet.apicontractsv1 import merchantAuthenticationType
|
|
4
|
+
from authorizenet.apicontrollersbase import APIOperationBase
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.core.exceptions import ImproperlyConfigured
|
|
7
|
+
from lxml.objectify import ObjectifiedElement
|
|
8
|
+
|
|
9
|
+
if not settings.configured:
|
|
10
|
+
from terminusgps import default_settings
|
|
11
|
+
|
|
12
|
+
settings.configure(default_settings)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class AuthorizenetControllerExecutionError(Exception):
|
|
16
|
+
"""Raised when an Authorizenet API controller fails to execute."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, message: str, code: str, *args, **kwargs) -> None:
|
|
19
|
+
super().__init__(message, *args, **kwargs)
|
|
20
|
+
self._message: str = message
|
|
21
|
+
self._code: str = code
|
|
22
|
+
|
|
23
|
+
def __str__(self) -> str:
|
|
24
|
+
return f"{self.code}: {self.message}"
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def message(self) -> str:
|
|
28
|
+
"""An Authorizenet API error message."""
|
|
29
|
+
return self._message
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def code(self) -> str:
|
|
33
|
+
"""An Authorizenet API error code."""
|
|
34
|
+
return self._code
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AuthorizenetService:
|
|
38
|
+
"""A service for safely interacting with the Authorizenet API."""
|
|
39
|
+
|
|
40
|
+
REQUIRED_SETTINGS = (
|
|
41
|
+
"MERCHANT_AUTH_ENVIRONMENT",
|
|
42
|
+
"MERCHANT_AUTH_LOGIN_ID",
|
|
43
|
+
"MERCHANT_AUTH_TRANSACTION_KEY",
|
|
44
|
+
"MERCHANT_AUTH_VALIDATION_MODE",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def __init__(self) -> None:
|
|
48
|
+
"""Raises :py:exc:`~django.core.exceptions.ImproperlyConfigured` if required settings weren't set."""
|
|
49
|
+
for setting in self.REQUIRED_SETTINGS:
|
|
50
|
+
if not hasattr(settings, setting):
|
|
51
|
+
raise ImproperlyConfigured(f"'{setting}' setting is required.")
|
|
52
|
+
|
|
53
|
+
def call_api(
|
|
54
|
+
self,
|
|
55
|
+
request: ObjectifiedElement,
|
|
56
|
+
controller_cls: type[APIOperationBase],
|
|
57
|
+
reference_id: str | None = None,
|
|
58
|
+
) -> ObjectifiedElement:
|
|
59
|
+
"""
|
|
60
|
+
Adds required authentication data to the request before executing it and returning its response.
|
|
61
|
+
|
|
62
|
+
If ``reference_id`` was provided, it is added to the request before execution.
|
|
63
|
+
|
|
64
|
+
:param request: An Authorizenet API request element.
|
|
65
|
+
:type request: ~lxml.objectify.ObjectifiedElement
|
|
66
|
+
:param controller_cls: An Authorizenet controller class.
|
|
67
|
+
:type controller_cls: type[~authorizenet.apicontrollersbase.APIOperationBase]
|
|
68
|
+
:param reference_id: An optional reference id string for the API call. Default is :py:obj:`None`.
|
|
69
|
+
:type reference_id: str | None
|
|
70
|
+
:raises AuthorizenetControllerExecutionError: If the API call failed.
|
|
71
|
+
:returns: An Authorizenet API response.
|
|
72
|
+
:rtype: ~lxml.objectify.ObjectifiedElement
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
request.merchantAuthentication = self.merchantAuthentication
|
|
76
|
+
if reference_id is not None:
|
|
77
|
+
request.refId = reference_id
|
|
78
|
+
|
|
79
|
+
controller = controller_cls(request)
|
|
80
|
+
controller.setenvironment(self.environment)
|
|
81
|
+
controller.execute()
|
|
82
|
+
|
|
83
|
+
response: ObjectifiedElement | None = controller.getresponse()
|
|
84
|
+
if response is None:
|
|
85
|
+
raise AuthorizenetControllerExecutionError(
|
|
86
|
+
message="No response from the Authorizenet API controller.",
|
|
87
|
+
code="1",
|
|
88
|
+
)
|
|
89
|
+
elif response is not None and response.messages.resultCode != "Ok":
|
|
90
|
+
raise AuthorizenetControllerExecutionError(
|
|
91
|
+
message=response.messages.message[0]["text"].text,
|
|
92
|
+
code=response.messages.message[0]["code"].text,
|
|
93
|
+
)
|
|
94
|
+
return response
|
|
95
|
+
|
|
96
|
+
@cached_property
|
|
97
|
+
def merchantAuthentication(self) -> merchantAuthenticationType:
|
|
98
|
+
"""Merchant authentication element for Authorizenet API requests."""
|
|
99
|
+
return merchantAuthenticationType(
|
|
100
|
+
name=str(settings.MERCHANT_AUTH_LOGIN_ID),
|
|
101
|
+
transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
@cached_property
|
|
105
|
+
def environment(self) -> str:
|
|
106
|
+
"""Environment for Authorizenet API requests."""
|
|
107
|
+
return str(settings.MERCHANT_AUTH_ENVIRONMENT)
|
|
108
|
+
|
|
109
|
+
@cached_property
|
|
110
|
+
def validationMode(self) -> str:
|
|
111
|
+
"""Validation mode for Authorizenet API requests."""
|
|
112
|
+
return str(settings.MERCHANT_AUTH_VALIDATION_MODE)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
Authentication
|
|
2
|
-
==============
|
|
3
|
-
|
|
4
|
-
Authentication for each Authorizenet API call is handled by values defined in a Django ``settings.py`` module.
|
|
5
|
-
|
|
6
|
-
Required settings:
|
|
7
|
-
|
|
8
|
-
+-----------------------------------+---------------+
|
|
9
|
-
| setting | type |
|
|
10
|
-
+===================================+===============+
|
|
11
|
-
| ``MERCHANT_AUTH_ENVIRONMENT`` | :py:obj:`str` |
|
|
12
|
-
+-----------------------------------+---------------+
|
|
13
|
-
| ``MERCHANT_AUTH_LOGIN_ID`` | :py:obj:`str` |
|
|
14
|
-
+-----------------------------------+---------------+
|
|
15
|
-
| ``MERCHANT_AUTH_TRANSACTION_KEY`` | :py:obj:`str` |
|
|
16
|
-
+-----------------------------------+---------------+
|
|
17
|
-
| ``MERCHANT_AUTH_VALIDATION_MODE`` | :py:obj:`str` |
|
|
18
|
-
+-----------------------------------+---------------+
|
|
19
|
-
|
|
20
|
-
.. automodule:: terminusgps.authorizenet.auth
|
|
21
|
-
:synopsis: Provides functions for authenticating Authorizenet API calls.
|
|
22
|
-
:members:
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
Usage
|
|
2
|
-
=====
|
|
3
|
-
|
|
4
|
-
Check the Authorizenet API documentation for expected attributes in each response.
|
|
5
|
-
|
|
6
|
-
.. code:: python
|
|
7
|
-
|
|
8
|
-
from terminusgps.authorizenet import api as anet
|
|
9
|
-
|
|
10
|
-
# An Authorizenet 'createCustomerProfileRequest'
|
|
11
|
-
response = anet.create_customer_profile(
|
|
12
|
-
merchant_id="1",
|
|
13
|
-
email="blake@terminusgps.com",
|
|
14
|
-
description="Blake Nall"
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
# Authorizenet API calls may return None
|
|
18
|
-
# Check first before trying to access attributes on it
|
|
19
|
-
if response is not None and hasattr(response, "customerProfileId"):
|
|
20
|
-
response.customerProfileId
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
from authorizenet.apicontractsv1 import merchantAuthenticationType
|
|
2
|
-
from django.conf import settings
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def get_merchant_auth() -> merchantAuthenticationType:
|
|
6
|
-
"""
|
|
7
|
-
Returns the merchant authentication information for Authorizenet API controller execution.
|
|
8
|
-
|
|
9
|
-
:returns: A merchant authentication object.
|
|
10
|
-
:rtype: ~authorizenet.apicontractsv1.merchantAuthenticationType
|
|
11
|
-
|
|
12
|
-
"""
|
|
13
|
-
return merchantAuthenticationType(
|
|
14
|
-
name=str(settings.MERCHANT_AUTH_LOGIN_ID),
|
|
15
|
-
transactionKey=str(settings.MERCHANT_AUTH_TRANSACTION_KEY),
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def get_environment() -> str:
|
|
20
|
-
"""
|
|
21
|
-
Returns the environment for Authorizenet API controller execution.
|
|
22
|
-
|
|
23
|
-
:returns: An Authorizenet API environment string.
|
|
24
|
-
:rtype: str
|
|
25
|
-
|
|
26
|
-
"""
|
|
27
|
-
return settings.MERCHANT_AUTH_ENVIRONMENT
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def get_validation_mode() -> str:
|
|
31
|
-
"""
|
|
32
|
-
Returns the validation mode for Authorizenet API controller execution.
|
|
33
|
-
|
|
34
|
-
:returns: An Authorizenet API validation string.
|
|
35
|
-
:rtype: str
|
|
36
|
-
|
|
37
|
-
"""
|
|
38
|
-
return settings.MERCHANT_AUTH_VALIDATION_MODE
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
from authorizenet.apicontrollersbase import APIOperationBase
|
|
2
|
-
from lxml.objectify import ObjectifiedElement
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def execute_controller(
|
|
6
|
-
controller: APIOperationBase, environment: str
|
|
7
|
-
) -> ObjectifiedElement | None:
|
|
8
|
-
"""
|
|
9
|
-
Executes an Authorizenet API controller and returns its response.
|
|
10
|
-
|
|
11
|
-
:param controller: An Authorizenet API controller.
|
|
12
|
-
:type controller: ~authorizenet.apicontrollersbase.APIOperationBase
|
|
13
|
-
:param environment: Authorizenet environment to execute the controller in.
|
|
14
|
-
:type environment: :py:obj:`str`
|
|
15
|
-
:param merchant_auth: Authorizenet merchant authentication element.
|
|
16
|
-
:type merchant_auth: ~authorizenet.apicontractsv1.merchantAuthenticationType
|
|
17
|
-
:raises AuthorizenetControllerExecutionError: If the API call fails.
|
|
18
|
-
:returns: An Authorizenet API response, if any.
|
|
19
|
-
:rtype: ~lxml.objectify.ObjectifiedElement | None
|
|
20
|
-
|
|
21
|
-
"""
|
|
22
|
-
controller.setenvironment(environment)
|
|
23
|
-
controller.execute()
|
|
24
|
-
response = controller.getresponse()
|
|
25
|
-
|
|
26
|
-
if response is None:
|
|
27
|
-
raise AuthorizenetControllerExecutionError(
|
|
28
|
-
message="Authorizenet controller response didn't exist.", code="1"
|
|
29
|
-
)
|
|
30
|
-
if response is not None and response.messages.resultCode != "Ok":
|
|
31
|
-
raise AuthorizenetControllerExecutionError(
|
|
32
|
-
message=response.messages.message[0]["text"].text,
|
|
33
|
-
code=response.messages.message[0]["code"].text,
|
|
34
|
-
)
|
|
35
|
-
return response
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class AuthorizenetControllerExecutionError(Exception):
|
|
39
|
-
"""Raised when an Authorizenet API controller fails to execute."""
|
|
40
|
-
|
|
41
|
-
def __init__(self, message: str, code: str, *args, **kwargs) -> None:
|
|
42
|
-
super().__init__(message, *args, **kwargs)
|
|
43
|
-
self._message = message
|
|
44
|
-
self._code = code
|
|
45
|
-
|
|
46
|
-
def __str__(self) -> str:
|
|
47
|
-
return f"{self.code}: {self.message}"
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def message(self) -> str:
|
|
51
|
-
"""An Authorizenet API error message."""
|
|
52
|
-
return self._message
|
|
53
|
-
|
|
54
|
-
@property
|
|
55
|
-
def code(self) -> str:
|
|
56
|
-
"""An Authorizenet API error code."""
|
|
57
|
-
return self._code
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
from functools import cached_property
|
|
2
|
-
from typing import Callable
|
|
3
|
-
|
|
4
|
-
from authorizenet.apicontractsv1 import merchantAuthenticationType
|
|
5
|
-
from django.conf import settings
|
|
6
|
-
from django.core.exceptions import ImproperlyConfigured
|
|
7
|
-
from lxml.objectify import ObjectifiedElement
|
|
8
|
-
|
|
9
|
-
from .auth import get_environment, get_merchant_auth, get_validation_mode
|
|
10
|
-
from .controllers import (
|
|
11
|
-
AuthorizenetControllerExecutionError,
|
|
12
|
-
execute_controller,
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class AuthorizenetService:
|
|
17
|
-
"""A service that safely interacts with the Authorizenet API."""
|
|
18
|
-
|
|
19
|
-
REQUIRED_SETTINGS = (
|
|
20
|
-
"MERCHANT_AUTH_ENVIRONMENT",
|
|
21
|
-
"MERCHANT_AUTH_LOGIN_ID",
|
|
22
|
-
"MERCHANT_AUTH_TRANSACTION_KEY",
|
|
23
|
-
"MERCHANT_AUTH_VALIDATION_MODE",
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
def __init__(self) -> None:
|
|
27
|
-
"""Raises :py:exc:`~django.core.exceptions.ImproperlyConfigured` if required settings weren't set."""
|
|
28
|
-
for setting in self.REQUIRED_SETTINGS:
|
|
29
|
-
if not hasattr(settings, setting):
|
|
30
|
-
raise ImproperlyConfigured(f"'{setting}' setting is required.")
|
|
31
|
-
|
|
32
|
-
def request(self, func: Callable, *args, **kwargs) -> ObjectifiedElement:
|
|
33
|
-
"""
|
|
34
|
-
Calls the Authorizenet API function with arguments and returns the result.
|
|
35
|
-
|
|
36
|
-
:param func: An Authorizenet API function.
|
|
37
|
-
:type func: ~typing.Callable
|
|
38
|
-
:param args: Positional arguments for the API call.
|
|
39
|
-
:param kwargs: Keyword arguments for the API call.
|
|
40
|
-
:raises ValueError: If any function arguments were invalid.
|
|
41
|
-
:raises ~terminusgps.authorizenet.controllers.AuthorizenetControllerExecutionError: If the API call failed.
|
|
42
|
-
:returns: The Authorizenet API call response.
|
|
43
|
-
:rtype: ~lxml.objectify.ObjectifiedElement
|
|
44
|
-
|
|
45
|
-
"""
|
|
46
|
-
try:
|
|
47
|
-
request, controller_cls = func(*args, **kwargs)
|
|
48
|
-
request.merchantAuthentication = self.merchantAuthentication
|
|
49
|
-
controller = controller_cls(request)
|
|
50
|
-
return execute_controller(controller, self.environment)
|
|
51
|
-
except AuthorizenetControllerExecutionError | ValueError:
|
|
52
|
-
raise
|
|
53
|
-
|
|
54
|
-
@cached_property
|
|
55
|
-
def merchantAuthentication(self) -> merchantAuthenticationType:
|
|
56
|
-
"""Merchant authentication element for Authorizenet API requests."""
|
|
57
|
-
return get_merchant_auth()
|
|
58
|
-
|
|
59
|
-
@cached_property
|
|
60
|
-
def environment(self) -> str:
|
|
61
|
-
"""Environment for Authorizenet API requests."""
|
|
62
|
-
return get_environment()
|
|
63
|
-
|
|
64
|
-
@cached_property
|
|
65
|
-
def validationMode(self) -> str:
|
|
66
|
-
"""Validation mode for Authorizenet API requests."""
|
|
67
|
-
return get_validation_mode()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/__init__.py
RENAMED
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/authorizenet/api/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/resource.py
RENAMED
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/retranslator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_terminusgps-45.6.0 → python_terminusgps-45.7.0}/terminusgps/wialon/items/unit_group.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|