Skip to content

Commit 665efef

Browse files
Refactor: Use response_type in decode_response
Co-authored-by: hello <hello@def-not-hacking-the.net>
1 parent fe95248 commit 665efef

File tree

9 files changed

+30
-24
lines changed

9 files changed

+30
-24
lines changed

src/contiguity/_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ContiguityApiError(Exception):
1515
class BaseApiClient:
1616
def handle_error(self, response: Response, /, *, fail_message: str = "api request failed") -> None:
1717
if not HTTPStatus.OK <= response.status_code < HTTPStatus.MULTIPLE_CHOICES:
18-
data = decode_response(response.content, type=ErrorResponse)
18+
data = decode_response(response.content, response_type=ErrorResponse)
1919
msg = f"{fail_message}. {response.status_code} {data.error}"
2020
raise ContiguityApiError(msg)
2121

src/contiguity/_instant_messaging.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def send( # noqa: PLR0913
5353
)
5454

5555
self._client.handle_error(response, fail_message="failed to send instant message")
56-
data = decode_response(response.content, type=IMSendResponse)
56+
data = decode_response(response.content, response_type=IMSendResponse)
5757
logger.debug("successfully sent %s message to %r", self._api_path[1:], to)
5858
return data
5959

@@ -70,7 +70,7 @@ def _typing(self, *, to: str, action: Literal["start", "stop"], from_: str | Non
7070
)
7171

7272
self._client.handle_error(response, fail_message=f"failed to {action} {self._api_path[1:]} typing indicator")
73-
data = decode_response(response.content, type=IMTypingResponse)
73+
data = decode_response(response.content, response_type=IMTypingResponse)
7474
logger.debug("successfully %s %s typing indicator for %r", action, self._api_path[1:], to)
7575
return data
7676

@@ -101,7 +101,7 @@ def _reactions(
101101
)
102102

103103
self._client.handle_error(response, fail_message=f"failed to {action} {self._api_path[1:]} reaction")
104-
data = decode_response(response.content, type=IMReactionResponse)
104+
data = decode_response(response.content, response_type=IMReactionResponse)
105105
logger.debug("successfully %s %s reaction for %r", action, self._api_path[1:], to)
106106
return data
107107

src/contiguity/_response.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,22 @@ class ErrorResponse(BaseResponse):
2828
status: HTTPStatus
2929

3030

31-
def decode_response(content: bytes, /, *, type: type[T]) -> T:
32-
raw = msgspec.json.decode(content, type=RawResponse[type])
31+
def decode_response(content: bytes, /, *, response_type: type[T]) -> T:
32+
raw = msgspec.json.decode(content, type=RawResponse[response_type])
3333
metadata = ResponseMetadata(
3434
id=raw.id,
3535
timestamp=raw.timestamp,
3636
api_version=raw.api_version,
3737
object=raw.object,
3838
)
3939
data = msgspec.to_builtins(raw.data)
40+
41+
# Handle sequence types (list of structs)
42+
if isinstance(data, Sequence) and not isinstance(data, str):
43+
return msgspec.convert(data, type=response_type)
44+
45+
# Handle mapping types (single struct with metadata)
4046
if not isinstance(data, Mapping):
41-
msg = f"expected Mapping instance for 'data' field, got {_type(data)}"
47+
msg = f"expected Mapping or Sequence instance for 'data' field, got {_type(data)}"
4248
raise TypeError(msg)
43-
return msgspec.convert({**data, "metadata": metadata}, type=type)
49+
return msgspec.convert({**data, "metadata": metadata}, type=response_type)

src/contiguity/domains.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,23 @@ def register(
5959
)
6060

6161
self._client.handle_error(response, fail_message="failed to register domain")
62-
data = decode_response(response.content, type=PartialDomain)
62+
data = decode_response(response.content, response_type=PartialDomain)
6363
logger.debug("successfully registered domain %r", domain)
6464
return data
6565

6666
def list(self) -> list[PartialDomain]:
6767
response = self._client.get("/domains")
6868
self._client.handle_error(response, fail_message="failed to list domains")
69-
return decode_response(response.content, type=list[PartialDomain])
69+
return decode_response(response.content, response_type=list[PartialDomain])
7070

7171
def get(self, domain: str, /) -> Domain:
7272
response = self._client.get(f"/domains/{domain}")
7373
self._client.handle_error(response, fail_message="failed to get domain")
74-
return decode_response(response.content, type=Domain)
74+
return decode_response(response.content, response_type=Domain)
7575

7676
def delete(self, domain: str, /) -> DeleteDomainResponse:
7777
response = self._client.delete(f"/domains/{domain}")
7878
self._client.handle_error(response, fail_message="failed to delete domain")
79-
data = decode_response(response.content, type=DeleteDomainResponse)
79+
data = decode_response(response.content, response_type=DeleteDomainResponse)
8080
logger.debug("successfully deleted domain %r", domain)
8181
return data

