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.
Files changed (21) hide show
  1. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/PKG-INFO +1 -1
  2. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/APIClient.py +32 -11
  3. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/PKG-INFO +1 -1
  4. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/pyproject.toml +1 -1
  5. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/setup.py +1 -1
  6. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestAPIClient.py +13 -0
  7. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/LICENSE +0 -0
  8. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/README.md +0 -0
  9. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/APIError.py +0 -0
  10. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Account.py +0 -0
  11. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Invoice.py +0 -0
  12. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/Mail.py +0 -0
  13. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api/__init__.py +0 -0
  14. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/SOURCES.txt +0 -0
  15. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/dependency_links.txt +0 -0
  16. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/mailbox_org_api.egg-info/top_level.txt +0 -0
  17. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/setup.cfg +0 -0
  18. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestAccount.py +0 -0
  19. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestInvoice.py +0 -0
  20. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/TestMail.py +0 -0
  21. {mailbox_org_api-2.0 → mailbox_org_api-2.1}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mailbox-org-api
3
- Version: 2.0
3
+ Version: 2.1
4
4
  Summary: A library to access the mailbox.org Business API.
5
5
  Author: Hendrik Schlange
6
6
  Author-email: Hendrik Schlange <mail@heshsum.de>
@@ -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 = requests.post(
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
- del headers["HPLS-AUTH"]
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) > 1 >= params.get('page', 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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mailbox-org-api
3
- Version: 2.0
3
+ Version: 2.1
4
4
  Summary: A library to access the mailbox.org Business API.
5
5
  Author: Hendrik Schlange
6
6
  Author-email: Hendrik Schlange <mail@heshsum.de>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mailbox-org-api"
3
- version = "2.0"
3
+ version = "2.1"
4
4
  authors = [
5
5
  { name="Hendrik Schlange", email="mail@heshsum.de" },
6
6
  ]
@@ -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.0',
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