Skip to content

Commit

Permalink
Improve AsyncClientBase (#3)
Browse files Browse the repository at this point in the history
Improve AsyncClientBase

Handle properly non-successful codes and connection retries.
  • Loading branch information
akalex authored Dec 9, 2022
1 parent 04428bf commit 9e982d4
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 165 deletions.
9 changes: 7 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Changelog

## 0.3.0

- ``AsyncClientBase`` has been adjusted to handle properly non-successful codes and connection retries.
- Class ``SendEmailRequest`` has been updated with type annotations.

## 0.2.0

* `README.md` has been updated with examples of how to use.
- `README.md` has been updated with examples of how to use.

## 0.1.0

* First release on PyPI.
- First release on PyPI.
25 changes: 16 additions & 9 deletions async_customerio/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,42 @@
import base64
import typing as t

from typing_extensions import TypedDict

from async_customerio.client_base import AsyncClientBase
from async_customerio.errors import AsyncCustomerIOError
from async_customerio.regions import Region, Regions
from async_customerio.utils import join_url


IdentifierID = TypedDict("IdentifierID", {"id": t.Union[str, int]})
IdentifierEMAIL = TypedDict("IdentifierEMAIL", {"email": str})
IdentifierCIOID = TypedDict("IdentifierCIOID", {"cio_id": t.Union[str, int]})


class SendEmailRequest:
"""An object with all the options available for triggering a transactional message"""

def __init__(
self,
transactional_message_id: t.Union[str, int] = None,
to: str = None,
identifiers=None,
identifiers: t.Union[IdentifierID, IdentifierEMAIL, IdentifierCIOID] = None,
_from: str = None,
headers=None,
headers: t.Dict[str, str] = None,
reply_to: str = None,
bcc=None,
bcc: str = None,
subject: str = None,
preheader=None,
body=None,
preheader: str = None,
body: str = None,
plaintext_body: str = None,
amp_body=None,
fake_bcc=None,
amp_body: str = None,
fake_bcc: str = None,
disable_message_retention: bool = None,
send_to_unsubscribed: bool = None,
tracked: bool = None,
queue_draft=None,
message_data=None,
queue_draft: bool = None,
message_data: dict = None,
attachments: t.Dict[str, str] = None,
):

Expand Down
27 changes: 22 additions & 5 deletions async_customerio/client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@
import httpx

import pkg_resources
from async_customerio.errors import AsyncCustomerIOError
from async_customerio.utils import sanitize


CUSTOMERIO_UNAVAILABLE_MESSAGE = """Failed to receive valid response after {count} retries.
Check system status at http://status.customer.io.
Last caught exception -- {klass}: {message}
"""


class AsyncClientBase:
def __init__(self, retries: int = 3, timeout: int = 10):
self.timeout = timeout
Expand All @@ -37,7 +44,7 @@ async def send_request(
*,
json_payload: t.Dict[str, t.Any] = None,
headers: t.Dict[str, str] = None,
auth: t.Optional[t.Tuple[str, str]] = None
auth: t.Optional[t.Tuple[str, str]] = None,
) -> t.Union[dict]:
"""
Sends an HTTP call using the ``httpx`` library.
Expand All @@ -63,10 +70,20 @@ async def send_request(
json_payload,
headers,
)
raw_cio_response: httpx.Response = await client.request(
method, url, json=json_payload and sanitize(json_payload), headers=merged_headers
)
raw_cio_response.raise_for_status()
try:
raw_cio_response: httpx.Response = await client.request(
method, url, json=json_payload and sanitize(json_payload), headers=merged_headers
)
result_status = raw_cio_response.status_code
if result_status != 200:
raise AsyncCustomerIOError(f"{result_status}: {url} {json_payload} {raw_cio_response.text}")
except Exception as err:
# Raise exception alerting user that the system might be
# experiencing an outage and refer them to system status page.
raise AsyncCustomerIOError(
CUSTOMERIO_UNAVAILABLE_MESSAGE.format(klass=type(err), message=err, count=self.retries)
)

logging.debug(
"Response Code: %s, Time spent to make a request: %s",
raw_cio_response.status_code,
Expand Down
Loading

0 comments on commit 9e982d4

Please sign in to comment.