Skip to content

Commit dbf483f

Browse files
authored
Disallowed NaN and Infinity values in JSONs sent to the Apify API (#87)
If you tried to push an item which contained a `NaN` to a dataset, it would return an error from the Apify API, that the JSON you sent to it is invalid. ```python >>> client.dataset('~nan-testing-dataset').push_items([{ 'a': float('NaN')}]) ApifyApiError: Cannot parse POST payload as JSON: Unexpected token N in JSON at position 7 ``` That is because in Python, by default, `json.dumps()` stringifies `NaN` and `Infinity` values. This is against the JSON standard, and `JSON.parse` on the API fails to parse the value. This fixes it by adding the `allow_nan=False` parameter to `json.dumps()`, so that the error is caught before sending the invalid JSON to the API, and throws an error early. ```python >>> client.dataset('~nan-testing-dataset').push_items([{ 'a': float('NaN')}]) ValueError: Out of range float values are not JSON compliant: nan ```
1 parent 84b3e8a commit dbf483f

File tree

3 files changed

+6
-2
lines changed

3 files changed

+6
-2
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ Changelog
2525
- added support for `origin` parameter in actor/task run methods
2626
- added clients for actor version environment variables
2727

28+
### Fixed
29+
30+
- disallowed `NaN` and `Infinity` values in JSONs sent to the Apify API
31+
2832
### Internal changes
2933

3034
- simplified retrying with exponential backoff

src/apify_client/_http_client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def _prepare_request_call(
100100

101101
# dump JSON data to string, so they can be gzipped
102102
if json:
103-
data = jsonlib.dumps(json, ensure_ascii=False, default=str).encode('utf-8')
103+
data = jsonlib.dumps(json, ensure_ascii=False, allow_nan=False, default=str).encode('utf-8')
104104
headers['Content-Type'] = 'application/json'
105105

106106
if isinstance(data, (str, bytes, bytearray)):

src/apify_client/_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def _encode_key_value_store_record_value(value: Any, content_type: Optional[str]
211211
content_type = 'application/json; charset=utf-8'
212212

213213
if 'application/json' in content_type and not _is_file_or_bytes(value) and not isinstance(value, str):
214-
value = json.dumps(value, ensure_ascii=False, indent=2, default=str).encode('utf-8')
214+
value = json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False, default=str).encode('utf-8')
215215

216216
return (value, content_type)
217217

0 commit comments

Comments
 (0)