Skip to content

Commit 753465b

Browse files
committed
Remove the parse_response parameter for the call method
1 parent 61f84e1 commit 753465b

File tree

7 files changed

+45
-58
lines changed

7 files changed

+45
-58
lines changed

src/apify_client/_http_client.py

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
from typing import TYPE_CHECKING, Any
1111

1212
import httpx
13-
from apify_shared.utils import ignore_docs, is_content_type_json, is_content_type_text, is_content_type_xml
13+
from apify_shared.utils import ignore_docs
1414

15-
from apify_client._errors import ApifyApiError, InvalidResponseBodyError, is_retryable_error
15+
from apify_client._errors import ApifyApiError, is_retryable_error
1616
from apify_client._logging import log_context, logger_name
1717
from apify_client._statistics import Statistics
1818
from apify_client._utils import retry_with_exp_backoff, retry_with_exp_backoff_async
@@ -64,25 +64,6 @@ def __init__(
6464

6565
self.stats = stats or Statistics()
6666

67-
@staticmethod
68-
def _maybe_parse_response(response: httpx.Response) -> Any:
69-
if response.status_code == HTTPStatus.NO_CONTENT:
70-
return None
71-
72-
content_type = ''
73-
if 'content-type' in response.headers:
74-
content_type = response.headers['content-type'].split(';')[0].strip()
75-
76-
try:
77-
if is_content_type_json(content_type):
78-
return response.json()
79-
elif is_content_type_xml(content_type) or is_content_type_text(content_type): # noqa: RET505
80-
return response.text
81-
else:
82-
return response.content
83-
except ValueError as err:
84-
raise InvalidResponseBodyError(response) from err
85-
8667
@staticmethod
8768
def _parse_params(params: dict | None) -> dict | None:
8869
if params is None:
@@ -143,17 +124,13 @@ def call(
143124
data: Any = None,
144125
json: JSONSerializable | None = None,
145126
stream: bool | None = None,
146-
parse_response: bool | None = True,
147127
timeout_secs: int | None = None,
148128
) -> httpx.Response:
149129
log_context.method.set(method)
150130
log_context.url.set(url)
151131

152132
self.stats.calls += 1
153133

154-
if stream and parse_response:
155-
raise ValueError('Cannot stream response and parse it at the same time!')
156-
157134
headers, params, content = self._prepare_request_call(headers, params, data, json)
158135

159136
httpx_client = self.httpx_client
@@ -190,11 +167,6 @@ def _make_request(stop_retrying: Callable, attempt: int) -> httpx.Response:
190167
# If response status is < 300, the request was successful, and we can return the result
191168
if response.status_code < 300: # noqa: PLR2004
192169
logger.debug('Request successful', extra={'status_code': response.status_code})
193-
if not stream:
194-
_maybe_parsed_body = (
195-
self._maybe_parse_response(response) if parse_response else response.content
196-
)
197-
setattr(response, '_maybe_parsed_body', _maybe_parsed_body) # noqa: B010
198170

199171
return response
200172

@@ -239,17 +211,13 @@ async def call(
239211
data: Any = None,
240212
json: JSONSerializable | None = None,
241213
stream: bool | None = None,
242-
parse_response: bool | None = True,
243214
timeout_secs: int | None = None,
244215
) -> httpx.Response:
245216
log_context.method.set(method)
246217
log_context.url.set(url)
247218

248219
self.stats.calls += 1
249220

250-
if stream and parse_response:
251-
raise ValueError('Cannot stream response and parse it at the same time!')
252-
253221
headers, params, content = self._prepare_request_call(headers, params, data, json)
254222

255223
httpx_async_client = self.httpx_async_client
@@ -283,11 +251,6 @@ async def _make_request(stop_retrying: Callable, attempt: int) -> httpx.Response
283251
# If response status is < 300, the request was successful, and we can return the result
284252
if response.status_code < 300: # noqa: PLR2004
285253
logger.debug('Request successful', extra={'status_code': response.status_code})
286-
if not stream:
287-
_maybe_parsed_body = (
288-
self._maybe_parse_response(response) if parse_response else response.content
289-
)
290-
setattr(response, '_maybe_parsed_body', _maybe_parsed_body) # noqa: B010
291254

292255
return response
293256

src/apify_client/_utils.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,21 @@
99
from http import HTTPStatus
1010
from typing import TYPE_CHECKING, Any, TypeVar, cast
1111

12-
from apify_shared.utils import is_file_or_bytes, maybe_extract_enum_member_value
12+
from apify_shared.utils import (
13+
is_content_type_json,
14+
is_content_type_text,
15+
is_content_type_xml,
16+
is_file_or_bytes,
17+
maybe_extract_enum_member_value,
18+
)
19+
20+
from apify_client._errors import InvalidResponseBodyError
1321

1422
if TYPE_CHECKING:
1523
from collections.abc import Awaitable
1624

25+
from httpx import Response
26+
1727
from apify_client._errors import ApifyApiError
1828

1929
PARSE_DATE_FIELDS_MAX_DEPTH = 3
@@ -149,3 +159,24 @@ def encode_key_value_store_record_value(value: Any, content_type: str | None = N
149159
value = json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False, default=str).encode('utf-8')
150160

151161
return (value, content_type)
162+
163+
164+
def maybe_parse_response(response: Response) -> Any:
165+
if response.status_code == HTTPStatus.NO_CONTENT:
166+
return None
167+
168+
content_type = ''
169+
if 'content-type' in response.headers:
170+
content_type = response.headers['content-type'].split(';')[0].strip()
171+
172+
try:
173+
if is_content_type_json(content_type):
174+
response_data = response.json()
175+
elif is_content_type_xml(content_type) or is_content_type_text(content_type):
176+
response_data = response.text
177+
else:
178+
response_data = response.content
179+
except ValueError as err:
180+
raise InvalidResponseBodyError(response) from err
181+
else:
182+
return response_data

src/apify_client/clients/resource_clients/dataset.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,6 @@ def get_items_as_bytes(
420420
url=self._url('items'),
421421
method='GET',
422422
params=request_params,
423-
parse_response=False,
424423
)
425424

426425
return response.content
@@ -516,7 +515,6 @@ def stream_items(
516515
method='GET',
517516
params=request_params,
518517
stream=True,
519-
parse_response=False,
520518
)
521519
yield response
522520
finally:
@@ -877,7 +875,6 @@ async def get_items_as_bytes(
877875
url=self._url('items'),
878876
method='GET',
879877
params=request_params,
880-
parse_response=False,
881878
)
882879

883880
return response.content
@@ -973,7 +970,6 @@ async def stream_items(
973970
method='GET',
974971
params=request_params,
975972
stream=True,
976-
parse_response=False,
977973
)
978974
yield response
979975
finally:

src/apify_client/clients/resource_clients/key_value_store.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
from apify_shared.utils import filter_out_none_values_recursively, ignore_docs, parse_date_fields
99

1010
from apify_client._errors import ApifyApiError
11-
from apify_client._utils import catch_not_found_or_throw, encode_key_value_store_record_value, pluck_data
11+
from apify_client._utils import (
12+
catch_not_found_or_throw,
13+
encode_key_value_store_record_value,
14+
maybe_parse_response,
15+
pluck_data,
16+
)
1217
from apify_client.clients.base import ResourceClient, ResourceClientAsync
1318

1419
if TYPE_CHECKING:
@@ -146,7 +151,7 @@ def get_record(self, key: str, *, as_bytes: bool = False, as_file: bool = False)
146151

147152
return {
148153
'key': key,
149-
'value': response._maybe_parsed_body, # type: ignore[attr-defined] # noqa: SLF001
154+
'value': maybe_parse_response(response),
150155
'content_type': response.headers['content-type'],
151156
}
152157

@@ -196,7 +201,6 @@ def get_record_as_bytes(self, key: str) -> dict | None:
196201
url=self._url(f'records/{key}'),
197202
method='GET',
198203
params=self._params(),
199-
parse_response=False,
200204
)
201205

