Skip to content

Commit e0cd844

Browse files
committed
v1.1.0 - Major update - return instances instead of dicts
**Data classes / objects** As many of us know, it gets tiring having to constantly type `x['balance']` when something returns a dictionary, especially when there's no IDE completion for it. To solve this problem, new classes have been written to represent SteemEngine objects, such as balances, transactions, and tokens. This allows you to access keys simply through `x.balance` instead. For backwards compatibility, the `ObjBase` parent class allows instances of these data classes to be treated like dictionaries/lists, so `x['balance']` will still work, and it will return the same format as before, while `x.balance` for example, would return the balance as a proper `Decimal` object. You can also convert the classes into dicts/lists with `dict(x)` and `list(x)`, but be aware that this uses the `raw_data` that was originally passed, so these converted objects will not have their keys casted to the appropriate Python types, unless they were casted before being passed into the class. - New module `privex.steemengine.objects` for classes designed to hold data - `ObjBase` is used as the base class for the data classes. For backwards compatibility, it allows instances of the classes to be accessed like a dictionary/list, offers `from_list` for easy conversions of `list<dict>` into their respective data classes, and also implements `__iter__` so instances can be converted using `dict(x)` and `list(x)`. - `Token` represents the data of a SteemEngine token such as name/symbol/supply - `SEBalance` represents a balance with account/symbol/balance - `SETransaction` represents a history tx with txid/timestamp/quantity etc. - `TokenMetadata` represents the `metadata` field of token data **Upgraded SteemEngineToken to use the data classes** The **SteemEngineToken** class has been updated to use the new data classes. Thanks to `ObjBase`, this should hopefully not break any existing applications, but there's always a risk. The methods that have been updated: - `list_tokens` now returns `List[Token]` instead of `List[dict]` - `get_token` now returns `Token` instead of `dict` - `get_token_balances` now returns `List[SEBalance]` instead of `List[dict]` - `list_transactions` now returns `List[SETransaction]` instead of `List[dict]` **Documentation for the new data classes** The documentation has been updated with details on how the data classes work. The documentation for **SteemEngineToken** methods have *mostly* been updated to show usage of the new data classes instead of `dict`s.
1 parent f03efc2 commit e0cd844

12 files changed

+326
-22
lines changed

docs/source/code/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
privex.steemengine.SteemEngineToken.SteemEngineToken
55
privex.steemengine.SteemEngineHistory.SteemEngineHistory
66
privex.steemengine.exceptions
7+
privex.steemengine.objects
78
tests
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Data Objects (Token/SEBalance etc.)
2+
====================================
3+
4+
.. automodule:: privex.steemengine.objects
5+
6+
7+
8+
9+
10+
11+
12+
.. rubric:: Classes
13+
14+
.. autosummary::
15+
:toctree: stubs
16+
17+
ObjBase
18+
SEBalance
19+
SETransaction
20+
Token
21+
TokenMetadata
22+
23+
24+
25+
26+
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
objects.ObjBase
2+
==================================
3+
4+
.. currentmodule:: privex.steemengine.objects
5+
6+
.. autoclass:: ObjBase
7+
8+
9+
.. automethod:: __init__
10+
11+
12+
.. rubric:: Methods
13+
14+
.. autosummary::
15+
16+
~ObjBase.__init__
17+
~ObjBase.from_list
18+
19+
20+
21+
22+
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
objects.SEBalance
2+
====================================
3+
4+
.. currentmodule:: privex.steemengine.objects
5+
6+
.. autoclass:: SEBalance
7+
8+
9+
.. automethod:: __init__
10+
11+
12+
.. rubric:: Methods
13+
14+
.. autosummary::
15+
16+
~SEBalance.__init__
17+
~SEBalance.from_list
18+
19+
20+
21+
22+
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
objects.SETransaction
2+
========================================
3+
4+
.. currentmodule:: privex.steemengine.objects
5+
6+
.. autoclass:: SETransaction
7+
8+
9+
.. automethod:: __init__
10+
11+
12+
.. rubric:: Methods
13+
14+
.. autosummary::
15+
16+
~SETransaction.__init__
17+
~SETransaction.from_list
18+
19+
20+
21+
22+
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
objects.Token
2+
================================
3+
4+
.. currentmodule:: privex.steemengine.objects
5+
6+
.. autoclass:: Token
7+
8+
9+
.. automethod:: __init__
10+
11+
12+
.. rubric:: Methods
13+
14+
.. autosummary::
15+
16+
~Token.__init__
17+
~Token.from_list
18+
19+
20+
21+
22+
23+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
objects.TokenMetadata
2+
========================================
3+
4+
.. currentmodule:: privex.steemengine.objects
5+
6+
.. autoclass:: TokenMetadata
7+
8+
9+
.. automethod:: __init__
10+
11+
12+
.. rubric:: Methods
13+
14+
.. autosummary::
15+
16+
~TokenMetadata.__init__
17+
~TokenMetadata.from_list
18+
19+
20+
21+
22+
23+

