11"""Temp Mail API client implementation."""
22
33import typing
4- from typing import Optional , List , Dict , Any
4+ from typing import Optional , List , Dict , Any , overload , Literal
55from urllib .parse import urljoin
6- import requests
6+ import httpx
77
88from . import __version__
99from .models import (
@@ -35,17 +35,39 @@ def __init__(
3535 self .base_url = base_url
3636 self .timeout = timeout
3737
38- self .session = requests .Session ()
39- self .session .headers .update (
40- {
38+ self .client = httpx .Client (
39+ headers = {
4140 "X-API-Key" : api_key ,
4241 "Content-Type" : "application/json" ,
4342 "User-Agent" : f"temp-mail-python/{ __version__ } " ,
44- }
43+ },
44+ timeout = timeout ,
4545 )
4646
4747 self ._last_rate_limit : Optional [RateLimit ] = None
4848
49+ @overload
50+ def _make_request (
51+ self ,
52+ method : str ,
53+ endpoint : str ,
54+ params : Optional [Dict [str , Any ]] = None ,
55+ json_data : Optional [Dict [str , Any ]] = None ,
56+ return_content : Literal [True ] = ...,
57+ update_rate_limit : bool = True ,
58+ ) -> bytes : ...
59+
60+ @overload
61+ def _make_request (
62+ self ,
63+ method : str ,
64+ endpoint : str ,
65+ params : Optional [Dict [str , Any ]] = None ,
66+ json_data : Optional [Dict [str , Any ]] = None ,
67+ return_content : Literal [False ] = ...,
68+ update_rate_limit : bool = True ,
69+ ) -> Dict [str , Any ]: ...
70+
4971 def _make_request (
5072 self ,
5173 method : str ,
@@ -66,12 +88,11 @@ def _make_request(
6688 url = urljoin (self .base_url , endpoint )
6789
6890 try :
69- response = self .session .request (
91+ response = self .client .request (
7092 method = method ,
7193 url = url ,
7294 params = params ,
7395 json = json_data ,
74- timeout = self .timeout ,
7596 )
7697
7798 if 200 <= response .status_code < 300 :
@@ -92,7 +113,7 @@ def _make_request(
92113 raise ValidationError (api_response .detail )
93114 else :
94115 raise TempMailError (api_response .detail )
95- except requests . exceptions . RequestException as e :
116+ except httpx . RequestError as e :
96117 raise TempMailError (f"Request failed: { str (e )} " )
97118
98119 def _update_rate_limit_from_headers (self , headers : Any ) -> None :
@@ -125,7 +146,10 @@ def create_email(
125146 json_data ["domain_type" ] = domain_type .value
126147
127148 data = self ._make_request (
128- "POST" , "/v1/emails" , json_data = json_data if json_data else None
149+ "POST" ,
150+ "/v1/emails" ,
151+ json_data = json_data if json_data else None ,
152+ return_content = False ,
129153 )
130154
131155 return EmailAddress .from_json (data )
@@ -137,7 +161,7 @@ def list_domains(self) -> List[Domain]:
137161 Returns:
138162 List[Domain]: Available domains
139163 """
140- data = self ._make_request ("GET" , "/v1/domains" )
164+ data = self ._make_request ("GET" , "/v1/domains" , return_content = False )
141165
142166 return [Domain .from_json (domain ) for domain in data ["domains" ]]
143167
@@ -146,7 +170,9 @@ def list_email_messages(
146170 email : str ,
147171 ) -> List [EmailMessage ]:
148172 """Get all messages for a specific email address."""
149- data = self ._make_request ("GET" , f"/v1/emails/{ email } /messages" )
173+ data = self ._make_request (
174+ "GET" , f"/v1/emails/{ email } /messages" , return_content = False
175+ )
150176
151177 messages = []
152178 for msg_data in data ["messages" ]:
@@ -156,20 +182,24 @@ def list_email_messages(
156182
157183 def get_message (self , message_id : str ) -> EmailMessage :
158184 """Get a specific message by ID."""
159- data = self ._make_request ("GET" , f"/v1/messages/{ message_id } " )
185+ data = self ._make_request (
186+ "GET" , f"/v1/messages/{ message_id } " , return_content = False
187+ )
160188 return EmailMessage .from_json (data )
161189
162190 def delete_message (self , message_id : str ) -> None :
163191 """Delete a specific message by ID."""
164- self ._make_request ("DELETE" , f"/v1/messages/{ message_id } " )
192+ self ._make_request ("DELETE" , f"/v1/messages/{ message_id } " , return_content = False )
165193
166194 def delete_email (self , email : str ) -> None :
167195 """Delete an email address and all its messages."""
168- self ._make_request ("DELETE" , f"/v1/emails/{ email } " )
196+ self ._make_request ("DELETE" , f"/v1/emails/{ email } " , return_content = False )
169197
170198 def get_message_source_code (self , message_id : str ) -> str :
171199 """Get the raw source code of a message."""
172- data = self ._make_request ("GET" , f"/v1/messages/{ message_id } /source_code" )
200+ data = self ._make_request (
201+ "GET" , f"/v1/messages/{ message_id } /source_code" , return_content = False
202+ )
173203 return data ["data" ]
174204
175205 def download_attachment (self , attachment_id : str ) -> bytes :
@@ -184,7 +214,9 @@ def get_rate_limit(self) -> RateLimit:
184214 Get current rate limit information.
185215 :return: RateLimit object
186216 """
187- data = self ._make_request ("GET" , "/v1/rate_limit" , update_rate_limit = False )
217+ data = self ._make_request (
218+ "GET" , "/v1/rate_limit" , return_content = False , update_rate_limit = False
219+ )
188220 rate_limit : RateLimit = RateLimit .from_json (data )
189221 # Also update the last known rate limit since this method doesn't use headers
190222 self ._last_rate_limit = rate_limit
@@ -197,3 +229,16 @@ def last_rate_limit(self) -> Optional[RateLimit]:
197229 It will be None if no requests have been made yet.
198230 """
199231 return self ._last_rate_limit
232+
233+ def close (self ) -> None :
234+ """Close the underlying HTTPX client.
235+
236+ The client will *not* be usable after this.
237+ """
238+ self .client .close ()
239+
240+ def __enter__ (self ):
241+ return self
242+
243+ def __exit__ (self , exc_type , exc_val , exc_tb ) -> None :
244+ self .close ()
0 commit comments