202206
return {
@@ -228,7 +232,6 @@ def stream_record(self, key: str) -> Iterator[dict | None]:
228232
url=self._url(f'records/{key}'),
229233
method='GET',
230234
params=self._params(),
231-
parse_response=False,
232235
stream=True,
233236
)
234237

@@ -393,7 +396,7 @@ async def get_record(self, key: str) -> dict | None:
393396

394397
return {
395398
'key': key,
396-
'value': response._maybe_parsed_body, # type: ignore[attr-defined] # noqa: SLF001
399+
'value': maybe_parse_response(response),
397400
'content_type': response.headers['content-type'],
398401
}
399402

@@ -443,7 +446,6 @@ async def get_record_as_bytes(self, key: str) -> dict | None:
443446
url=self._url(f'records/{key}'),
444447
method='GET',
445448
params=self._params(),
446-
parse_response=False,
447449
)
448450

449451
return {
@@ -475,7 +477,6 @@ async def stream_record(self, key: str) -> AsyncIterator[dict | None]:
475477
url=self._url(f'records/{key}'),
476478
method='GET',
477479
params=self._params(),
478-
parse_response=False,
479480
stream=True,
480481
)
481482

src/apify_client/clients/resource_clients/log.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ def get_as_bytes(self, *, raw: bool = False) -> bytes | None:
7676
url=self.url,
7777
method='GET',
7878
params=self._params(raw=raw),
79-
parse_response=False,
8079
)
8180