privex/steemengine/SteemEngineToken.py

+27-20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from privex.jsonrpc import SteemEngineRPC
55
from privex.steemengine import exceptions
66
from privex.steemengine.SteemEngineHistory import SteemEngineHistory
7+
from privex.steemengine.objects import SEBalance, SETransaction, Token
78
from privex.helpers import empty
89

910
log = logging.getLogger(__name__)
@@ -96,28 +97,28 @@ def custom_beem(node: Union[str, list] = "", *args, **kwargs):
9697
SteemEngineToken._steem = Steem(node, *args, **kwargs)
9798
return SteemEngineToken._steem
9899

99-
def get_balances(self, user) -> List[dict]:
100+
def get_balances(self, user) -> List[SEBalance]:
100101
"""
101102
Get all token balances for a user.
102103
103104
**Example:**
104105
105106
>>> balances = SteemEngineToken().get_balances('someguy123')
106107
>>> for bal in balances:
107-
... print(f"{bal['symbol']} balance is: {bal['balance']}")
108+
... print(f"{bal.symbol} balance is: {bal.balance}")
108109
ENG balance is: 12.345
109110
SGTK balance is: 51235
110111
STEEMP balance is: 102.437
111112
112113
:param user: Username to find all token balances for
113-
:return list<dict> balances: All balances of a user [{account:str, symbol:str, balance:str}...]
114+
:return list<SEBalance> balances: All balances of a user [{account:str, symbol:str, balance:str}...]
114115
"""
115116
log.debug('Finding all token balances for user %s', user)
116-
return self.rpc.find(
117+
return list(SEBalance.from_list(self.rpc.find(
117118
contract='tokens',
118119
table='balances',
119120
query=dict(account=user)
120-
)
121+
)))
121122

122123
def get_token_balance(self, user, symbol) -> Decimal:
123124
"""
@@ -159,22 +160,22 @@ def account_exists(self, user) -> bool:
159160
log.debug('Checking if user %s exists', user)
160161
return len(self.steem.rpc.get_account(user)) > 0
161162

162-
def list_tokens(self, limit=1000, offset=0) -> List[dict]:
163+
def list_tokens(self, limit=1000, offset=0) -> List[Token]:
163164
"""
164-
Returns a list of all tokens.
165+
Returns a list of all tokens as :class:`.Token` objects.
165166
166167
**Example:**
167168
168169
>>> for t in SteemEngineToken().list_tokens():
169-
... print(f"Token {t['symbol']} has a max supply of {t['maxSupply']} and issued by {t['issuer']}")
170+
... print(f"Token {t.symbol} has a max supply of {t.max_supply} and issued by {t.issuer}")
170171
Token ENG has a max supply of 9007199254740991 and issued by null
171172
Token STEEMP has a max supply of 1000000000000 and issued by steem-peg
172173
Token BTCP has a max supply of 1000000000000 and issued by btcpeg
173174
Token LTCP has a max supply of 1000000000000 and issued by ltcp
174175
175176
:param limit: Amount of token objects to retrieve
176177
:param offset: Amount of token objects to skip (for pagination)
177-
:return list<dict> tokens: Each list item formatted like this:
178+
:return List<Token> tokens: Each :class:`.Token` list item formatted like this:
178179
179180
.. code-block:: js
180181
@@ -190,12 +191,12 @@ def list_tokens(self, limit=1000, offset=0) -> List[dict]:
190191
}
191192
192193
"""
193-
return self.rpc.find(
194+
return list(Token.from_list(self.rpc.find(
194195
contract='tokens',
195196
table='tokens',
196197
query={},
197198
limit=limit, offset=offset
198-
)
199+
)))
199200

200201
def find_steem_tx(self, tx_data: dict, last_blocks=15) -> dict:
201202
"""
@@ -228,14 +229,14 @@ def find_steem_tx(self, tx_data: dict, last_blocks=15) -> dict:
228229
return tx
229230
return None
230231

