mailbox-org-api 2.0__tar.gz → 2.1__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.
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/PKG-INFO +1 -1
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/APIClient.py +32 -11
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/PKG-INFO +1 -1
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/pyproject.toml +1 -1
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/setup.py +1 -1
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestAPIClient.py +13 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/LICENSE +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/README.md +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/APIError.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Account.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Invoice.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Mail.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/__init__.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/SOURCES.txt +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/dependency_links.txt +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/top_level.txt +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/setup.cfg +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestAccount.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestInvoice.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestMail.py +0 -0
- {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/__init__.py +0 -0
|
@@ -3,9 +3,10 @@ Module for the mailbox Business API client
|
|
|
3
3
|
"""
|
|
4
4
|
import json
|
|
5
5
|
import requests
|
|
6
|
+
from requests.adapters import HTTPAdapter
|
|
7
|
+
from urllib3.util.retry import Retry
|
|
8
|
+
from requests.exceptions import RequestException
|
|
6
9
|
import typing_extensions
|
|
7
|
-
from requests import RequestException
|
|
8
|
-
|
|
9
10
|
from mailbox_org_api.APIError import APIError
|
|
10
11
|
from mailbox_org_api.Account import Account
|
|
11
12
|
from mailbox_org_api.Mail import Mail
|
|
@@ -19,8 +20,7 @@ class APIClient:
|
|
|
19
20
|
"""
|
|
20
21
|
Object for API Client
|
|
21
22
|
"""
|
|
22
|
-
|
|
23
|
-
def __init__(self, debug_output=False):
|
|
23
|
+
def __init__(self, debug_output=False, max_retries=5):
|
|
24
24
|
# URL of the API
|
|
25
25
|
self.url = "https://api.mailbox.org/v1/"
|
|
26
26
|
|
|
@@ -35,6 +35,27 @@ class APIClient:
|
|
|
35
35
|
|
|
36
36
|
self.debug_output = debug_output
|
|
37
37
|
|
|
38
|
+
# Initialize the session
|
|
39
|
+
self.session = requests.Session()
|
|
40
|
+
|
|
41
|
+
# Set default headers for the session
|
|
42
|
+
self.session.headers.update({
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
# Retry strategy
|
|
47
|
+
retry_strategy = Retry(
|
|
48
|
+
total=max_retries,
|
|
49
|
+
backoff_factor=0.5,
|
|
50
|
+
# Retry on these specific HTTP status codes
|
|
51
|
+
status_forcelist=[429, 500, 502, 503, 504],
|
|
52
|
+
# Allow retries for POST requests
|
|
53
|
+
allowed_methods=["HEAD", "GET", "OPTIONS", "POST"]
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
adapter = HTTPAdapter(max_retries=retry_strategy)
|
|
57
|
+
self.session.mount('https://', adapter)
|
|
58
|
+
|
|
38
59
|
# Increment the request ID
|
|
39
60
|
def get_jsonrpc_id(self):
|
|
40
61
|
"""Method to create the JSON RPC request ID. """
|
|
@@ -73,8 +94,7 @@ class APIClient:
|
|
|
73
94
|
# Print the clean version of the request
|
|
74
95
|
print('API full request:\t', print_request)
|
|
75
96
|
|
|
76
|
-
api_response =
|
|
77
|
-
self.url, data=json.dumps(request), headers=headers)
|
|
97
|
+
api_response = self.session.post(self.url, data=json.dumps(request))
|
|
78
98
|
try:
|
|
79
99
|
api_response = api_response.json()
|
|
80
100
|
except RequestException as error:
|
|
@@ -115,7 +135,7 @@ class APIClient:
|
|
|
115
135
|
self.auth_id = str(api_response["session"])
|
|
116
136
|
print('Auth ID:', self.auth_id)
|
|
117
137
|
# The auth-header is added to the list of headers, as it has to be provided with each call
|
|
118
|
-
headers.update({"HPLS-AUTH": self.auth_id})
|
|
138
|
+
self.session.headers.update({"HPLS-AUTH": self.auth_id})
|
|
119
139
|
return api_response
|
|
120
140
|
|
|
121
141
|
def deauth(self) -> dict:
|
|
@@ -126,8 +146,9 @@ class APIClient:
|
|
|
126
146
|
api_response = self.api_request('deauth',{})
|
|
127
147
|
if api_response:
|
|
128
148
|
# The auth header is stripped
|
|
129
|
-
|
|
149
|
+
self.session.headers.pop("HPLS-AUTH")
|
|
130
150
|
self.auth_id = None
|
|
151
|
+
self.session.close()
|
|
131
152
|
return api_response
|
|
132
153
|
|
|
133
154
|
def hello_world(self):
|
|
@@ -431,7 +452,7 @@ class APIClient:
|
|
|
431
452
|
"""
|
|
432
453
|
return self.api_request('domain.validate.spf', {'domain':domain})
|
|
433
454
|
|
|
434
|
-
def mail_list(self, domain, details: bool = False, page_size: int = None, page: int = None, sort_field: str = None,
|
|
455
|
+
def mail_list(self, domain: str, details: bool = False, page_size: int = None, page: int = None, sort_field: str = None,
|
|
435
456
|
sort_order: str = None) -> dict:
|
|
436
457
|
"""
|
|
437
458
|
Function to list all mailboxes
|
|
@@ -454,8 +475,8 @@ class APIClient:
|
|
|
454
475
|
|
|
455
476
|
# Check values (without triggering a KeyError)
|
|
456
477
|
# Logic: If page_size exists and is > 1, ensure page is also > 1
|
|
457
|
-
if params.get('page_size', 0)
|
|
458
|
-
raise ValueError(f'''If 'page_size' is used, 'page' must be specified''')
|
|
478
|
+
if params.get('page_size', 0) >= 1 > params.get('page', 0):
|
|
479
|
+
raise ValueError(f'''If 'page_size' is used, a 'page' >0 must be specified''')
|
|
459
480
|
|
|
460
481
|
# 3. Use walrus operator to assign a value to a variable, but only if it exists
|
|
461
482
|
if (field := params.get('sort_field')) and field not in mail_list_sort_field:
|
|
@@ -3,7 +3,7 @@ from setuptools import find_packages, setup
|
|
|
3
3
|
setup(
|
|
4
4
|
name='mailbox_org_api',
|
|
5
5
|
packages=find_packages(),
|
|
6
|
-
version='2.
|
|
6
|
+
version='2.1',
|
|
7
7
|
description='A library to access the mailbox.org Business API',
|
|
8
8
|
author='Hendrik Schlange',
|
|
9
9
|
install_requires=['requests'],
|
|
@@ -63,6 +63,14 @@ class TestAPIClient:
|
|
|
63
63
|
assert api.jsonrpc_id == 1
|
|
64
64
|
api.deauth()
|
|
65
65
|
|
|
66
|
+
def test_deauth(self):
|
|
67
|
+
api = APIClient.APIClient()
|
|
68
|
+
assert api.session.headers.get('HPLS-AUTH') is None
|
|
69
|
+
api.auth(api_test_user, api_test_pass)
|
|
70
|
+
assert api.session.headers.get('HPLS-AUTH') is not None
|
|
71
|
+
api.deauth()
|
|
72
|
+
assert api.session.headers.get('HPLS-AUTH') is None
|
|
73
|
+
|
|
66
74
|
def test_account_get(self):
|
|
67
75
|
api = APIClient.APIClient()
|
|
68
76
|
api.auth(api_test_user, api_test_pass)
|
|
@@ -226,6 +234,11 @@ class TestAPIClient:
|
|
|
226
234
|
['MAIL_BLACKLIST', 'MAIL_SPAMPROTECTION', 'MAIL_PASSWORDRESET_SMS', 'MAIL_BACKUPRECOVER'])
|
|
227
235
|
assert mails[0]['plan'] in ['premium', 'standard', 'light']
|
|
228
236
|
assert mails[0]['creation_date'] is not None
|
|
237
|
+
paginated_mails = api.mail_list(domain, page_size=50, page=1)
|
|
238
|
+
assert paginated_mails is not None
|
|
239
|
+
assert paginated_mails['totalHits'] is not None
|
|
240
|
+
assert paginated_mails['totalPages'] is not None
|
|
241
|
+
assert paginated_mails['results'] is not None
|
|
229
242
|
with pytest.raises(APIError):
|
|
230
243
|
api.mail_list(domain, page = 2)
|
|
231
244
|
with pytest.raises(APIError):
|
|
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
|