8281
return response.content # noqa: TRY300
@@ -105,7 +104,6 @@ def stream(self, *, raw: bool = False) -> Iterator[httpx.Response | None]:
105104
method='GET',
106105
params=self._params(stream=True, raw=raw),
107106
stream=True,
108-
parse_response=False,
109107
)
110108

111109
yield response
@@ -166,7 +164,6 @@ async def get_as_bytes(self, *, raw: bool = False) -> bytes | None:
166164
url=self.url,
167165
method='GET',
168166
params=self._params(raw=raw),
169-
parse_response=False,
170167
)
171168

172169
return response.content # noqa: TRY300
@@ -195,7 +192,6 @@ async def stream(self, *, raw: bool = False) -> AsyncIterator[httpx.Response | N
195192
method='GET',
196193
params=self._params(stream=True, raw=raw),
197194
stream=True,
198-
parse_response=False,
199195
)
200196

201197
yield response

tests/unit/test_client_errors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_client_apify_api_error_streamed(httpserver: HTTPServer) -> None:
9292
httpserver.expect_request('/stream_error').respond_with_handler(streaming_handler)
9393

9494
with pytest.raises(ApifyApiError) as e:
95-
client.call(method='GET', url=httpserver.url_for('/stream_error'), stream=True, parse_response=False)
95+
client.call(method='GET', url=httpserver.url_for('/stream_error'), stream=True)
9696

9797
assert e.value.message == error['error']['message']
9898
assert e.value.type == error['error']['type']
@@ -108,7 +108,7 @@ async def test_async_client_apify_api_error_streamed(httpserver: HTTPServer) ->
108108
httpserver.expect_request('/stream_error').respond_with_handler(streaming_handler)
109109

110110
with pytest.raises(ApifyApiError) as e:
111-
await client.call(method='GET', url=httpserver.url_for('/stream_error'), stream=True, parse_response=False)
111+
await client.call(method='GET', url=httpserver.url_for('/stream_error'), stream=True)
112112

113113
assert e.value.message == error['error']['message']
114114
assert e.value.type == error['error']['type']

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)