Skip to content

Commit 2118c10

Browse files
committed
fix: misc fixes
1 parent 4665e82 commit 2118c10

7 files changed

Lines changed: 37 additions & 28 deletions

File tree

examples/simple_email_async.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
import os
33

44
import resend
5-
from resend import HTTPXClient
65

76
if not os.environ["RESEND_API_KEY"]:
87
raise EnvironmentError("RESEND_API_KEY is missing")
98

109
# Set up async HTTP client
11-
resend.default_http_client = HTTPXClient()
10+
resend.default_http_client = resend.HTTPXClient()
1211

1312
params: resend.Emails.SendParams = {
1413
"from": "onboarding@resend.dev",
@@ -25,7 +24,7 @@
2524
}
2625

2726

28-
async def main():
27+
async def main() -> None:
2928
# Without Idempotency Key
3029
email_non_idempotent: resend.Email = await resend.Emails.send_async(params)
3130
print(f"Sent email without idempotency key: {email_non_idempotent['id']}")
@@ -37,7 +36,9 @@ async def main():
3736
email_idempotent: resend.Email = await resend.Emails.send_async(params, options)
3837
print(f"Sent email with idempotency key: {email_idempotent['id']}")
3938

40-
email_resp: resend.Email = await resend.Emails.get_async(email_id=email_non_idempotent["id"])
39+
email_resp: resend.Email = await resend.Emails.get_async(
40+
email_id=email_non_idempotent["id"]
41+
)
4142
print(f"Retrieved email: {email_resp['id']}")
4243
print("Email ID: ", email_resp["id"])
4344
print("Email from: ", email_resp["from"])
@@ -51,4 +52,4 @@ async def main():
5152

5253

5354
if __name__ == "__main__":
54-
asyncio.run(main())
55+
asyncio.run(main())

resend/__init__.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from typing import Union
23

34
from .api_keys._api_key import ApiKey
45
from .api_keys._api_keys import ApiKeys
@@ -16,25 +17,24 @@
1617
from .emails._emails import Emails
1718
from .emails._tag import Tag
1819
from .http_client import HTTPClient
20+
from .http_client_async import \
21+
AsyncHTTPClient # Okay to import AsyncHTTPClient since it is just an interface.
1922
from .http_client_requests import RequestsClient
2023
from .request import Request
21-
22-
# Async imports (optional - only available with pip install resend[async])
23-
try:
24-
from .http_client_async import AsyncHTTPClient
25-
from .http_client_httpx import HTTPXClient
26-
from .async_request import AsyncRequest
27-
except ImportError:
28-
# Async classes not available without httpx dependency
29-
pass
3024
from .version import __version__, get_version
3125

26+
# Type for clients that support both sync and async
27+
ResendHTTPClient = Union[HTTPClient, AsyncHTTPClient]
28+
29+
# This is the client that is set by default HTTP Client
30+
# But this can be overridden by the user and set to an async client.
31+
default_http_client: ResendHTTPClient = RequestsClient()
32+
33+
3234
# Config vars
3335
api_key = os.environ.get("RESEND_API_KEY")
3436
api_url = os.environ.get("RESEND_API_URL", "https://api.resend.com")
3537

36-
# HTTP Client
37-
default_http_client: HTTPClient = RequestsClient()
3838

3939
# API resources
4040
from .emails._emails import Emails # noqa
@@ -66,11 +66,9 @@
6666

6767
# Add async exports if available
6868
try:
69-
from .http_client_httpx import HTTPXClient
70-
__all__.extend([
71-
"AsyncHTTPClient",
72-
"HTTPXClient",
73-
"AsyncRequest"
74-
])
69+
from .async_request import AsyncRequest # noqa: F401
70+
from .http_client_httpx import HTTPXClient # noqa: F401
71+
72+
__all__.extend(["AsyncHTTPClient", "HTTPXClient", "AsyncRequest"])
7573
except ImportError:
7674
pass

resend/async_request.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import resend
77
from resend.exceptions import (NoContentError, ResendError,
88
raise_for_code_and_type)
9+
from resend.http_client_async import AsyncHTTPClient
910
from resend.version import get_version
1011

1112
RequestVerb = Literal["get", "post", "put", "patch", "delete"]
@@ -71,7 +72,9 @@ async def make_request(self, url: str) -> Union[Dict[str, Any], List[Any]]:
7172
json_params = None
7273

7374
try:
74-
content, _status_code, resp_headers = await resend.default_http_client.request(
75+
# Cast to AsyncHTTPClient for type checking - user must set HTTPXClient
76+
async_client = cast(AsyncHTTPClient, resend.default_http_client)
77+
content, _status_code, resp_headers = await async_client.request(
7578
method=self.verb,
7679
url=url,
7780
headers=headers,
@@ -105,4 +108,4 @@ async def make_request(self, url: str) -> Union[Dict[str, Any], List[Any]]:
105108
code=500,
106109
message="Failed to decode JSON response",
107110
error_type="InternalServerError",
108-
)
111+
)

resend/emails/_emails.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ def update(cls, params: UpdateParams) -> UpdateEmailResponse:
256256
return resp
257257

258258
@classmethod
259-
async def send_async(cls, params: SendParams, options: Optional[SendOptions] = None) -> Email:
259+
async def send_async(
260+
cls, params: SendParams, options: Optional[SendOptions] = None
261+
) -> Email:
260262
"""
261263
Send an email through the Resend Email API (async version).
262264
see more: https://resend.com/docs/api-reference/emails/send-email

resend/http_client_async.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ async def request(
1717
headers: Mapping[str, str],
1818
json: Optional[Union[Dict[str, object], List[object]]] = None,
1919
) -> Tuple[bytes, int, Mapping[str, str]]:
20-
pass
20+
pass

resend/http_client_httpx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ async def request(
3737
except httpx.RequestError as e:
3838
# This gets caught by the async request.perform() method
3939
# and raises a ResendError with the error type "HttpClientError"
40-
raise RuntimeError(f"Request failed: {e}") from e
40+
raise RuntimeError(f"Request failed: {e}") from e

resend/request.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ def make_request(self, url: str) -> Union[Dict[str, Any], List[Any]]:
7171
json_params = None
7272

7373
try:
74-
content, _status_code, resp_headers = resend.default_http_client.request(
74+
# Cast to HTTPClient for type checking - sync context expects sync client
75+
from resend.http_client import HTTPClient
76+
77+
sync_client = cast(HTTPClient, resend.default_http_client)
78+
79+
content, _status_code, resp_headers = sync_client.request(
7580
method=self.verb,
7681
url=url,
7782
headers=headers,

0 commit comments

Comments
 (0)