Skip to content

Commit 26fccba

Browse files
committed
Use custom response type in exceptions, to avoid needing to use requests' API to handle exceptions, and to avoid relying on requests's types which are incomplete
1 parent 5d60a44 commit 26fccba

File tree

9 files changed

+59
-19
lines changed

9 files changed

+59
-19
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lint: \
1717
pip-missing-reqs \
1818
pyproject-fmt \
1919
pyright \
20+
pyright-verifytypes \
2021
pyroma \
2122
spelling \
2223
vulture \

docs/source/api-reference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ API Reference
55
:undoc-members:
66
:members:
77

8+
.. automodule:: vws.exceptions.response
9+
:undoc-members:
10+
:members:
11+
812
.. automodule:: vws.reports
913
:undoc-members:
1014
:members:

lint.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ pyroma:
4848
pyright:
4949
pyright .
5050

51+
.PHONY: pyright-verifytypes
52+
pyright-verifytypes:
53+
pyright --verifytypes vws
54+
5155
.PHONY: vulture
5256
vulture:
5357
vulture --min-confidence 100 --exclude _vendor --exclude .eggs .

src/vws/exceptions/base_exceptions.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55

66
from __future__ import annotations
77

8-
from typing import TYPE_CHECKING
9-
10-
if TYPE_CHECKING:
11-
from requests import Response
8+
from .response import Response
129

1310

1411
class CloudRecoException(Exception):

src/vws/exceptions/custom_exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""
66

77

8-
from requests import Response
8+
from .response import Response
99

1010

1111
class OopsAnErrorOccurredPossiblyBadName(Exception):

src/vws/exceptions/response.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""Responses for exceptions."""
2+
3+
from dataclasses import dataclass
4+
5+
6+
@dataclass
7+
class Response:
8+
"""
9+
A response from a request.
10+
"""
11+
12+
text: str
13+
url: str
14+
status_code: int
15+
headers: dict[str, str]
16+
request_body: bytes | str | None

src/vws/exceptions/vws_exceptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ def target_name(self) -> str:
137137
"""
138138
The target name which already exists.
139139
"""
140-
response_body = self.response.request.body or b""
141-
request_json = json.loads(response_body)
140+
response_body = self.response.request_body or b""
141+
request_json = json.loads(s=response_body)
142142
return str(request_json["name"])
143143

144144

src/vws/query.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from __future__ import annotations
66

77
import datetime
8+
import json
89
from http import HTTPStatus
910
from typing import Any, BinaryIO
1011
from urllib.parse import urljoin
@@ -24,6 +25,7 @@
2425
RequestEntityTooLarge,
2526
ServerError,
2627
)
28+
from vws.exceptions.response import Response
2729
from vws.include_target_data import CloudRecoIncludeTargetData
2830
from vws.reports import QueryResult, TargetData
2931

@@ -133,14 +135,21 @@ def query(
133135
"Content-Type": content_type_header,
134136
}
135137

136-
response = requests.request(
138+
requests_response = requests.request(
137139
method=method,
138140
url=urljoin(base=self._base_vwq_url, url=request_path),
139141
headers=headers,
140142
data=content,
141143
# We should make the timeout customizable.
142144
timeout=None,
143145
)
146+
response = Response(
147+
text=requests_response.text,
148+
url=requests_response.url,
149+
status_code=requests_response.status_code,
150+
headers=dict(requests_response.headers),
151+
request_body=requests_response.request.body,
152+
)
144153

145154
if response.status_code == HTTPStatus.REQUEST_ENTITY_TOO_LARGE:
146155
raise RequestEntityTooLarge
@@ -153,7 +162,7 @@ def query(
153162
): # pragma: no cover
154163
raise ServerError(response=response)
155164

156-
result_code = response.json()["result_code"]
165+
result_code = json.loads(s=response.text)["result_code"]
157166
if result_code != "Success":
158167
exception = {
159168
"AuthenticationFailure": AuthenticationFailure,
@@ -164,7 +173,7 @@ def query(
164173
raise exception(response=response)
165174

166175
result: list[QueryResult] = []
167-
result_list = list(response.json()["results"])
176+
result_list = list(json.loads(s=response.text)["results"])
168177
for item in result_list:
169178
target_data: TargetData | None = None
170179
if "target_data" in item:

src/vws/vws.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from urllib.parse import urljoin
1414

1515
import requests
16-
from requests import Response
1716
from vws_auth_tools import authorization_header, rfc_1123_date
1817

1918
from vws.exceptions.custom_exceptions import (
@@ -48,6 +47,8 @@
4847
TargetSummaryReport,
4948
)
5049

50+
from .exceptions.response import Response
51+
5152
if TYPE_CHECKING:
5253
import io
5354

@@ -107,7 +108,7 @@ def _target_api_request(
107108

108109
url = urljoin(base=base_vws_url, url=request_path)
109110

110-
return requests.request(
111+
requests_response = requests.request(
111112
method=method,
112113
url=url,
113114
headers=headers,
@@ -116,6 +117,14 @@ def _target_api_request(
116117
timeout=None,
117118
)
118119

120+
return Response(
121+
text=requests_response.text,
122+
url=requests_response.url,
123+
status_code=requests_response.status_code,
124+
headers=dict(requests_response.headers),
125+
request_body=requests_response.request.body,
126+
)
127+
119128

120129
class VWS:
121130
"""
@@ -198,7 +207,7 @@ def _make_request(
198207
): # pragma: no cover
199208
raise ServerError(response=response)
200209