src/contiguity/email.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,6 @@ def email( # noqa: PLR0913
9595
)
9696

9797
self._client.handle_error(response, fail_message="failed to send email")
98-
data = decode_response(response.content, type=EmailResponse)
98+
data = decode_response(response.content, response_type=EmailResponse)
9999
logger.debug("successfully sent email to %r", to)
100100
return data

src/contiguity/imessage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def mark_read(self, *, to: str, from_: str) -> ReadResponse:
9292
)
9393

9494
self._client.handle_error(response, fail_message="failed to send instant message")
95-
data = decode_response(response.content, type=ReadResponse)
95+
data = decode_response(response.content, response_type=ReadResponse)
9696
logger.debug("successfully sent %s read receipt to %r", self._api_path[1:], to)
9797
return data
9898

@@ -102,4 +102,4 @@ def get_history(self, *, to: str, from_: str, limit: int = 20) -> History:
102102
)
103103

104104
self._client.handle_error(response, fail_message="failed to get message history")
105-
return decode_response(response.content, type=History)
105+
return decode_response(response.content, response_type=History)

src/contiguity/leases.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,17 @@ class Leases(BaseProduct):
8181
def get_available_numbers(self) -> list[NumberDetails]:
8282
response = self._client.get("/leases")
8383
self._client.handle_error(response, fail_message="failed to get available numbers")
84-
return decode_response(response.content, type=list[NumberDetails])
84+
return decode_response(response.content, response_type=list[NumberDetails])
8585

8686
def get_leased_numbers(self) -> list[NumberDetails]:
8787
response = self._client.get("/leased")
8888
self._client.handle_error(response, fail_message="failed to get leased numbers")
89-
return decode_response(response.content, type=list[NumberDetails])
89+
return decode_response(response.content, response_type=list[NumberDetails])
9090

9191
def get_number_details(self, number: str, /) -> NumberDetails:
9292
response = self._client.get(f"/lease/{number}")
9393
self._client.handle_error(response, fail_message="failed to get number details")
94-
return decode_response(response.content, type=NumberDetails)
94+
return decode_response(response.content, response_type=NumberDetails)
9595

9696
def lease_number(
9797
self,
@@ -106,10 +106,10 @@ def lease_number(
106106
json={"billing_method": billing_method},
107107
)
108108
self._client.handle_error(response, fail_message="failed to lease number")
109-
return decode_response(response.content, type=NumberDetails)
109+
return decode_response(response.content, response_type=NumberDetails)
110110

111111
def terminate_lease(self, number: NumberDetails | str, /) -> TerminateLeaseResponse:
112112
number = number.id if isinstance(number, NumberDetails) else number
113113
response = self._client.delete(f"/leased/{number}")
114114
self._client.handle_error(response, fail_message="failed to terminate lease")
115-
return decode_response(response.content, type=TerminateLeaseResponse)
115+
return decode_response(response.content, response_type=TerminateLeaseResponse)

src/contiguity/otp.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def send(
8181
)
8282

8383
self._client.handle_error(response, fail_message="failed to send OTP")
84-
data = decode_response(response.content, type=OTPSendResponse)
84+
data = decode_response(response.content, response_type=OTPSendResponse)
8585
logger.debug("successfully sent OTP %r to %r", data.otp_id, to)
8686
return data
8787

@@ -94,7 +94,7 @@ def resend(self, otp_id: str, /) -> OTPResendResponse:
9494
)
9595

9696
self._client.handle_error(response, fail_message="failed to resend OTP")
97-
data = decode_response(response.content, type=OTPResendResponse)
97+
data = decode_response(response.content, response_type=OTPResendResponse)
9898
logger.debug("successfully resent OTP %r with status: %r", otp_id, data.resent)
9999
return data
100100

@@ -108,6 +108,6 @@ def verify(self, otp: int | str, /, *, otp_id: str) -> OTPVerifyResponse:
108108
)
109109

110110
self._client.handle_error(response, fail_message="failed to verify OTP")
111-
data = decode_response(response.content, type=OTPVerifyResponse)
111+
data = decode_response(response.content, response_type=OTPVerifyResponse)
112112
logger.debug("successfully verified OTP %r with status: %r", otp_id, data.verified)
113113
return data

src/contiguity/text.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ def send(
4444
)
4545

4646
self._client.handle_error(response, fail_message="failed to send text message")
47-
data = decode_response(response.content, type=TextResponse)
47+
data = decode_response(response.content, response_type=TextResponse)
4848
logger.debug("successfully sent text to %r", to)
4949
return data

0 commit comments

Comments
 (0)