1
1
from typing import NoReturn
2
+ from typing import Optional
2
3
from typing import Union
3
4
4
5
import requests
5
6
6
7
from mailtrap .exceptions import APIError
7
8
from mailtrap .exceptions import AuthorizationError
9
+ from mailtrap .exceptions import ClientConfigurationError
8
10
from mailtrap .mail .base import BaseMail
9
11
10
12
11
13
class MailtrapClient :
12
14
DEFAULT_HOST = "send.api.mailtrap.io"
13
15
DEFAULT_PORT = 443
16
+ SANDBOX_HOST = "sandbox.api.mailtrap.io"
14
17
15
18
def __init__ (
16
19
self ,
17
20
token : str ,
18
- api_host : str = DEFAULT_HOST ,
21
+ api_host : Optional [ str ] = None ,
19
22
api_port : int = DEFAULT_PORT ,
23
+ sandbox : bool = False ,
24
+ inbox_id : Optional [str ] = None ,
20
25
) -> None :
21
26
self .token = token
22
27
self .api_host = api_host
23
28
self .api_port = api_port
29
+ self .sandbox = sandbox
30
+ self .inbox_id = inbox_id
31
+
32
+ self ._validate_itself ()
24
33
25
34
def send (self , mail : BaseMail ) -> dict [str , Union [bool , list [str ]]]:
26
- url = f"{ self .base_url } /api/send"
27
- response = requests .post (url , headers = self .headers , json = mail .api_data )
35
+ response = requests .post (
36
+ self .api_send_url , headers = self .headers , json = mail .api_data
37
+ )
28
38
29
39
if response .ok :
30
40
data : dict [str , Union [bool , list [str ]]] = response .json ()
@@ -34,7 +44,15 @@ def send(self, mail: BaseMail) -> dict[str, Union[bool, list[str]]]:
34
44
35
45
@property
36
46
def base_url (self ) -> str :
37
- return f"https://{ self .api_host .rstrip ('/' )} :{ self .api_port } "
47
+ return f"https://{ self ._host .rstrip ('/' )} :{ self .api_port } "
48
+
49
+ @property
50
+ def api_send_url (self ) -> str :
51
+ url = f"{ self .base_url } /api/send"
52
+ if self .sandbox and self .inbox_id :
53
+ return f"{ url } /{ self .inbox_id } "
54
+
55
+ return url
38
56
39
57
@property
40
58
def headers (self ) -> dict [str , str ]:
@@ -46,6 +64,14 @@ def headers(self) -> dict[str, str]:
46
64
),
47
65
}
48
66
67
+ @property
68
+ def _host (self ) -> str :
69
+ if self .api_host :
70
+ return self .api_host
71
+ if self .sandbox :
72
+ return self .SANDBOX_HOST
73
+ return self .DEFAULT_HOST
74
+
49
75
@staticmethod
50
76
def _handle_failed_response (response : requests .Response ) -> NoReturn :
51
77
status_code = response .status_code
@@ -55,3 +81,12 @@ def _handle_failed_response(response: requests.Response) -> NoReturn:
55
81
raise AuthorizationError (data ["errors" ])
56
82
57
83
raise APIError (status_code , data ["errors" ])
84
+
85
+ def _validate_itself (self ) -> None :
86
+ if self .sandbox and not self .inbox_id :
87
+ raise ClientConfigurationError ("`inbox_id` is required for sandbox mode" )
88
+
89
+ if not self .sandbox and self .inbox_id :
90
+ raise ClientConfigurationError (
91
+ "`inbox_id` is not allowed in non-sandbox mode"
92
+ )
0 commit comments