201-
result_code = response.json()["result_code"]
210+
result_code = json.loads(s=response.text)["result_code"]
202211

203212
if result_code == expected_result_code:
204213
return response
@@ -303,7 +312,7 @@ def add_target(
303312
expected_result_code="TargetCreated",
304313
)
305314

306-
return str(response.json()["target_id"])
315+
return str(json.loads(response.text)["target_id"])
307316

308317
def get_target_record(self, target_id: str) -> TargetStatusAndRecord:
309318
"""
@@ -340,7 +349,7 @@ def get_target_record(self, target_id: str) -> TargetStatusAndRecord:
340349
expected_result_code="Success",
341350
)
342351

343-
result_data = response.json()
352+
result_data = json.loads(s=response.text)
344353
status = TargetStatuses(result_data["status"])
345354
target_record_dict = dict(result_data["target_record"])
346355
target_record = TargetRecord(
@@ -436,7 +445,7 @@ def list_targets(self) -> list[str]:
436445
expected_result_code="Success",
437446
)
438447

439-
return list(response.json()["results"])
448+
return list(json.loads(response.text)["results"])
440449

441450
def get_target_summary_report(self, target_id: str) -> TargetSummaryReport:
442451
"""
@@ -473,7 +482,7 @@ def get_target_summary_report(self, target_id: str) -> TargetSummaryReport:
473482
expected_result_code="Success",
474483
)
475484

476-
result_data = dict(response.json())
485+
result_data = dict(json.loads(response.text))
477486
return TargetSummaryReport(
478487
status=TargetStatuses(result_data["status"]),
479488
database_name=result_data["database_name"],
@@ -516,7 +525,7 @@ def get_database_summary_report(self) -> DatabaseSummaryReport:
516525
expected_result_code="Success",
517526
)
518527

519-
response_data = dict(response.json())
528+
response_data = dict(json.loads(response.text))
520529
return DatabaseSummaryReport(
521530
active_images=response_data["active_images"],
522531
current_month_recos=response_data["current_month_recos"],
@@ -603,7 +612,7 @@ def get_duplicate_targets(self, target_id: str) -> list[str]:
603612
expected_result_code="Success",
604613
)
605614

606-
return list(response.json()["similar_targets"])
615+
return list(json.loads(s=response.text)["similar_targets"])
607616

608617
def update_target(
609618
self,

0 commit comments

Comments
 (0)