Skip to content

Commit 85288cf

Browse files
committed
added toJSON
1 parent 32445d6 commit 85288cf

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

tronapi/base/encoding.py

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1+
import json
12
import re
23
from typing import Union
34

4-
from eth_utils import hexstr_if_str, to_hex, big_endian_to_int, int_to_big_endian
5+
from hexbytes import HexBytes
6+
7+
from eth_utils import (
8+
hexstr_if_str,
9+
to_hex,
10+
big_endian_to_int,
11+
int_to_big_endian
12+
)
513

614
from tronapi.utils.hexadecimal import (
715
remove_0x_prefix,
@@ -11,10 +19,16 @@
1119
)
1220

1321
from tronapi.base.toolz import (
14-
curry,
22+
curry
1523
)
1624

17-
from tronapi.utils.types import is_boolean, is_integer
25+
from tronapi.utils.types import (
26+
is_boolean,
27+
is_integer,
28+
is_list_like
29+
)
30+
31+
from tronapi.base.datastructures import AttributeDict
1832
from tronapi.utils.validation import assert_one_val
1933

2034

@@ -129,3 +143,71 @@ def to_4byte_hex(hex_or_str_or_bytes: Union[int, str, bytes]) -> str:
129143
)
130144
hex_str = encode_hex(byte_str)
131145
return pad_hex(hex_str, size_of_4bytes)
146+
147+
148+
class FriendlyJsonSerialize:
149+
"""
150+
Friendly JSON serializer & deserializer
151+
When encoding or decoding fails, this class collects
152+
information on which fields failed, to show more
153+
helpful information in the raised error messages.
154+
"""
155+
156+
def _json_mapping_errors(self, mapping):
157+
for key, val in mapping.items():
158+
try:
159+
self._friendly_json_encode(val)
160+
except TypeError as exc:
161+
yield "%r: because (%s)" % (key, exc)
162+
163+
def _json_list_errors(self, iterable):
164+
for index, element in enumerate(iterable):
165+
try:
166+
self._friendly_json_encode(element)
167+
except TypeError as exc:
168+
yield "%d: because (%s)" % (index, exc)
169+
170+
def _friendly_json_encode(self, obj, cls=None):
171+
try:
172+
encoded = json.dumps(obj, cls=cls)
173+
return encoded
174+
except TypeError as full_exception:
175+
if hasattr(obj, 'items'):
176+
item_errors = '; '.join(self._json_mapping_errors(obj))
177+
raise TypeError("dict had unencodable value at keys: {{{}}}".format(item_errors))
178+
elif is_list_like(obj):
179+
element_errors = '; '.join(self._json_list_errors(obj))
180+
raise TypeError("list had unencodable value at index: [{}]".format(element_errors))
181+
else:
182+
raise full_exception
183+
184+
@staticmethod
185+
def json_decode(json_str):
186+
try:
187+
decoded = json.loads(json_str)
188+
return decoded
189+
except json.decoder.JSONDecodeError as exc:
190+
err_msg = 'Could not decode {} because of {}.'.format(repr(json_str), exc)
191+
# Calling code may rely on catching JSONDecodeError to recognize bad json
192+
# so we have to re-raise the same type.
193+
raise json.decoder.JSONDecodeError(err_msg, exc.doc, exc.pos)
194+
195+
def json_encode(self, obj, cls=None):
196+
try:
197+
return self._friendly_json_encode(obj, cls=cls)
198+
except TypeError as exc:
199+
raise TypeError("Could not encode to JSON: {}".format(exc))
200+
201+
202+
class TronJsonEncoder(json.JSONEncoder):
203+
def default(self, obj):
204+
if isinstance(obj, AttributeDict):
205+
return {k: v for k, v in obj.items()}
206+
if isinstance(obj, HexBytes):
207+
return obj.hex()
208+
return json.JSONEncoder.default(self, obj)
209+
210+
211+
def to_json(obj: object) -> object:
212+
"""Convert a complex object (like a transaction object) to a JSON string"""
213+
return FriendlyJsonSerialize().json_encode(obj, cls=TronJsonEncoder)

tronapi/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
from tronapi.base.encoding import (
2525
to_bytes,
2626
to_int,
27-
to_text
27+
to_text,
28+
to_json
2829
)
2930

3031
from tronapi.exceptions import InvalidTronError, TronError
@@ -55,6 +56,7 @@ class Tron:
5556
toInt = staticmethod(to_int)
5657
toHex = staticmethod(to_hex)
5758
toText = staticmethod(to_text)
59+
toJSON = staticmethod(to_json)
5860

5961
# Currency Utility
6062
toSun = staticmethod(to_sun)

0 commit comments

Comments
 (0)