mailbox-org-api 2.3__tar.gz → 2.4__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.3 → mailbox_org_api-2.4}/PKG-INFO +14 -8
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/README.md +13 -7
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/APIClient.py +152 -133
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/APIError.py +2 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/Invoice.py +1 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api.egg-info/PKG-INFO +14 -8
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/pyproject.toml +1 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/setup.py +1 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/tests/TestAPIClient.py +39 -11
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/tests/TestAccount.py +3 -2
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/tests/TestInvoice.py +2 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/tests/TestMail.py +3 -1
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/LICENSE +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/Account.py +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/Mail.py +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api/__init__.py +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api.egg-info/SOURCES.txt +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api.egg-info/dependency_links.txt +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/mailbox_org_api.egg-info/top_level.txt +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/setup.cfg +0 -0
- {mailbox_org_api-2.3 → mailbox_org_api-2.4}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mailbox-org-api
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4
|
|
4
4
|
Summary: A library to access the mailbox Business API.
|
|
5
5
|
Author: Hendrik Schlange
|
|
6
6
|
Author-email: Hendrik Schlange <mail@heshsum.de>
|
|
@@ -36,11 +36,15 @@ pip install mailbox-org-api
|
|
|
36
36
|
pip install git+https://github.com/heshsum/mailbox-org-api
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
## Usage
|
|
39
|
+
## Usage and documentation
|
|
40
40
|
Basic usage is fairly straightforward. The naming scheme of the functions is similar to the naming at mailbox.org,
|
|
41
|
-
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
41
|
+
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
42
|
+
|
|
43
|
+
Therefore, the functions mirror the functions as provided and documented at mailbox:
|
|
44
|
+
[api.mailbox.org](https://api.mailbox.org)
|
|
45
|
+
|
|
42
46
|
Additionally, some helper functions for common or more complicated tasks are included to make life a bit easier,
|
|
43
|
-
e.g. for changing plans, password and to
|
|
47
|
+
e.g. for changing plans, password and to retrieving invoices.
|
|
44
48
|
|
|
45
49
|
```python
|
|
46
50
|
from mailbox_org_api import APIClient
|
|
@@ -87,6 +91,8 @@ api.mail_set_forwards('foo@bar.com', ['forward1@bar.com', 'forward2@bar.com'])
|
|
|
87
91
|
api.deauth()
|
|
88
92
|
```
|
|
89
93
|
|
|
94
|
+
More information can be found in the [Wiki](https://github.com/heshsum/mailbox-org-api/wiki)
|
|
95
|
+
|
|
90
96
|
## Common tasks
|
|
91
97
|
mailbox_org_api includes a number of helper functions to make common tasks simpler. These include:
|
|
92
98
|
|
|
@@ -163,21 +169,21 @@ Usage:
|
|
|
163
169
|
api.account_invoice_get_token('BMBO-1234-24')
|
|
164
170
|
```
|
|
165
171
|
|
|
166
|
-
###
|
|
172
|
+
### account_invoice_get_file
|
|
167
173
|
Invoices are provided as Based64 encoded gz Strings. This function
|
|
168
174
|
1. takes the invoice ID
|
|
169
175
|
2. retrieves the token for the invoice
|
|
170
176
|
3. gets the binary data
|
|
171
177
|
4. decodes the Base64
|
|
172
178
|
5. decompresses it
|
|
173
|
-
6. returns the bytes of the actual
|
|
179
|
+
6. returns the bytes of the actual invoice file
|
|
174
180
|
|
|
175
181
|
Usage
|
|
176
182
|
```python
|
|
177
183
|
invoice_id = 'BMBO-1234-24'
|
|
178
|
-
account_name = '
|
|
184
|
+
account_name = 'foo'
|
|
179
185
|
with open(invoice_id + '.pdf', 'w') as file:
|
|
180
|
-
file.write(api.
|
|
186
|
+
file.write(api.account_invoice_get_file(account_name, invoice_id, 'PDF'))
|
|
181
187
|
```
|
|
182
188
|
|
|
183
189
|
## Here be dragons
|
|
@@ -19,11 +19,15 @@ pip install mailbox-org-api
|
|
|
19
19
|
pip install git+https://github.com/heshsum/mailbox-org-api
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
## Usage
|
|
22
|
+
## Usage and documentation
|
|
23
23
|
Basic usage is fairly straightforward. The naming scheme of the functions is similar to the naming at mailbox.org,
|
|
24
|
-
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
24
|
+
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
25
|
+
|
|
26
|
+
Therefore, the functions mirror the functions as provided and documented at mailbox:
|
|
27
|
+
[api.mailbox.org](https://api.mailbox.org)
|
|
28
|
+
|
|
25
29
|
Additionally, some helper functions for common or more complicated tasks are included to make life a bit easier,
|
|
26
|
-
e.g. for changing plans, password and to
|
|
30
|
+
e.g. for changing plans, password and to retrieving invoices.
|
|
27
31
|
|
|
28
32
|
```python
|
|
29
33
|
from mailbox_org_api import APIClient
|
|
@@ -70,6 +74,8 @@ api.mail_set_forwards('foo@bar.com', ['forward1@bar.com', 'forward2@bar.com'])
|
|
|
70
74
|
api.deauth()
|
|
71
75
|
```
|
|
72
76
|
|
|
77
|
+
More information can be found in the [Wiki](https://github.com/heshsum/mailbox-org-api/wiki)
|
|
78
|
+
|
|
73
79
|
## Common tasks
|
|
74
80
|
mailbox_org_api includes a number of helper functions to make common tasks simpler. These include:
|
|
75
81
|
|
|
@@ -146,21 +152,21 @@ Usage:
|
|
|
146
152
|
api.account_invoice_get_token('BMBO-1234-24')
|
|
147
153
|
```
|
|
148
154
|
|
|
149
|
-
###
|
|
155
|
+
### account_invoice_get_file
|
|
150
156
|
Invoices are provided as Based64 encoded gz Strings. This function
|
|
151
157
|
1. takes the invoice ID
|
|
152
158
|
2. retrieves the token for the invoice
|
|
153
159
|
3. gets the binary data
|
|
154
160
|
4. decodes the Base64
|
|
155
161
|
5. decompresses it
|
|
156
|
-
6. returns the bytes of the actual
|
|
162
|
+
6. returns the bytes of the actual invoice file
|
|
157
163
|
|
|
158
164
|
Usage
|
|
159
165
|
```python
|
|
160
166
|
invoice_id = 'BMBO-1234-24'
|
|
161
|
-
account_name = '
|
|
167
|
+
account_name = 'foo'
|
|
162
168
|
with open(invoice_id + '.pdf', 'w') as file:
|
|
163
|
-
file.write(api.
|
|
169
|
+
file.write(api.account_invoice_get_file(account_name, invoice_id, 'PDF'))
|
|
164
170
|
```
|
|
165
171
|
|
|
166
172
|
## Here be dragons
|
|
@@ -5,7 +5,6 @@ import json
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
7
|
import requests
|
|
8
|
-
import typing_extensions
|
|
9
8
|
from requests.adapters import HTTPAdapter
|
|
10
9
|
from requests.exceptions import RequestException
|
|
11
10
|
from urllib3.util.retry import Retry
|
|
@@ -19,10 +18,12 @@ headers = {'content-type': 'application/json'}
|
|
|
19
18
|
|
|
20
19
|
keys_to_string = ['additional_cloud_quota', 'additional_mail_quota']
|
|
21
20
|
|
|
21
|
+
|
|
22
22
|
class APIClient:
|
|
23
23
|
"""
|
|
24
24
|
Object for API Client
|
|
25
25
|
"""
|
|
26
|
+
|
|
26
27
|
def __init__(self, debug_output=False, max_retries=5):
|
|
27
28
|
# URL of the API
|
|
28
29
|
self.url = "https://api.mailbox.org/v1/"
|
|
@@ -128,7 +129,7 @@ class APIClient:
|
|
|
128
129
|
:param password: the password
|
|
129
130
|
:return: the API response for the request
|
|
130
131
|
"""
|
|
131
|
-
api_response = self.api_request('auth', {'user':username, 'pass':password})
|
|
132
|
+
api_response = self.api_request('auth', {'user': username, 'pass': password})
|
|
132
133
|
if api_response['session']:
|
|
133
134
|
# Level gives information about the calls available
|
|
134
135
|
self.level = api_response["level"]
|
|
@@ -146,7 +147,7 @@ class APIClient:
|
|
|
146
147
|
Function to close the current API session
|
|
147
148
|
:return: True if the API session is closed, False otherwise
|
|
148
149
|
"""
|
|
149
|
-
api_response = self.api_request('deauth',{})
|
|
150
|
+
api_response = self.api_request('deauth', {})
|
|
150
151
|
if api_response:
|
|
151
152
|
# The auth header is stripped
|
|
152
153
|
self.session.headers.pop("HPLS-AUTH")
|
|
@@ -159,7 +160,7 @@ class APIClient:
|
|
|
159
160
|
Function for hello world, just to test the connection
|
|
160
161
|
:return: The response from the mailbox.org Business API
|
|
161
162
|
"""
|
|
162
|
-
return self.api_request('hello.world',{})
|
|
163
|
+
return self.api_request('hello.world', {})
|
|
163
164
|
|
|
164
165
|
def hello_innerworld(self):
|
|
165
166
|
"""
|
|
@@ -213,9 +214,9 @@ class APIClient:
|
|
|
213
214
|
:param account: the account name to get
|
|
214
215
|
:return: the response from the mailbox.org Business API
|
|
215
216
|
"""
|
|
216
|
-
return self.api_request('account.get', {'account':account})
|
|
217
|
+
return self.api_request('account.get', {'account': account})
|
|
217
218
|
|
|
218
|
-
def account_get_object(self, account:str) -> Account:
|
|
219
|
+
def account_get_object(self, account: str) -> Account:
|
|
219
220
|
result = self.api_request('account.get', {'account': account})
|
|
220
221
|
account_object = Account(account)
|
|
221
222
|
for k, v in result.items():
|
|
@@ -259,7 +260,7 @@ class APIClient:
|
|
|
259
260
|
:param account: the account name to delete
|
|
260
261
|
:return: the response from the mailbox.org Business API
|
|
261
262
|
"""
|
|
262
|
-
return self.api_request('account.del', {'account':account})
|
|
263
|
+
return self.api_request('account.del', {'account': account})
|
|
263
264
|
|
|
264
265
|
def account_invoice_list(self, account: str) -> dict:
|
|
265
266
|
"""
|
|
@@ -267,7 +268,7 @@ class APIClient:
|
|
|
267
268
|
:param account: the account name to list
|
|
268
269
|
:return: the response from the mailbox.org Business API
|
|
269
270
|
"""
|
|
270
|
-
return self.api_request('account.invoice.list', {'account':account})
|
|
271
|
+
return self.api_request('account.invoice.list', {'account': account})
|
|
271
272
|
|
|
272
273
|
def account_invoice_get(self, account: str, token: str) -> dict:
|
|
273
274
|
"""
|
|
@@ -276,7 +277,7 @@ class APIClient:
|
|
|
276
277
|
:param token: the token for the invoice
|
|
277
278
|
:return: the response from the mailbox.org Business API - the invoice as a Base64 encoded gzipped string
|
|
278
279
|
"""
|
|
279
|
-
return self.api_request('account.invoice.get', {'account':account, 'token':token})
|
|
280
|
+
return self.api_request('account.invoice.get', {'account': account, 'token': token})
|
|
280
281
|
|
|
281
282
|
def account_invoice_get_object(self, account: str, invoice_id: str) -> Invoice:
|
|
282
283
|
"""
|
|
@@ -303,7 +304,7 @@ class APIClient:
|
|
|
303
304
|
"""
|
|
304
305
|
Function to get a list of all invoice ids for a specific account
|
|
305
306
|
"""
|
|
306
|
-
response = self.api_request('account.invoice.list', {'account':account})
|
|
307
|
+
response = self.api_request('account.invoice.list', {'account': account})
|
|
307
308
|
invoices = []
|
|
308
309
|
|
|
309
310
|
for invoice in response:
|
|
@@ -316,7 +317,7 @@ class APIClient:
|
|
|
316
317
|
"""
|
|
317
318
|
invoices = self.account_invoice_list(account)
|
|
318
319
|
open_invoices = []
|
|
319
|
-
|
|
320
|
+
|
|
320
321
|
for i in invoices:
|
|
321
322
|
if i['status'] == 'open':
|
|
322
323
|
open_invoices.append(i)
|
|
@@ -335,22 +336,12 @@ class APIClient:
|
|
|
335
336
|
return invoice['token']
|
|
336
337
|
raise ValueError('Invoice not found')
|
|
337
338
|
|
|
338
|
-
@typing_extensions.deprecated('Use account_invoice_get_file instead')
|
|
339
|
-
def account_invoice_get_pdf(self, account: str, invoice_id: str) -> bytes:
|
|
340
|
-
"""
|
|
341
|
-
Function to get a specific invoice as a PDf-file
|
|
342
|
-
:param account: the account name
|
|
343
|
-
:param invoice_id: the invoice ID
|
|
344
|
-
:return: the PDF as bytes
|
|
345
|
-
"""
|
|
346
|
-
return self.account_invoice_get_file(account, invoice_id, 'pdf')
|
|
347
|
-
|
|
348
339
|
def account_invoice_get_file(self, account: str, invoice_id: str, file_type: str) -> bytes:
|
|
349
340
|
"""
|
|
350
341
|
Function to get a specific invoice as a PDf-file
|
|
351
342
|
:param account: the account name
|
|
352
343
|
:param invoice_id: the invoice ID
|
|
353
|
-
:param file_type: The file type to return. Valid:
|
|
344
|
+
:param file_type: The file type to return. Valid: CSV, PDF and XML
|
|
354
345
|
:return: the file as bytes
|
|
355
346
|
"""
|
|
356
347
|
if file_type not in ('csv', 'pdf', 'xml'):
|
|
@@ -368,17 +359,30 @@ class APIClient:
|
|
|
368
359
|
# Take the Base64 encoded data (response['bin']), decode the Base 64, decompress the gz and return the bytes
|
|
369
360
|
return zlib.decompress(base64.b64decode(response['bin']))
|
|
370
361
|
|
|
371
|
-
def domain_list(self, account:str, search_filter:str | None = None) -> dict:
|
|
362
|
+
def domain_list(self, account: str, search_filter: str | None = None) -> dict:
|
|
372
363
|
"""
|
|
373
364
|
Function to list all domains
|
|
374
365
|
:param account: the account to list domains for
|
|
375
366
|
:param search_filter: String for optional search filter
|
|
376
367
|
:return: the API response
|
|
377
368
|
"""
|
|
378
|
-
params = {'account':account}
|
|
369
|
+
params = {'account': account}
|
|
379
370
|
if isinstance(search_filter, str):
|
|
380
|
-
params.update({'filter':str(search_filter)})
|
|
381
|
-
return self.api_request('domain.list',params)
|
|
371
|
+
params.update({'filter': str(search_filter)})
|
|
372
|
+
return self.api_request('domain.list', params)
|
|
373
|
+
|
|
374
|
+
def domain_get_list(self, account: str, search_filter: str | None = None) -> list:
|
|
375
|
+
"""
|
|
376
|
+
Function to get a List object with domain names for a given account
|
|
377
|
+
:param account: the account to list domains for
|
|
378
|
+
:param search_filter: String for optional search filter
|
|
379
|
+
:return: a List object containing the domain names
|
|
380
|
+
"""
|
|
381
|
+
result = self.domain_list(account, search_filter)
|
|
382
|
+
domains = []
|
|
383
|
+
for i in result:
|
|
384
|
+
domains.append(i['domain'])
|
|
385
|
+
return domains
|
|
382
386
|
|
|
383
387
|
def domain_add(self, account: str, domain: str, password: str, **kwargs) -> dict:
|
|
384
388
|
"""
|
|
@@ -390,7 +394,7 @@ class APIClient:
|
|
|
390
394
|
See documentation here: https://api.mailbox.org/v1/doc/methods/index.html#domain-add
|
|
391
395
|
:return: the API response
|
|
392
396
|
"""
|
|
393
|
-
params = {'account':account, 'domain':domain, 'password':password}
|
|
397
|
+
params = {'account': account, 'domain': domain, 'password': password}
|
|
394
398
|
params.update({k: v for k, v in kwargs.items() if v is not None})
|
|
395
399
|
return self.api_request('domain.add', params)
|
|
396
400
|
|
|
@@ -400,7 +404,7 @@ class APIClient:
|
|
|
400
404
|
:param domain: the domain to get
|
|
401
405
|
:return: the API response
|
|
402
406
|
"""
|
|
403
|
-
return self.api_request('domain.get',{'domain':domain})
|
|
407
|
+
return self.api_request('domain.get', {'domain': domain})
|
|
404
408
|
|
|
405
409
|
def domain_capabilities_set(self, domain: str, capabilities: list) -> dict:
|
|
406
410
|
"""
|
|
@@ -445,7 +449,7 @@ class APIClient:
|
|
|
445
449
|
:param domain: the domain to delete
|
|
446
450
|
:return: the API response
|
|
447
451
|
"""
|
|
448
|
-
return self.api_request('domain.del', {'account':account, 'domain':domain})
|
|
452
|
+
return self.api_request('domain.del', {'account': account, 'domain': domain})
|
|
449
453
|
|
|
450
454
|
def domain_validate_spf(self, domain: str) -> dict:
|
|
451
455
|
"""
|
|
@@ -453,9 +457,9 @@ class APIClient:
|
|
|
453
457
|
:param domain: the domain to validate
|
|
454
458
|
:return: the API response - information about the SPF config
|
|
455
459
|
"""
|
|
456
|
-
return self.api_request('domain.validate.spf', {'domain':domain})
|
|
460
|
+
return self.api_request('domain.validate.spf', {'domain': domain})
|
|
457
461
|
|
|
458
|
-
def mail_list(self, domain: str, details: bool = False, page_size: int
|
|
462
|
+
def mail_list(self, domain: str, details: bool = False, page_size: int | None = None, page: int | None = None,
|
|
459
463
|
sort_field: str | None = None, sort_order: str | None = None) -> dict:
|
|
460
464
|
"""
|
|
461
465
|
Function to list all mailboxes
|
|
@@ -467,8 +471,8 @@ class APIClient:
|
|
|
467
471
|
:param sort_order: the order to sort by. Possible values: 'asc', 'desc'
|
|
468
472
|
:return: the response from the mailbox.org Business API
|
|
469
473
|
"""
|
|
470
|
-
args = {'domain':domain, 'details':details, 'page_size':page_size, 'page':page, 'sort_field':sort_field,
|
|
471
|
-
|
|
474
|
+
args = {'domain': domain, 'details': details, 'page_size': page_size, 'page': page, 'sort_field': sort_field,
|
|
475
|
+
'sort_order': sort_order}
|
|
472
476
|
|
|
473
477
|
# Allowed sort fields as documented here: https://api.mailbox.org/v1/doc/methods/index.html#mail-list
|
|
474
478
|
mail_list_sort_field = ['mail', 'first_name', 'last_name', 'status', 'domain', 'plan', 'type', 'creation_date']
|
|
@@ -490,8 +494,20 @@ class APIClient:
|
|
|
490
494
|
|
|
491
495
|
return self.api_request('mail.list', params)
|
|
492
496
|
|
|
493
|
-
def
|
|
494
|
-
|
|
497
|
+
def mail_get_list(self, domain: str) -> list:
|
|
498
|
+
"""
|
|
499
|
+
Function to get a list of all mailboxes of a domain as a List object.
|
|
500
|
+
:param domain: the domain to list all mailboxes for.
|
|
501
|
+
:return: a List object containing all mail addresses of the given domain.
|
|
502
|
+
"""
|
|
503
|
+
result = self.mail_list(domain)
|
|
504
|
+
mails = []
|
|
505
|
+
for i in result:
|
|
506
|
+
mails.append(i['mail'])
|
|
507
|
+
return mails
|
|
508
|
+
|
|
509
|
+
def mail_add(self, mail: str, password: str, plan: str, first_name: str, last_name: str, inboxsave: bool = True,
|
|
510
|
+
forwards: list | None = None, **kwargs) -> dict:
|
|
495
511
|
"""
|
|
496
512
|
Function to add a mail
|
|
497
513
|
:param mail: the mail to add
|
|
@@ -510,10 +526,10 @@ class APIClient:
|
|
|
510
526
|
'create_own_context': bool, 'title': str, 'birthday': str, 'position': str,
|
|
511
527
|
'department': str, 'company': str, 'street': str, 'postal_code': str, 'city': str,
|
|
512
528
|
'phone': str, 'fax': str, 'cell_phone': str, 'recover': bool, 'skip_welcome_mail': bool,
|
|
513
|
-
'uid_extern': str, 'language': str, 'evac_force_activation':bool}
|
|
529
|
+
'uid_extern': str, 'language': str, 'evac_force_activation': bool}
|
|
514
530
|
|
|
515
531
|
if password and 'password_hash' in kwargs:
|
|
516
|
-
|
|
532
|
+
raise KeyError('''Simultaneous usage of 'password' and 'password_hash' not allowed.
|
|
517
533
|
Use 'password' = None if password_hash is used.''')
|
|
518
534
|
|
|
519
535
|
if forwards is None:
|
|
@@ -526,8 +542,8 @@ class APIClient:
|
|
|
526
542
|
kwargs[k] = str(kwargs[k])
|
|
527
543
|
|
|
528
544
|
# After validation, build parameter list from mail and kwargs
|
|
529
|
-
params = {'mail':mail, 'password':password, 'plan':plan, 'first_name':first_name, 'last_name':last_name,
|
|
530
|
-
'inboxsave':inboxsave, 'forwards':forwards}
|
|
545
|
+
params = {'mail': mail, 'password': password, 'plan': plan, 'first_name': first_name, 'last_name': last_name,
|
|
546
|
+
'inboxsave': inboxsave, 'forwards': forwards}
|
|
531
547
|
params.update({k: v for k, v in kwargs.items() if v is not None})
|
|
532
548
|
return self.api_request('mail.add', params)
|
|
533
549
|
|
|
@@ -538,10 +554,10 @@ class APIClient:
|
|
|
538
554
|
:param include_quota_usage: True if the quota usage should be included in the request
|
|
539
555
|
:return the response for the request
|
|
540
556
|
"""
|
|
541
|
-
return self.api_request('mail.get', {'mail':mail, 'include_quota_usage':include_quota_usage})
|
|
557
|
+
return self.api_request('mail.get', {'mail': mail, 'include_quota_usage': include_quota_usage})
|
|
542
558
|
|
|
543
|
-
def mail_get_object(self, mail:str) -> Mail:
|
|
544
|
-
result = self.api_request('mail.get', {'mail':mail, 'include_quota_usage':False})
|
|
559
|
+
def mail_get_object(self, mail: str) -> Mail:
|
|
560
|
+
result = self.api_request('mail.get', {'mail': mail, 'include_quota_usage': False})
|
|
545
561
|
mail_object = Mail(mail)
|
|
546
562
|
for k, v in result.items():
|
|
547
563
|
if v is not None:
|
|
@@ -558,15 +574,15 @@ class APIClient:
|
|
|
558
574
|
"""
|
|
559
575
|
# Allowed attributes as documented here: https://api.mailbox.org/v1/doc/methods/index.html#mail-set
|
|
560
576
|
allowed_parameters = {'password': str, 'password_hash': str, 'same_password_allowed': bool,
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
577
|
+
'require_reset_password': bool, 'plan': str, 'additional_mail_quota': int,
|
|
578
|
+
'additional_cloud_quota': int, 'first_name': str, 'last_name': str, 'inboxsave': bool,
|
|
579
|
+
'forwards': list, 'aliases': list, 'alternate_mail': str, 'memo': str, 'allow_nets': str,
|
|
580
|
+
'active': bool, 'title': str, 'birthday': str, 'position': str, 'department': str,
|
|
581
|
+
'company': str, 'street': str, 'postal_code': str, 'city': str, 'phone': str, 'fax': str,
|
|
582
|
+
'cell_phone': str, 'uid_extern': str, 'language': str, 'deletion_date': str}
|
|
567
583
|
|
|
568
584
|
if 'password' in kwargs and 'password_hash' in kwargs:
|
|
569
|
-
|
|
585
|
+
raise KeyError('''Simultaneous usage of 'password' and 'password_hash' not allowed.''')
|
|
570
586
|
|
|
571
587
|
if 'additional_mail_quota' in kwargs or 'additional_cloud_quota' in kwargs and 'plan' not in kwargs:
|
|
572
588
|
raise KeyError('''If setting additional quota, 'plan' must be given.''')
|
|
@@ -581,9 +597,9 @@ class APIClient:
|
|
|
581
597
|
kwargs[k] = str(kwargs[k])
|
|
582
598
|
|
|
583
599
|
# After validation, build parameter list from mail and kwargs
|
|
584
|
-
params = {'mail':mail}
|
|
600
|
+
params = {'mail': mail}
|
|
585
601
|
params.update({k: v for k, v in kwargs.items() if v is not None})
|
|
586
|
-
|
|
602
|
+
|
|
587
603
|
return self.api_request('mail.set', params)
|
|
588
604
|
|
|
589
605
|
def mail_set_password(self, mail: str, password: str) -> dict:
|
|
@@ -593,7 +609,7 @@ class APIClient:
|
|
|
593
609
|
:param password: the password to set
|
|
594
610
|
:return: the response for the request
|
|
595
611
|
"""
|
|
596
|
-
return self.api_request('mail.set', {'mail':mail, 'password':password})
|
|
612
|
+
return self.api_request('mail.set', {'mail': mail, 'password': password})
|
|
597
613
|
|
|
598
614
|
def mail_set_password_require_reset(self, mail: str, password: str) -> dict:
|
|
599
615
|
"""
|
|
@@ -611,7 +627,7 @@ class APIClient:
|
|
|
611
627
|
:param plan: the plan to set
|
|
612
628
|
:return: the response for the request
|
|
613
629
|
"""
|
|
614
|
-
return self.api_request('mail.set', {'mail':mail, 'plan':plan})
|
|
630
|
+
return self.api_request('mail.set', {'mail': mail, 'plan': plan})
|
|
615
631
|
|
|
616
632
|
def mail_set_forwards(self, mail: str, forwards: list) -> dict:
|
|
617
633
|
"""
|
|
@@ -620,7 +636,7 @@ class APIClient:
|
|
|
620
636
|
:param forwards: a list of addresses to forwards mails to
|
|
621
637
|
:return: the response for the request
|
|
622
638
|
"""
|
|
623
|
-
return self.api_request('mail.set', {'mail':mail, 'forwards':forwards})
|
|
639
|
+
return self.api_request('mail.set', {'mail': mail, 'forwards': forwards})
|
|
624
640
|
|
|
625
641
|
def mail_set_aliases(self, mail: str, aliases: list) -> dict:
|
|
626
642
|
"""
|
|
@@ -629,7 +645,7 @@ class APIClient:
|
|
|
629
645
|
:param aliases: a list of aliases to set
|
|
630
646
|
:return: the response for the request
|
|
631
647
|
"""
|
|
632
|
-
return self.api_request('mail.set', {'mail':mail, 'aliases':aliases})
|
|
648
|
+
return self.api_request('mail.set', {'mail': mail, 'aliases': aliases})
|
|
633
649
|
|
|
634
650
|
def mail_set_state(self, mail: str, active: bool) -> dict:
|
|
635
651
|
"""
|
|
@@ -638,7 +654,7 @@ class APIClient:
|
|
|
638
654
|
:param active: True if the mail should be active, False if it shall be deactivated
|
|
639
655
|
:return: the response for the request
|
|
640
656
|
"""
|
|
641
|
-
return self.api_request('mail.set', {'mail':mail, 'active':active})
|
|
657
|
+
return self.api_request('mail.set', {'mail': mail, 'active': active})
|
|
642
658
|
|
|
643
659
|
def mail_set_additional_mail_quota(self, mail: str, quota: int) -> dict:
|
|
644
660
|
"""
|
|
@@ -648,7 +664,7 @@ class APIClient:
|
|
|
648
664
|
:return: the response for the request
|
|
649
665
|
"""
|
|
650
666
|
plan = self.mail_get(mail)['plan']
|
|
651
|
-
return self.api_request('mail.set', {'mail': mail, 'plan':plan, 'additional_mail_quota':quota})
|
|
667
|
+
return self.api_request('mail.set', {'mail': mail, 'plan': plan, 'additional_mail_quota': quota})
|
|
652
668
|
|
|
653
669
|
def mail_set_additional_cloud_quota(self, mail: str, quota: int) -> dict:
|
|
654
670
|
"""
|
|
@@ -670,7 +686,7 @@ class APIClient:
|
|
|
670
686
|
:return: the response for the request
|
|
671
687
|
"""
|
|
672
688
|
return self.api_request('mail.set', {'mail': mail, 'deletion_date': deletion_date,
|
|
673
|
-
|
|
689
|
+
'active': False})
|
|
674
690
|
|
|
675
691
|
def mail_capabilities_set(self, mail: str, capabilities: list) -> dict:
|
|
676
692
|
"""
|
|
@@ -687,7 +703,7 @@ class APIClient:
|
|
|
687
703
|
invalid = set(capabilities) - set(mail_capabilities)
|
|
688
704
|
if invalid:
|
|
689
705
|
raise ValueError(f'Invalid capabilities found: {", ".join(invalid)}')
|
|
690
|
-
params = {'mail':mail, 'capabilities':list(capabilities)}
|
|
706
|
+
params = {'mail': mail, 'capabilities': list(capabilities)}
|
|
691
707
|
return self.api_request('mail.capabilities.set', params)
|
|
692
708
|
|
|
693
709
|
def mail_del(self, mail: str) -> dict:
|
|
@@ -696,17 +712,17 @@ class APIClient:
|
|
|
696
712
|
:param mail: the mail to delete
|
|
697
713
|
:return: the response for the request
|
|
698
714
|
"""
|
|
699
|
-
return self.api_request('mail.del', {'mail':mail})
|
|
715
|
+
return self.api_request('mail.del', {'mail': mail})
|
|
700
716
|
|
|
701
|
-
def mail_apppassword_list(self, mail:str) -> dict:
|
|
717
|
+
def mail_apppassword_list(self, mail: str) -> dict:
|
|
702
718
|
"""
|
|
703
719
|
Function to list all app passwords of a given mail
|
|
704
720
|
:param mail: the mail to list app passwords for
|
|
705
721
|
:return: the response for the request
|
|
706
722
|
"""
|
|
707
|
-
return self.api_request('mail.apppassword.list', {'mail':mail})
|
|
723
|
+
return self.api_request('mail.apppassword.list', {'mail': mail})
|
|
708
724
|
|
|
709
|
-
def mail_apppassword_add(self, mail:str, memo:str, imap_allowed:bool = True, smtp_allowed:bool = True) -> dict:
|
|
725
|
+
def mail_apppassword_add(self, mail: str, memo: str, imap_allowed: bool = True, smtp_allowed: bool = True) -> dict:
|
|
710
726
|
"""
|
|
711
727
|
Function to generate a new mail app password for a mail
|
|
712
728
|
:param mail: the mail to generate a new mail app password
|
|
@@ -715,8 +731,8 @@ class APIClient:
|
|
|
715
731
|
:param smtp_allowed: True if the app password should be allowed to use an SMTP server. Default: True
|
|
716
732
|
:return: the response for the request
|
|
717
733
|
"""
|
|
718
|
-
return self.api_request('mail.apppassword.add', {'mail':mail, 'memo':memo,
|
|
719
|
-
'imap_allowed':imap_allowed, 'smtp_allowed':smtp_allowed})
|
|
734
|
+
return self.api_request('mail.apppassword.add', {'mail': mail, 'memo': memo,
|
|
735
|
+
'imap_allowed': imap_allowed, 'smtp_allowed': smtp_allowed})
|
|
720
736
|
|
|
721
737
|
def mail_apppassword_del(self, apppassword_id: int) -> dict:
|
|
722
738
|
"""
|
|
@@ -724,7 +740,7 @@ class APIClient:
|
|
|
724
740
|
:param apppassword_id: the id of the mail app password
|
|
725
741
|
:return: the response for the request
|
|
726
742
|
"""
|
|
727
|
-
return self.api_request('mail.apppassword.del', {'id':apppassword_id})
|
|
743
|
+
return self.api_request('mail.apppassword.del', {'id': apppassword_id})
|
|
728
744
|
|
|
729
745
|
def mail_externaluid(self, account: str, uid_extern: str) -> dict:
|
|
730
746
|
"""
|
|
@@ -733,7 +749,7 @@ class APIClient:
|
|
|
733
749
|
:param uid_extern: the external UID to get a mail for
|
|
734
750
|
:return: mailbox API response - an array with the mail details
|
|
735
751
|
"""
|
|
736
|
-
return self.api_request('mail.externaluid', {'account':account, 'uid_extern':uid_extern})
|
|
752
|
+
return self.api_request('mail.externaluid', {'account': account, 'uid_extern': uid_extern})
|
|
737
753
|
|
|
738
754
|
def mail_backup_list(self, mail: str) -> dict:
|
|
739
755
|
"""
|
|
@@ -741,7 +757,7 @@ class APIClient:
|
|
|
741
757
|
:param mail: the mail to list backups for
|
|
742
758
|
:return: mailbox API response - an array with the backup numbers and dates
|
|
743
759
|
"""
|
|
744
|
-
return self.api_request('mail.backup.list', {'mail':mail})
|
|
760
|
+
return self.api_request('mail.backup.list', {'mail': mail})
|
|
745
761
|
|
|
746
762
|
def mail_backup_import(self, mail: str, backup_id: str, time: str, backup_filter: str) -> dict:
|
|
747
763
|
"""
|
|
@@ -753,7 +769,7 @@ class APIClient:
|
|
|
753
769
|
:return: mailbox API response - an array with the backup numbers and dates
|
|
754
770
|
"""
|
|
755
771
|
return self.api_request('mail.backup.import',
|
|
756
|
-
{'mail':mail, 'id':backup_id, 'time':time, 'filter':backup_filter})
|
|
772
|
+
{'mail': mail, 'id': backup_id, 'time': time, 'filter': backup_filter})
|
|
757
773
|
|
|
758
774
|
def mail_spamprotect_get(self, mail: str) -> dict:
|
|
759
775
|
"""
|
|
@@ -761,7 +777,7 @@ class APIClient:
|
|
|
761
777
|
:param mail: the mail to get the spam settings for
|
|
762
778
|
:return: mailbox API response - an array with the spam settings
|
|
763
779
|
"""
|
|
764
|
-
return self.api_request('mail.spamprotect.get', {'mail':mail})
|
|
780
|
+
return self.api_request('mail.spamprotect.get', {'mail': mail})
|
|
765
781
|
|
|
766
782
|
def mail_spamprotect_set(self, mail: str, greylist: bool, smtp_plausibility: bool, rbl: bool,
|
|
767
783
|
bypass_banned_checks: bool, tag2level: float, killlevel: str, route_to: str) -> dict:
|
|
@@ -781,27 +797,28 @@ class APIClient:
|
|
|
781
797
|
raise ValueError('''Invalid value for killlevel. Only 'reject' or 'route' are allowed''')
|
|
782
798
|
|
|
783
799
|
return self.api_request('mail.spamprotect.set',
|
|
784
|
-
{'mail':mail, 'greylist': bool2str(greylist),
|
|
785
|
-
'smtp_plausibility':bool2str(smtp_plausibility), 'rbl':bool2str(rbl),
|
|
786
|
-
'bypass_banned_checks':bool2str(bypass_banned_checks),
|
|
787
|
-
'
|
|
800
|
+
{'mail': mail, 'greylist': bool2str(greylist),
|
|
801
|
+
'smtp_plausibility': bool2str(smtp_plausibility), 'rbl': bool2str(rbl),
|
|
802
|
+
'bypass_banned_checks': bool2str(bypass_banned_checks),
|
|
803
|
+
'tag2level': round(tag2level, 1),
|
|
804
|
+
'killevel': killlevel, 'route_to': route_to})
|
|
788
805
|
|
|
789
806
|
def mail_blacklist_list(self, mail: str) -> dict:
|
|
790
807
|
"""
|
|
791
|
-
Function to list the mail blacklist for a given mail address
|
|
792
|
-
:param mail: the mail to list the blacklist for
|
|
793
|
-
:return: mailbox API response - an array with the complete blacklist of the mail
|
|
808
|
+
Function to list the mail blacklist for a given mail address.
|
|
809
|
+
:param mail: the mail to list the blacklist for.
|
|
810
|
+
:return: mailbox API response - an array with the complete blacklist of the mail.
|
|
794
811
|
"""
|
|
795
|
-
return self.api_request('mail.blacklist.list', {'mail':mail})
|
|
812
|
+
return self.api_request('mail.blacklist.list', {'mail': mail})
|
|
796
813
|
|
|
797
814
|
def mail_blacklist_add(self, mail: str, add_address: str) -> dict:
|
|
798
815
|
"""
|
|
799
|
-
Function to add a mail to a blacklist of a mail address
|
|
800
|
-
:param mail: the mail of the owner of the blacklist
|
|
801
|
-
:param add_address: the address to add to the blacklist
|
|
802
|
-
:return: mailbox API response - an array with the complete blacklist of the mail
|
|
816
|
+
Function to add a mail to a blacklist of a mail address.
|
|
817
|
+
:param mail: the mail of the owner of the blacklist.
|
|
818
|
+
:param add_address: the address to add to the blacklist.
|
|
819
|
+
:return: mailbox API response - an array with the complete blacklist of the mail.
|
|
803
820
|
"""
|
|
804
|
-
return self.api_request('mail.blacklist.add', {'mail':mail, 'add_address':add_address})
|
|
821
|
+
return self.api_request('mail.blacklist.add', {'mail': mail, 'add_address': add_address})
|
|
805
822
|
|
|
806
823
|
def mail_blacklist_del(self, mail: str, delete_address: str) -> dict:
|
|
807
824
|
"""
|
|
@@ -810,7 +827,7 @@ class APIClient:
|
|
|
810
827
|
:param delete_address: the address to delete from the blacklist
|
|
811
828
|
:return: mailbox API response - an array with the complete blacklist of the mail
|
|
812
829
|
"""
|
|
813
|
-
return self.api_request('mail.blacklist.del', {'mail':mail, 'delete_address':delete_address})
|
|
830
|
+
return self.api_request('mail.blacklist.del', {'mail': mail, 'delete_address': delete_address})
|
|
814
831
|
|
|
815
832
|
def mail_vacation_get(self, mail: str) -> dict:
|
|
816
833
|
"""
|
|
@@ -818,7 +835,7 @@ class APIClient:
|
|
|
818
835
|
:param mail: the mail to get the vacation notice for
|
|
819
836
|
:return: mailbox API response - the vacation notice of the mail
|
|
820
837
|
"""
|
|
821
|
-
return self.api_request('mail.vacation.get', {'mail':mail})
|
|
838
|
+
return self.api_request('mail.vacation.get', {'mail': mail})
|
|
822
839
|
|
|
823
840
|
def mail_vacation_set(self, mail: str, subject: str, body: str, start_date: str, end_date: str,
|
|
824
841
|
additional_mail_addresses: list | None = None) -> dict:
|
|
@@ -832,8 +849,8 @@ class APIClient:
|
|
|
832
849
|
:param additional_mail_addresses: list of addresses to add to the vacation notice (optional)
|
|
833
850
|
:return: mailbox API response - array with result 'true' of the request, code and message in case of an error
|
|
834
851
|
"""
|
|
835
|
-
params = {'mail':mail, 'subject':subject, 'body':body,'start_date':start_date, 'end_date':end_date,
|
|
836
|
-
'additional_mail_addresses':additional_mail_addresses}
|
|
852
|
+
params = {'mail': mail, 'subject': subject, 'body': body, 'start_date': start_date, 'end_date': end_date,
|
|
853
|
+
'additional_mail_addresses': additional_mail_addresses}
|
|
837
854
|
|
|
838
855
|
# If no additional_mail_addresses are given, remove the parameter from the request
|
|
839
856
|
if not additional_mail_addresses:
|
|
@@ -841,7 +858,7 @@ class APIClient:
|
|
|
841
858
|
|
|
842
859
|
return self.api_request('mail.vacation.set', params)
|
|
843
860
|
|
|
844
|
-
def group_list(self, account:str | None = None) -> dict:
|
|
861
|
+
def group_list(self, account: str | None = None) -> dict:
|
|
845
862
|
"""
|
|
846
863
|
Function to list all groups for an account
|
|
847
864
|
:param account: optional parameter for the account to list the groups for
|
|
@@ -885,13 +902,13 @@ class APIClient:
|
|
|
885
902
|
:param account: optional parameter for the account to add the group for
|
|
886
903
|
:return: mailbox API response - True if the group was added, False otherwise
|
|
887
904
|
"""
|
|
888
|
-
params = {'name':name, 'display_name':display_name, 'mail_addresses_to_add':mail_addresses_to_add}
|
|
905
|
+
params = {'name': name, 'display_name': display_name, 'mail_addresses_to_add': mail_addresses_to_add}
|
|
889
906
|
if account:
|
|
890
907
|
params['account'] = account
|
|
891
908
|
return self.api_request('group.add', params)
|
|
892
909
|
|
|
893
910
|
def group_set(self, group_id: int, display_name: str, mail_addresses_to_add: list | None = None,
|
|
894
|
-
mail_addresses_to_remove: list | None = None, account: str | None= None) -> dict:
|
|
911
|
+
mail_addresses_to_remove: list | None = None, account: str | None = None) -> dict:
|
|
895
912
|
"""
|
|
896
913
|
Function to modify a group. Either mail_addresses_to_add or mail_addresses_to_remove have to be specified.
|
|
897
914
|
:param group_id: the group's id of the group to modify
|
|
@@ -905,8 +922,8 @@ class APIClient:
|
|
|
905
922
|
if mail_addresses_to_add is None and mail_addresses_to_remove is None:
|
|
906
923
|
raise ValueError('mail_addresses_to_add or mail_addresses_to_remove are required')
|
|
907
924
|
|
|
908
|
-
params = {'group_id':group_id, 'display_name':display_name, 'mail_addresses_to_add':mail_addresses_to_add,
|
|
909
|
-
'mail_addresses_to_remove':mail_addresses_to_remove}
|
|
925
|
+
params = {'group_id': group_id, 'display_name': display_name, 'mail_addresses_to_add': mail_addresses_to_add,
|
|
926
|
+
'mail_addresses_to_remove': mail_addresses_to_remove}
|
|
910
927
|
if account:
|
|
911
928
|
params['account'] = account
|
|
912
929
|
return self.api_request('group.set', params)
|
|
@@ -917,16 +934,16 @@ class APIClient:
|
|
|
917
934
|
:param mail: the mail to query
|
|
918
935
|
:return: mailbox API response - a list of available password reset methods
|
|
919
936
|
"""
|
|
920
|
-
return self.api_request('mail.passwordreset.listmethods', {'mail':mail})
|
|
937
|
+
return self.api_request('mail.passwordreset.listmethods', {'mail': mail})
|
|
921
938
|
|
|
922
939
|
def mail_passwordreset_sendsms(self, mail: str, cell_phone: str) -> dict:
|
|
923
940
|
"""
|
|
924
941
|
Function to send a password reset for a mail via SMS
|
|
925
942
|
:param mail: the mail to send the SMS for
|
|
926
943
|
:param cell_phone: the cell phone number of the mailbox
|
|
927
|
-
:return:
|
|
944
|
+
:return: API response from mailbox - True if the SMS was sent, False otherwise
|
|
928
945
|
"""
|
|
929
|
-
return self.api_request('mail.passwordreset.sendsms',{'mail':mail, 'cell_phone':cell_phone})
|
|
946
|
+
return self.api_request('mail.passwordreset.sendsms', {'mail': mail, 'cell_phone': cell_phone})
|
|
930
947
|
|
|
931
948
|
def mail_passwordreset_setpassword(self, mail: str, token: str, password: str) -> dict:
|
|
932
949
|
"""
|
|
@@ -937,7 +954,7 @@ class APIClient:
|
|
|
937
954
|
:return: mailbox API response - True if the password was set, False otherwise
|
|
938
955
|
"""
|
|
939
956
|
return self.api_request('mail.passwordreset.setpassword',
|
|
940
|
-
{'mail':mail, 'token':token, 'password':password})
|
|
957
|
+
{'mail': mail, 'token': token, 'password': password})
|
|
941
958
|
|
|
942
959
|
def context_list(self, account: str) -> dict:
|
|
943
960
|
"""
|
|
@@ -945,7 +962,7 @@ class APIClient:
|
|
|
945
962
|
:param account: the account to list all contexts for
|
|
946
963
|
:return: mailbox API response - an array with key 'context id' and value 'associated domains'
|
|
947
964
|
"""
|
|
948
|
-
return self.api_request('context.list', {'account':account})
|
|
965
|
+
return self.api_request('context.list', {'account': account})
|
|
949
966
|
|
|
950
967
|
def search(self, query: str, get_account_summary: bool = False, get_extended_mail_result: bool = False) -> dict:
|
|
951
968
|
"""
|
|
@@ -955,8 +972,8 @@ class APIClient:
|
|
|
955
972
|
:param get_extended_mail_result: whether to return more information about mailboxes found
|
|
956
973
|
:return: the mailbox API response for the request - an array with results for accounts, domains and mailboxes
|
|
957
974
|
"""
|
|
958
|
-
return self.api_request('search', {'query':query, 'get_account_summary':get_account_summary,
|
|
959
|
-
'get_extended_mail_result':get_extended_mail_result})
|
|
975
|
+
return self.api_request('search', {'query': query, 'get_account_summary': get_account_summary,
|
|
976
|
+
'get_extended_mail_result': get_extended_mail_result})
|
|
960
977
|
|
|
961
978
|
def mailinglist_list(self, account: str) -> dict:
|
|
962
979
|
"""
|
|
@@ -964,7 +981,7 @@ class APIClient:
|
|
|
964
981
|
:param account: the account to list all mailing lists for
|
|
965
982
|
:return: a dict containing the list of mailing lists
|
|
966
983
|
"""
|
|
967
|
-
return self.api_request('mailinglist.list', {'account':account})
|
|
984
|
+
return self.api_request('mailinglist.list', {'account': account})
|
|
968
985
|
|
|
969
986
|
def mailinglist_add(self, mailinglist: str, password: str, account: str, adminmail: str | None = None) -> dict:
|
|
970
987
|
"""
|
|
@@ -975,8 +992,8 @@ class APIClient:
|
|
|
975
992
|
:param adminmail: admin email address of the mailing list (optional)
|
|
976
993
|
:return: True if the mailing list was added, error code otherwise
|
|
977
994
|
"""
|
|
978
|
-
return self.api_request('mailinglist.add', {'mailinglist':mailinglist, 'password':password,
|
|
979
|
-
|
|
995
|
+
return self.api_request('mailinglist.add', {'mailinglist': mailinglist, 'password': password,
|
|
996
|
+
'account': account, 'adminmail': adminmail})
|
|
980
997
|
|
|
981
998
|
def mailinglist_get(self, mailinglist: str, account: str) -> dict:
|
|
982
999
|
"""
|
|
@@ -985,20 +1002,20 @@ class APIClient:
|
|
|
985
1002
|
:param account: the account of the mailing list
|
|
986
1003
|
:return: the mailbox API response for the request - a dict of the mailing list
|
|
987
1004
|
"""
|
|
988
|
-
return self.api_request('mailinglist.get', {'mailinglist':mailinglist, 'account':account})
|
|
1005
|
+
return self.api_request('mailinglist.get', {'mailinglist': mailinglist, 'account': account})
|
|
989
1006
|
|
|
990
1007
|
def mailinglist_set(self, mailinglist: str, account: str, password: str | None = None,
|
|
991
1008
|
adminmail: str | None = None) -> dict:
|
|
992
1009
|
"""
|
|
993
|
-
Function to change a mailing list
|
|
994
|
-
:param mailinglist: the mailing list to change
|
|
995
|
-
:param password: the password of the mailing list
|
|
996
|
-
:param account: the account of the mailing list (optional)
|
|
997
|
-
:param adminmail: admin email address of the mailing list (optional)
|
|
998
|
-
:return: the mailbox API response for the request - True if the mailing list was changed, error code otherwise
|
|
1010
|
+
Function to change a mailing list.
|
|
1011
|
+
:param mailinglist: the mailing list to change.
|
|
1012
|
+
:param password: the password of the mailing list.
|
|
1013
|
+
:param account: the account of the mailing list (optional).
|
|
1014
|
+
:param adminmail: admin email address of the mailing list (optional).
|
|
1015
|
+
:return: the mailbox API response for the request - True if the mailing list was changed, error code otherwise.
|
|
999
1016
|
"""
|
|
1000
|
-
return self.api_request('mailinglist.set', {'mailinglist':mailinglist, 'account':account,
|
|
1001
|
-
|
|
1017
|
+
return self.api_request('mailinglist.set', {'mailinglist': mailinglist, 'account': account,
|
|
1018
|
+
'password': password, 'adminmail': adminmail})
|
|
1002
1019
|
|
|
1003
1020
|
def mailinglist_del(self, mailinglist: str, account: str) -> dict:
|
|
1004
1021
|
"""
|
|
@@ -1007,7 +1024,7 @@ class APIClient:
|
|
|
1007
1024
|
:param account: the account of the mailing list
|
|
1008
1025
|
:return: the mailbox API response for the request - True if the mailing list was deleted, error code otherwise
|
|
1009
1026
|
"""
|
|
1010
|
-
return self.api_request('mailinglist.del', {'mailinglist':mailinglist, 'account':account})
|
|
1027
|
+
return self.api_request('mailinglist.del', {'mailinglist': mailinglist, 'account': account})
|
|
1011
1028
|
|
|
1012
1029
|
def additionalmailaccount_list(self, parent_mail: str) -> dict:
|
|
1013
1030
|
"""
|
|
@@ -1015,7 +1032,7 @@ class APIClient:
|
|
|
1015
1032
|
:param parent_mail: the parent mail to list additional mail accounts for
|
|
1016
1033
|
:return: a dict containing the parent mail account and a list of additional mail accounts
|
|
1017
1034
|
"""
|
|
1018
|
-
return self.api_request('additionalmailaccount.list', {'parent_mail':parent_mail})
|
|
1035
|
+
return self.api_request('additionalmailaccount.list', {'parent_mail': parent_mail})
|
|
1019
1036
|
|
|
1020
1037
|
def additionalmailaccount_add(self, parent_mail: str, new_account_mail: str, new_account_password: str,
|
|
1021
1038
|
primary_address: str | None = None, mail_server: str = 'imap.mailbox.org',
|
|
@@ -1031,23 +1048,23 @@ class APIClient:
|
|
|
1031
1048
|
2. mail server settings are grouped
|
|
1032
1049
|
3. transport server settings are grouped
|
|
1033
1050
|
4. Ports are integers
|
|
1034
|
-
:param new_account_mail: the additional mail address to add
|
|
1035
|
-
:param new_account_password: the password of the additional mail address
|
|
1036
|
-
:param parent_mail: the mail address to add the additional mail account to
|
|
1037
|
-
:param primary_address: the primary 'address from' for the additional mail address
|
|
1038
|
-
:param mail_server: the IMAP server to use
|
|
1039
|
-
:param mail_port: the port of the IMAP server
|
|
1040
|
-
:param transport_server: the SMTP server to use
|
|
1041
|
-
:param transport_port: the port of the SMTP server
|
|
1042
|
-
:param mail_secure: whether to use SSL for IMAP
|
|
1043
|
-
:param mail_starttls: whether to use STARTTLS for IMAP
|
|
1044
|
-
:param transport_secure: whether to use SSL for SMTP
|
|
1045
|
-
:param transport_starttls: whether to use STARTTLS for SMTP
|
|
1046
|
-
:param trash_folder: name of the trash folder
|
|
1047
|
-
:param sent_folder: name of the sent folder
|
|
1048
|
-
:param drafts_folder: name of the drafts folder
|
|
1049
|
-
:param spam_folder: name of the spam folder
|
|
1050
|
-
:return: the response for the request - True if adding was successful, error code otherwise
|
|
1051
|
+
:param new_account_mail: the additional mail address to add.
|
|
1052
|
+
:param new_account_password: the password of the additional mail address.
|
|
1053
|
+
:param parent_mail: the mail address to add the additional mail account to.
|
|
1054
|
+
:param primary_address: the primary 'address from' for the additional mail address.
|
|
1055
|
+
:param mail_server: the IMAP server to use.
|
|
1056
|
+
:param mail_port: the port of the IMAP server.
|
|
1057
|
+
:param transport_server: the SMTP server to use.
|
|
1058
|
+
:param transport_port: the port of the SMTP server.
|
|
1059
|
+
:param mail_secure: whether to use SSL for IMAP.
|
|
1060
|
+
:param mail_starttls: whether to use STARTTLS for IMAP.
|
|
1061
|
+
:param transport_secure: whether to use SSL for SMTP.
|
|
1062
|
+
:param transport_starttls: whether to use STARTTLS for SMTP.
|
|
1063
|
+
:param trash_folder: name of the trash folder.
|
|
1064
|
+
:param sent_folder: name of the sent folder.
|
|
1065
|
+
:param drafts_folder: name of the drafts folder.
|
|
1066
|
+
:param spam_folder: name of the spam folder.
|
|
1067
|
+
:return: the response for the request - True if adding was successful, error code otherwise.
|
|
1051
1068
|
"""
|
|
1052
1069
|
return self.api_request('additionalmailaccount.add', {'new_account_mail': new_account_mail,
|
|
1053
1070
|
'new_account_password': new_account_password,
|
|
@@ -1073,7 +1090,7 @@ class APIClient:
|
|
|
1073
1090
|
:return: True if the account was deleted, error code otherwise
|
|
1074
1091
|
"""
|
|
1075
1092
|
return self.api_request('additionalmailaccount.delete',
|
|
1076
|
-
{'parent_mail':parent_mail, 'account_mail':account_mail})
|
|
1093
|
+
{'parent_mail': parent_mail, 'account_mail': account_mail})
|
|
1077
1094
|
|
|
1078
1095
|
def evac_activate(self):
|
|
1079
1096
|
"""
|
|
@@ -1083,7 +1100,7 @@ class APIClient:
|
|
|
1083
1100
|
"""
|
|
1084
1101
|
return self.api_request('evac_activate', {})
|
|
1085
1102
|
|
|
1086
|
-
def evac_resetaccount(self, delete_mail_accounts_and_domains:bool = False) -> dict:
|
|
1103
|
+
def evac_resetaccount(self, delete_mail_accounts_and_domains: bool = False) -> dict:
|
|
1087
1104
|
"""
|
|
1088
1105
|
Function to reset a mailbox EVAC account.
|
|
1089
1106
|
Note: this needs a special permission from mailbox.
|
|
@@ -1093,6 +1110,7 @@ class APIClient:
|
|
|
1093
1110
|
return self.api_request('evac_resetaccount',
|
|
1094
1111
|
{'delete_mail_accounts_and_domains': delete_mail_accounts_and_domains})
|
|
1095
1112
|
|
|
1113
|
+
|
|
1096
1114
|
def validate_params(allowed: dict, actual: dict) -> bool | None:
|
|
1097
1115
|
for arg in actual:
|
|
1098
1116
|
if arg not in allowed:
|
|
@@ -1104,6 +1122,7 @@ def validate_params(allowed: dict, actual: dict) -> bool | None:
|
|
|
1104
1122
|
return True
|
|
1105
1123
|
return None
|
|
1106
1124
|
|
|
1125
|
+
|
|
1107
1126
|
def bool2str(state: bool) -> str:
|
|
1108
1127
|
"""
|
|
1109
1128
|
Converts a boolean value to '1' if True, and '0' if False...
|
|
@@ -1111,4 +1130,4 @@ def bool2str(state: bool) -> str:
|
|
|
1111
1130
|
"""
|
|
1112
1131
|
if state:
|
|
1113
1132
|
return '1'
|
|
1114
|
-
return '0'
|
|
1133
|
+
return '0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mailbox-org-api
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4
|
|
4
4
|
Summary: A library to access the mailbox Business API.
|
|
5
5
|
Author: Hendrik Schlange
|
|
6
6
|
Author-email: Hendrik Schlange <mail@heshsum.de>
|
|
@@ -36,11 +36,15 @@ pip install mailbox-org-api
|
|
|
36
36
|
pip install git+https://github.com/heshsum/mailbox-org-api
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
## Usage
|
|
39
|
+
## Usage and documentation
|
|
40
40
|
Basic usage is fairly straightforward. The naming scheme of the functions is similar to the naming at mailbox.org,
|
|
41
|
-
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
41
|
+
but instead of points, it uses underscores (e.g. instead of `mail.add` it's `mail_add`).
|
|
42
|
+
|
|
43
|
+
Therefore, the functions mirror the functions as provided and documented at mailbox:
|
|
44
|
+
[api.mailbox.org](https://api.mailbox.org)
|
|
45
|
+
|
|
42
46
|
Additionally, some helper functions for common or more complicated tasks are included to make life a bit easier,
|
|
43
|
-
e.g. for changing plans, password and to
|
|
47
|
+
e.g. for changing plans, password and to retrieving invoices.
|
|
44
48
|
|
|
45
49
|
```python
|
|
46
50
|
from mailbox_org_api import APIClient
|
|
@@ -87,6 +91,8 @@ api.mail_set_forwards('foo@bar.com', ['forward1@bar.com', 'forward2@bar.com'])
|
|
|
87
91
|
api.deauth()
|
|
88
92
|
```
|
|
89
93
|
|
|
94
|
+
More information can be found in the [Wiki](https://github.com/heshsum/mailbox-org-api/wiki)
|
|
95
|
+
|
|
90
96
|
## Common tasks
|
|
91
97
|
mailbox_org_api includes a number of helper functions to make common tasks simpler. These include:
|
|
92
98
|
|
|
@@ -163,21 +169,21 @@ Usage:
|
|
|
163
169
|
api.account_invoice_get_token('BMBO-1234-24')
|
|
164
170
|
```
|
|
165
171
|
|
|
166
|
-
###
|
|
172
|
+
### account_invoice_get_file
|
|
167
173
|
Invoices are provided as Based64 encoded gz Strings. This function
|
|
168
174
|
1. takes the invoice ID
|
|
169
175
|
2. retrieves the token for the invoice
|
|
170
176
|
3. gets the binary data
|
|
171
177
|
4. decodes the Base64
|
|
172
178
|
5. decompresses it
|
|
173
|
-
6. returns the bytes of the actual
|
|
179
|
+
6. returns the bytes of the actual invoice file
|
|
174
180
|
|
|
175
181
|
Usage
|
|
176
182
|
```python
|
|
177
183
|
invoice_id = 'BMBO-1234-24'
|
|
178
|
-
account_name = '
|
|
184
|
+
account_name = 'foo'
|
|
179
185
|
with open(invoice_id + '.pdf', 'w') as file:
|
|
180
|
-
file.write(api.
|
|
186
|
+
file.write(api.account_invoice_get_file(account_name, invoice_id, 'PDF'))
|
|
181
187
|
```
|
|
182
188
|
|
|
183
189
|
## Here be dragons
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
from mailbox_org_api import APIClient
|
|
2
|
-
from mailbox_org_api.APIError import APIError
|
|
3
|
-
import pytest
|
|
4
1
|
import os
|
|
5
|
-
import time
|
|
6
2
|
import secrets
|
|
7
3
|
import string
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from mailbox_org_api import APIClient
|
|
9
|
+
from mailbox_org_api.APIError import APIError
|
|
8
10
|
|
|
9
11
|
api_test_user = os.environ['API_TEST_USER']
|
|
10
12
|
api_test_pass = os.environ['API_TEST_PASS']
|
|
11
13
|
|
|
14
|
+
|
|
12
15
|
# Create a unique ID String by using the Unix time,
|
|
13
16
|
# converted to int (to get rid of the decimal) and then to String
|
|
14
17
|
def generate_id():
|
|
15
18
|
return str(int(time.time()))
|
|
16
19
|
|
|
20
|
+
|
|
17
21
|
def generate_pw():
|
|
18
22
|
# Length of password
|
|
19
23
|
length = 42
|
|
@@ -36,6 +40,7 @@ def generate_pw():
|
|
|
36
40
|
any(c in special for c in pw)):
|
|
37
41
|
return pw
|
|
38
42
|
|
|
43
|
+
|
|
39
44
|
def get_domain():
|
|
40
45
|
api = APIClient.APIClient()
|
|
41
46
|
api.auth(api_test_user, api_test_pass)
|
|
@@ -43,16 +48,18 @@ def get_domain():
|
|
|
43
48
|
api.deauth()
|
|
44
49
|
return domain
|
|
45
50
|
|
|
51
|
+
|
|
46
52
|
test_id = generate_id()
|
|
47
53
|
domain = get_domain()
|
|
48
54
|
|
|
55
|
+
|
|
49
56
|
class TestAPIClient:
|
|
50
57
|
def test_validate_params(self):
|
|
51
58
|
allowed = {'string': str}
|
|
52
59
|
with pytest.raises(ValueError):
|
|
53
|
-
APIClient.validate_params(allowed, {'integer':123})
|
|
60
|
+
APIClient.validate_params(allowed, {'integer': 123})
|
|
54
61
|
with pytest.raises(TypeError):
|
|
55
|
-
APIClient.validate_params(allowed, {'string':123})
|
|
62
|
+
APIClient.validate_params(allowed, {'string': 123})
|
|
56
63
|
|
|
57
64
|
def test_headers(self):
|
|
58
65
|
api = APIClient.APIClient()
|
|
@@ -195,7 +202,7 @@ class TestAPIClient:
|
|
|
195
202
|
api.auth(api_test_user, api_test_pass)
|
|
196
203
|
invoice = api.account_invoice_get_list(api_test_user)[0]
|
|
197
204
|
token = api.account_invoice_get_token(api_test_user, invoice_id=invoice)
|
|
198
|
-
assert len(token) >0
|
|
205
|
+
assert len(token) > 0
|
|
199
206
|
assert isinstance(token, str)
|
|
200
207
|
api.deauth()
|
|
201
208
|
|
|
@@ -210,6 +217,16 @@ class TestAPIClient:
|
|
|
210
217
|
assert isinstance(d['count_mails'], int)
|
|
211
218
|
api.deauth()
|
|
212
219
|
|
|
220
|
+
def test_domain_get_list(self):
|
|
221
|
+
api = APIClient.APIClient()
|
|
222
|
+
api.auth(api_test_user, api_test_pass)
|
|
223
|
+
domain_names = api.domain_get_list(api_test_user)
|
|
224
|
+
domains = api.domain_list(api_test_user)
|
|
225
|
+
assert len(domain_names) == len(domains)
|
|
226
|
+
for d in domains:
|
|
227
|
+
assert d['domain'] in domain_names
|
|
228
|
+
api.deauth()
|
|
229
|
+
|
|
213
230
|
def test_domain_get(self):
|
|
214
231
|
api = APIClient.APIClient()
|
|
215
232
|
api.auth(api_test_user, api_test_pass)
|
|
@@ -257,13 +274,24 @@ class TestAPIClient:
|
|
|
257
274
|
assert paginated_mails['totalPages'] is not None
|
|
258
275
|
assert paginated_mails['results'] is not None
|
|
259
276
|
with pytest.raises(APIError):
|
|
260
|
-
api.mail_list(domain, page
|
|
277
|
+
api.mail_list(domain, page=2)
|
|
261
278
|
with pytest.raises(APIError):
|
|
262
279
|
api.mail_list(domain, page_size=-1)
|
|
263
280
|
with pytest.raises(ValueError):
|
|
264
281
|
api.mail_list(domain, sort_order='wröng')
|
|
265
282
|
api.deauth()
|
|
266
283
|
|
|
284
|
+
def test_mail_get_list(self):
|
|
285
|
+
api = APIClient.APIClient()
|
|
286
|
+
api.auth(api_test_user, api_test_pass)
|
|
287
|
+
mails = api.mail_list(domain)
|
|
288
|
+
mail_addresses = api.mail_get_list(domain)
|
|
289
|
+
assert len(mail_addresses) == len(mails)
|
|
290
|
+
for i in mails:
|
|
291
|
+
assert i['mail'] is not None
|
|
292
|
+
assert i['mail'] in mail_addresses
|
|
293
|
+
api.deauth()
|
|
294
|
+
|
|
267
295
|
def test_mail_get(self):
|
|
268
296
|
api = APIClient.APIClient()
|
|
269
297
|
api.auth(api_test_user, api_test_pass)
|
|
@@ -318,8 +346,8 @@ class TestAPIClient:
|
|
|
318
346
|
'aliases': [test_id + '_alias@' + domain], 'alternate_mail': test_id + '_alternate@' + domain,
|
|
319
347
|
'memo': 'memo_string', 'active': True, 'title': 'Title', 'position': 'Job Position',
|
|
320
348
|
'department': 'Department', 'company': 'Company', 'street': 'Street 1',
|
|
321
|
-
'postal_code': '12345', 'city': 'City', 'phone':'+492345678', 'fax':'+492345678',
|
|
322
|
-
'cell_phone':'+492345678', 'uid_extern': 'external_uid_value', 'language': 'de_DE'}
|
|
349
|
+
'postal_code': '12345', 'city': 'City', 'phone': '+492345678', 'fax': '+492345678',
|
|
350
|
+
'cell_phone': '+492345678', 'uid_extern': 'external_uid_value', 'language': 'de_DE'}
|
|
323
351
|
|
|
324
352
|
# Adding parameters to call
|
|
325
353
|
params = {}
|
|
@@ -340,7 +368,7 @@ class TestAPIClient:
|
|
|
340
368
|
api.mail_set(mail, additional_cloud_quota=5)
|
|
341
369
|
|
|
342
370
|
with pytest.raises(KeyError):
|
|
343
|
-
api.mail_set(mail, additional_mail_quota
|
|
371
|
+
api.mail_set(mail, additional_mail_quota=5, additional_cloud_quota=5)
|
|
344
372
|
|
|
345
373
|
api.deauth()
|
|
346
374
|
|
|
@@ -2,6 +2,7 @@ from mailbox_org_api import Account
|
|
|
2
2
|
|
|
3
3
|
account_name = 'heiner.hansen'
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
class TestAccount:
|
|
6
7
|
def test_account(self):
|
|
7
8
|
account = Account.Account(account_name)
|
|
@@ -80,8 +81,8 @@ class TestAccount:
|
|
|
80
81
|
def test_account_contact(self):
|
|
81
82
|
account = Account.Account(account_name)
|
|
82
83
|
assert account.contact == {}
|
|
83
|
-
contact = {'mail':'contact@tests.internal', 'first_name': 'Test', 'last_name': 'Contact', 'birthday': '',
|
|
84
|
-
'street':'Teststr. 1', 'zipcode':'12345', 'town':'Testtown', 'country':'DE'}
|
|
84
|
+
contact = {'mail': 'contact@tests.internal', 'first_name': 'Test', 'last_name': 'Contact', 'birthday': '',
|
|
85
|
+
'street': 'Teststr. 1', 'zipcode': '12345', 'town': 'Testtown', 'country': 'DE'}
|
|
85
86
|
account.contact = contact
|
|
86
87
|
assert account.contact == contact
|
|
87
88
|
|
|
@@ -3,6 +3,7 @@ from mailbox_org_api import Invoice
|
|
|
3
3
|
test_account = 'test_account'
|
|
4
4
|
test_id = 'BMBO-1234-2025'
|
|
5
5
|
|
|
6
|
+
|
|
6
7
|
class TestMail:
|
|
7
8
|
|
|
8
9
|
def test_invoice_create(self):
|
|
@@ -43,4 +44,4 @@ class TestMail:
|
|
|
43
44
|
assert invoice.token is None
|
|
44
45
|
token = '123456789'
|
|
45
46
|
invoice.token = token
|
|
46
|
-
assert invoice.token == token
|
|
47
|
+
assert invoice.token == token
|
|
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
|