kiba-core 0.5.3.dev59__tar.gz → 0.5.3.dev60__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/json_util.py +11 -20
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/kiba_core.egg-info/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/pyproject.toml +1 -1
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_json_util.py +49 -6
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/.github/pull_request_template.md +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/.github/workflows/deploy.yml +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/.github/workflows/pull-request.yml +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/.github/workflows/release.yml +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/.gitignore +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/CHANGELOG.md +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/Dockerfile +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/README.md +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/api_request.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/api_response.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/authorizer.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/default_routes.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/health.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/json_route.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/database_connection_middleware.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/logging_middleware.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/server_headers_middleware.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/aws_requester.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/caching/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/caching/cache.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/caching/dict_cache.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/caching/file_cache.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/exceptions.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/http/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/http/basic_authentication.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/http/jwt.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/http/rest_method.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/logging.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/notifications/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/notifications/discord_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/notifications/notification_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/notifications/slack_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/py.typed +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/aqs.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/cosmos.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/message_queue.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/message_queue_processor.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/model.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/sql.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/queues/sqs.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/requester/requester.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/s3_manager.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/service_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/store/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/store/database.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/store/retriever.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/store/saver.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/async_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/chain_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/date_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/dict_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/file_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/hashing_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/http_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/list_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/string_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/typing_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/url_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/util/value_holder.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/web3/eth_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/web3/multicall3.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/kiba_core.egg-info/SOURCES.txt +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/kiba_core.egg-info/dependency_links.txt +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/kiba_core.egg-info/requires.txt +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/kiba_core.egg-info/top_level.txt +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/makefile +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/setup.cfg +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_api_response.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_authorizer.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_json_route.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/caching/test_dict_cache.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/caching/test_file_cache.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/requester/test_requester.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/test_database.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/test_exceptions.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_async_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_chain_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_date_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_dict_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_file_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_list_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_string_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/util/test_url_util.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/web3/test_rest_eth_client.py +0 -0
- {kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/uv.lock +0 -0
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
import json
|
|
3
1
|
import typing
|
|
4
2
|
from typing import Any
|
|
5
3
|
|
|
6
4
|
import orjson
|
|
5
|
+
import pydantic_core
|
|
7
6
|
|
|
8
7
|
from core import logging
|
|
9
8
|
from core.exceptions import KibaException
|
|
10
|
-
from core.util import date_util
|
|
11
9
|
from core.util.typing_util import Json
|
|
12
10
|
|
|
13
11
|
|
|
@@ -22,28 +20,19 @@ class JsonEncodeException(KibaException):
|
|
|
22
20
|
_HAS_LOGGED_FOR_SERIALIZATION_ERROR = False
|
|
23
21
|
|
|
24
22
|
|
|
25
|
-
class DatetimeEncoder(json.JSONEncoder):
|
|
26
|
-
def default(self, o: typing.Any) -> str: # type: ignore[explicit-any]
|
|
27
|
-
if isinstance(o, datetime.datetime):
|
|
28
|
-
return date_util.datetime_to_string(o)
|
|
29
|
-
try:
|
|
30
|
-
return typing.cast(str, super().default(o))
|
|
31
|
-
except TypeError:
|
|
32
|
-
return str(o)
|
|
33
|
-
|
|
34
|
-
|
|
35
23
|
def dumpb(obj: Any) -> bytes: # type: ignore[explicit-any]
|
|
36
24
|
global _HAS_LOGGED_FOR_SERIALIZATION_ERROR # noqa: PLW0603
|
|
37
25
|
try:
|
|
38
|
-
|
|
26
|
+
# NOTE(krishan711): Keep UTC datetime output aligned with pydantic's ISO 8601 format.
|
|
27
|
+
return orjson.dumps(obj, option=orjson.OPT_UTC_Z)
|
|
39
28
|
except TypeError as exception:
|
|
40
29
|
if str(exception) == 'Integer exceeds 64-bit range':
|
|
41
30
|
if not _HAS_LOGGED_FOR_SERIALIZATION_ERROR:
|
|
42
|
-
logging.warning(f'There was an error during the serialization an object: `{exception}`, falling back to
|
|
31
|
+
logging.warning(f'There was an error during the serialization an object: `{exception}`, falling back to pydantic.')
|
|
43
32
|
_HAS_LOGGED_FOR_SERIALIZATION_ERROR = True
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
33
|
+
# NOTE(krishan711): orjson is faster, but doesnt support ints bigger than 64bit
|
|
34
|
+
# so we use pydantic instead (still faster than python json)
|
|
35
|
+
return pydantic_core.to_json(obj, fallback=str, inf_nan_mode='null')
|
|
47
36
|
raise JsonEncodeException(message=str(exception)) from exception
|
|
48
37
|
|
|
49
38
|
|
|
@@ -53,6 +42,8 @@ def dumps(obj: Any) -> str: # type: ignore[explicit-any]
|
|
|
53
42
|
|
|
54
43
|
def loads(json: str | bytes | bytearray) -> Json:
|
|
55
44
|
try:
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
# NOTE(krishan711): orjson is faster, but doesnt support ints bigger than 64bit
|
|
46
|
+
# so we use pydantic instead (still faster than python json)
|
|
47
|
+
return typing.cast(Json, pydantic_core.from_json(json, allow_inf_nan=False))
|
|
48
|
+
except ValueError as exception:
|
|
58
49
|
raise JsonDecodeException(message=str(exception)) from exception
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import math
|
|
3
|
+
|
|
1
4
|
import pytest
|
|
2
5
|
|
|
3
6
|
from core.util import json_util
|
|
@@ -154,9 +157,49 @@ class TestJsonUtil:
|
|
|
154
157
|
assert isinstance(result, bytes)
|
|
155
158
|
assert result == b'11111111111111111111111'
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
def test_dumpb_and_loads_with_very_long_integer(self):
|
|
161
|
+
veryLongInteger = 11111111111111111111111
|
|
162
|
+
result = json_util.dumpb(obj=veryLongInteger)
|
|
163
|
+
assert isinstance(result, bytes)
|
|
164
|
+
assert int(json_util.loads(result)) == veryLongInteger
|
|
165
|
+
|
|
166
|
+
def test_dumpb_with_very_long_integer_and_datetime(self):
|
|
167
|
+
veryLongInteger = 25000000000000000001
|
|
168
|
+
naiveDatetime = datetime.datetime.fromisoformat('2024-01-02T03:04:05.678901')
|
|
169
|
+
utcDatetime = datetime.datetime(2024, 1, 2, 3, 4, 5, 678901, tzinfo=datetime.UTC)
|
|
170
|
+
result = json_util.dumpb({
|
|
171
|
+
'balance': veryLongInteger,
|
|
172
|
+
'naive': naiveDatetime,
|
|
173
|
+
'utc': utcDatetime,
|
|
174
|
+
})
|
|
175
|
+
assert result == b'{"balance":25000000000000000001,"naive":"2024-01-02T03:04:05.678901","utc":"2024-01-02T03:04:05.678901Z"}'
|
|
176
|
+
|
|
177
|
+
def test_dumpb_with_utc_datetime_matches_pydantic_fallback(self):
|
|
178
|
+
utcDatetime = datetime.datetime(2024, 1, 2, 3, 4, 5, 678901, tzinfo=datetime.UTC)
|
|
179
|
+
assert json_util.dumpb(utcDatetime) == b'"2024-01-02T03:04:05.678901Z"'
|
|
180
|
+
|
|
181
|
+
def test_dumpb_with_very_long_integer_uses_pydantic_fallbacks(self):
|
|
182
|
+
veryLongInteger = 25000000000000000001
|
|
183
|
+
|
|
184
|
+
class TestObject:
|
|
185
|
+
def __str__(self):
|
|
186
|
+
return 'test-object'
|
|
187
|
+
|
|
188
|
+
result = json_util.dumpb({
|
|
189
|
+
'balance': veryLongInteger,
|
|
190
|
+
'unknown': TestObject(),
|
|
191
|
+
'not_a_number': math.nan,
|
|
192
|
+
})
|
|
193
|
+
assert result == b'{"balance":25000000000000000001,"unknown":"test-object","not_a_number":null}'
|
|
194
|
+
|
|
195
|
+
def test_loads_preserves_large_integer_type_and_precision(self):
|
|
196
|
+
value = 25000000000000000001
|
|
197
|
+
decoded = json_util.loads(str(value))
|
|
198
|
+
assert type(decoded) is int
|
|
199
|
+
assert decoded == value
|
|
200
|
+
|
|
201
|
+
def test_loads_preserves_nested_large_integer_type_and_precision(self):
|
|
202
|
+
value = 25000000000000000001
|
|
203
|
+
decoded = json_util.loads(f'{{"balance": {value}}}')
|
|
204
|
+
assert type(decoded['balance']) is int
|
|
205
|
+
assert decoded['balance'] == value
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/exception_handling_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/core/api/middleware/server_headers_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev59 → kiba_core-0.5.3.dev60}/tests/api/test_exception_handling_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|