231-
def list_transactions(self, user, symbol=None, limit=100, offset=0) -> List[dict]:
232+
def list_transactions(self, user, symbol=None, limit=100, offset=0) -> List[SETransaction]:
232233
"""
233234
Get the Steem Engine transaction history for a given account
234235
235236
**Example:**
236237
237238
>>> for tx in SteemEngineToken().list_transactions('someguy123'):
238-
... print(tx['timestamp'], tx['from'], 'sent', tx['quantity'], tx['symbol'], 'to', tx['to'])
239+
... print(tx.timestamp, tx.sender, 'sent', tx.quantity, tx.symbol, 'to', tx.to)
239240
2019-07-04T06:18:09.000Z market sent 100 SGTK to someguy123
240241
2019-07-04T01:01:15.000Z minnowsupport sent 0.924 PAL to someguy123
241242
2019-07-03T17:10:36.000Z someguy123 sent 1 BTSP to btsp
@@ -244,27 +245,32 @@ def list_transactions(self, user, symbol=None, limit=100, offset=0) -> List[dict
244245
:param str symbol: Symbol to filter by, e.g. ENG (optional)
245246
:param int limit: Return this many transactions (optional)
246247
:param int offset: Skip this many transactions (for pagination) (optional)
247-
:return List<dict> txs: A list of ``dict(block, txid, timestamp, symbol, from, from_type, to, to_type, memo, quantity)``
248+
:return List<SETransaction> txs: A list of :class:`.SETransaction` containing
249+
250+
block, txid, timestamp, symbol, sender, from_type, to, to_type, memo, quantity
251+
248252
"""
249253
symbol = None if empty(symbol) else symbol.upper()
250254
log.debug('Getting TX history for user %s, symbol %s, limit %s, offset %s', user, symbol, limit, offset)
251-
return self.history_rpc.get_history(account=user, symbol=symbol, limit=limit, offset=offset)
255+
return list(SETransaction.from_list(self.history_rpc.get_history(account=user, symbol=symbol, limit=limit, offset=offset)))
252256

253-
def get_token(self, symbol) -> dict:
257+
def get_token(self, symbol) -> Token:
254258
"""
255259
Get the token object for an individual token.
256260
257261
**Example:**
258262
259263
>>> token = SteemEngineToken().get_token('SGTK'):
260-
>>> print(token['issuer'], token['name'])
264+
>>> print(token.issuer, token.name)
261265
someguy123 SomeToken
262266
263267
264268
:param str symbol: Symbol of the token to lookup, such as 'ENG'
265-
:return dict token_data: A dictionary containing data about the token (see below)
269+
:return Token token_data: An object containing data about the token (see below)
266270
267-
Formatted like below:
271+
A :class:`.Token` object can be accessed either via attributes ``token.issuer`` or as a dict.
272+
273+
They contain the fields below:
268274
269275
.. code-block:: js
270276
@@ -282,11 +288,12 @@ def get_token(self, symbol) -> dict:
282288
:return None: If token not found, ``None`` is returned.
283289
"""
284290
log.debug('Getting token object for symbol %s', symbol)
285-
return self.rpc.findone(
291+
tk = self.rpc.findone(
286292
contract='tokens',
287293
table='tokens',
288294
query=dict(symbol=symbol.upper())
289295
)
296+
return None if empty(tk) else Token(**tk)
290297

291298
def send_token(self, symbol, from_acc, to_acc, amount: Decimal, memo="", find_tx=True) -> dict:
292299
"""

privex/steemengine/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import sys
33
from privex.steemengine.SteemEngineToken import SteemEngineToken
44
from privex.steemengine.SteemEngineHistory import SteemEngineHistory
5+
from privex.steemengine.objects import Token, TokenMetadata, SEBalance, SETransaction, ObjBase
56

67
name = 'steemengine'
78

0 commit comments

Comments
 (0)