hive-nectar 0.0.4__py3-none-any.whl → 0.0.6__py3-none-any.whl

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.

Potentially problematic release.


This version of hive-nectar might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hive-nectar
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: Unofficial Python library for HIVE
5
5
  Project-URL: Homepage, http://www.github.com/thecrazygm/hive-nectar
6
6
  Project-URL: Download, https://github.com/thecrazygm/hive-nectar/tarball/0.00.01
@@ -54,6 +54,7 @@ Requires-Dist: pycryptodomex
54
54
  Requires-Dist: requests
55
55
  Requires-Dist: ruamel-yaml
56
56
  Requires-Dist: scrypt
57
+ Requires-Dist: types-requests>=2.32.0.20250328
57
58
  Requires-Dist: websocket-client
58
59
  Description-Content-Type: text/markdown
59
60
 
@@ -4,12 +4,12 @@ nectar/amount.py,sha256=Zpk-BAoRt1QjwO32CIBmXpCBIhyU1qHm_skYPjfboXg,18235
4
4
  nectar/asciichart.py,sha256=DwPyZAqne6o9L_PPRtlw6Xj0QdOZ-aId1lpOnmbyc6Q,8828
5
5
  nectar/asset.py,sha256=spGsJmlVQeZ6-oYhcwmQKsI3gpGmrpCzimYO1Qv4MtA,2725
6
6
  nectar/block.py,sha256=7nXVaYt8_tu9TJD6Zcr4Vo3owK8Rv8VKueWygawml3U,16064
7
- nectar/blockchain.py,sha256=BBXPc3UQ5kM-sjptQnvDosIhRXCK4gN3N1mXBSi1XzQ,49061
7
+ nectar/blockchain.py,sha256=FflzDKS3ByWRnYiOOE94la6ZgJ0QHihnOpqD9qRi6_0,49159
8
8
  nectar/blockchaininstance.py,sha256=mrHuhHsR7h-becNe_bE8WieFqMFyz49s-LecmC_k134,93119
9
9
  nectar/blockchainobject.py,sha256=ZlWeOWGMoHyATgw20YfPV47OYlwuOpO75hmf0c9IC_4,7095
10
10
  nectar/blurt.py,sha256=cZoUyAdr_HdUTm8K3N-PyaFYfpBL_WmomFWeWTHbeIA,23070
11
11
  nectar/cli.py,sha256=jYi_EGZKeML7fvVX3g59uqWsUPL2e72NkxM4qFFrjLM,227475
12
- nectar/comment.py,sha256=bg-0TFHCudLX44YhQdCyAswFZfZzGJY4A4nTFbCATdA,46654
12
+ nectar/comment.py,sha256=Hqj1TL9vKCWmDnBikVG8yCl7hgAwPBfqN_pkDsjtaxo,46791
13
13
  nectar/community.py,sha256=XyxIfdpIWart70MM2ojlZTfbKcRYr6qxGcWtEQNHfuI,17990
14
14
  nectar/constants.py,sha256=lrspBwCz9BE0YZY10DMS98oPwwxgmI0LzFdlQ7v53Ig,4974
15
15
  nectar/conveyor.py,sha256=dpvaVLaR48Tn56fkCUl5MoDQDcR3eLcrIKYm6ctZkRM,11265
@@ -32,18 +32,18 @@ nectar/steem.py,sha256=JwfO-dp7HT3mVEZVunHNp87gFbdO8e1tcpXQs_MygJ8,23916
32
32
  nectar/storage.py,sha256=yYsWc12fOUKEAkSn5wKGS-wSvsac3sMVn6uzLu_pn8c,1855
33
33
  nectar/transactionbuilder.py,sha256=j5PD3Wm_w9gHnKJ1Ug3sxz3RWPclWt-MQIO5ox027X8,25443
34
34
  nectar/utils.py,sha256=OGeLuO_nYDAvcX-onrm4xjn1L0binq8Glelgg6RdlSo,18882
35
- nectar/version.py,sha256=zDwHc53iG1aFz89YrYBMzTav_0YNKmKgekD_4NBZhsE,76
35
+ nectar/version.py,sha256=x7maU-a8H7SAAs06_OW-iZAEZ1HvGWVdSaQbjWOSVBQ,76
36
36
  nectar/vote.py,sha256=sO_ukJMEcUO_WI-D2EwbAiiRLApRQ1fyiwyX7YSAiOk,20222
37
37
  nectar/wallet.py,sha256=pgbiLJbwXKMiR7EOtuVFee6s3nAdpILHVQ5iPNy7zhs,16222
38
38
  nectar/witness.py,sha256=88XYjhTRNhyu9hfIG0sm3Pg1hC9eooo3HhW5EhcaYps,23600
39
39
  nectarapi/__init__.py,sha256=c0J2Z-lHOvkSch9bZS3LVQZjKku2XxnYMZToq7OAkfI,157
40
40
  nectarapi/exceptions.py,sha256=FnS4-ywWDxEAtV65Hd-4XxAV7j1wRgtQRLIvIGxA0Xs,1824
41
- nectarapi/graphenerpc.py,sha256=H3u8ybNqa4RgWD4PqbfnEPkdCXOj1Mn3IGAyuUe4KdY,23495
41
+ nectarapi/graphenerpc.py,sha256=7woRA4CmuwqYrJU9E4LV3UdxaANHzIrKuWZPaxTcJnw,22642
42
42
  nectarapi/node.py,sha256=mjK-fMFJ2icDaOUBoiUuDU-beo3aQK0HGwt0l0pC0YQ,5456
43
43
  nectarapi/noderpc.py,sha256=FxJz1KbjU6FbNdyp7ovOSZ8TbmD_xqQclKjeBP42Jls,10093
44
44
  nectarapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  nectarapi/rpcutils.py,sha256=0nKCrEeNHFSEU3AjaOGNh-2pjc8qw4mRA9lCrBkP1FQ,2910
46
- nectarapi/version.py,sha256=zDwHc53iG1aFz89YrYBMzTav_0YNKmKgekD_4NBZhsE,76
46
+ nectarapi/version.py,sha256=x7maU-a8H7SAAs06_OW-iZAEZ1HvGWVdSaQbjWOSVBQ,76
47
47
  nectarbase/__init__.py,sha256=U18vyJDvtsto3gHN9Fp3DHlcPd954sG06duHc72pNjs,234
48
48
  nectarbase/ledgertransactions.py,sha256=97WXhNhcjNDf_XjXDD08lBMzYmvHC63oZMLRQqVNvWY,2545
49
49
  nectarbase/memo.py,sha256=_-y9bxGr1DyEaD2-twVJ5Y-1ttFD-VJLyVAYzlT2ijw,7570
@@ -54,7 +54,7 @@ nectarbase/operations.py,sha256=K-ypT0KMcRPjcoOuYyUhpRaRUv5FtAhfdc7kSqbFyCs,4762
54
54
  nectarbase/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
55
  nectarbase/signedtransactions.py,sha256=r-MRnEQDnx6U6XFPcM3hPXiDZvU6sQVx4Vv_0nZF7fs,1792
56
56
  nectarbase/transactions.py,sha256=D7TK4Pkxr1N7p0Yh2bxvdXpOuEYpLl2tWK84Pj_93c0,319
57
- nectarbase/version.py,sha256=zDwHc53iG1aFz89YrYBMzTav_0YNKmKgekD_4NBZhsE,76
57
+ nectarbase/version.py,sha256=x7maU-a8H7SAAs06_OW-iZAEZ1HvGWVdSaQbjWOSVBQ,76
58
58
  nectargrapheneapi/__init__.py,sha256=_Gxdt_qaQQwwYABHEFBuf4tMh93ItIa3HPBH9nk1PTw,151
59
59
  nectargrapheneapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  nectargraphenebase/__init__.py,sha256=PzB_0qiWfqJku5vKQs0CpkVeipPmZ33Fpc1px4VCV-Q,570
@@ -76,7 +76,7 @@ nectargraphenebase/py23.py,sha256=aI1MAQ74DngxkjdpRlWEspmB1HNTQcpj3uHKo0b7rsM,78
76
76
  nectargraphenebase/signedtransactions.py,sha256=y5tq9ijO_EXUpn77cHgqx55RcsY0Jr-lwj_r_0w7OHI,6947
77
77
  nectargraphenebase/types.py,sha256=OZGVxgOoNPLiElNyDluUpmXNyREGzCEekZwq5uwPfGE,9771
78
78
  nectargraphenebase/unsignedtransactions.py,sha256=HwhbWkWS1mYCJWKMsUI18PogEmZ5sVTWLPwolvM6ZR0,9522
79
- nectargraphenebase/version.py,sha256=zDwHc53iG1aFz89YrYBMzTav_0YNKmKgekD_4NBZhsE,76
79
+ nectargraphenebase/version.py,sha256=x7maU-a8H7SAAs06_OW-iZAEZ1HvGWVdSaQbjWOSVBQ,76
80
80
  nectarstorage/__init__.py,sha256=AQXmR8clT9bO9SnIM8QEr5S8ZOpbKuG_BnBsDmGvec0,1347
81
81
  nectarstorage/base.py,sha256=h7Oca1_RaJw39P1I_xXRKup016pS8zCLOs3e4IHKKdE,9734
82
82
  nectarstorage/exceptions.py,sha256=0erk_d0Ejia9td_Ke7XFBl17H1BxbM42gFpkej8EbV0,421
@@ -85,8 +85,8 @@ nectarstorage/masterpassword.py,sha256=nyG90LeHeqEjXVbRT36gAWGe-MxyKGCfQ8SqvytK1
85
85
  nectarstorage/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  nectarstorage/ram.py,sha256=Cy6JbMrlgcEG673_KqfyaofhAdJR-luRKTedj3qTZEE,1034
87
87
  nectarstorage/sqlite.py,sha256=fkkDgi1lPv7lRo5wEAe4BzSVd2kDBGss3vCDYeNzDCs,10625
88
- hive_nectar-0.0.4.dist-info/METADATA,sha256=MD7UOEbMfErZE67n8BfBTgYmxSLfi0bpUFveBzHE_ng,6015
89
- hive_nectar-0.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
90
- hive_nectar-0.0.4.dist-info/entry_points.txt,sha256=DbqiJb5fFpQvGZ0ojvc2w3dXZitTg6FPz09CobKq4m8,47
91
- hive_nectar-0.0.4.dist-info/licenses/LICENSE.txt,sha256=WjJRNR4r7FuLEO2BTBLGa05T7bBecGGgH47NgKsSY0E,1158
92
- hive_nectar-0.0.4.dist-info/RECORD,,
88
+ hive_nectar-0.0.6.dist-info/METADATA,sha256=pTDha7Q-J-O4yAJMXFs2FRPZnq8yH6xvMfGgZFfRI8w,6062
89
+ hive_nectar-0.0.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
90
+ hive_nectar-0.0.6.dist-info/entry_points.txt,sha256=DbqiJb5fFpQvGZ0ojvc2w3dXZitTg6FPz09CobKq4m8,47
91
+ hive_nectar-0.0.6.dist-info/licenses/LICENSE.txt,sha256=WjJRNR4r7FuLEO2BTBLGa05T7bBecGGgH47NgKsSY0E,1158
92
+ hive_nectar-0.0.6.dist-info/RECORD,,
nectar/blockchain.py CHANGED
@@ -39,9 +39,7 @@ if not FUTURES_MODULE:
39
39
  # default exception handler. if you want to take some action on failed tasks
40
40
  # maybe add the task back into the queue, then make your own handler and pass it in
41
41
  def default_handler(name, exception, *args, **kwargs):
42
- log.warn(
43
- "%s raised %s with args %s and kwargs %s" % (name, str(exception), repr(args), repr(kwargs))
44
- )
42
+ log.warning(f"{name} raised {exception} with args {args!r} and kwargs {kwargs!r}")
45
43
  pass
46
44
 
47
45
 
@@ -67,7 +65,7 @@ class Worker(Thread):
67
65
  # get a task and raise immediately if none available
68
66
  func, args, kwargs = self.queue.get(False)
69
67
  self.idle.clear()
70
- except:
68
+ except Exception:
71
69
  # no work to do
72
70
  # if not self.idle.is_set():
73
71
  # print >> stdout, '%s is idle' % self.name
@@ -175,7 +173,7 @@ class Pool:
175
173
  # get a result, raises empty exception immediately if none available
176
174
  results.append(self.resultQueue.get(False))
177
175
  self.resultQueue.task_done()
178
- except:
176
+ except Exception:
179
177
  return results
180
178
  return results
181
179
 
@@ -627,7 +625,9 @@ class Blockchain(object):
627
625
  )
628
626
 
629
627
  if not bool(block_batch):
630
- raise BatchedCallsNotSupported()
628
+ raise BatchedCallsNotSupported(
629
+ f"{self.blockchain.rpc.url} Doesn't support batched calls"
630
+ )
631
631
  if not isinstance(block_batch, list):
632
632
  block_batch = [block_batch]
633
633
  for block in block_batch:
nectar/comment.py CHANGED
@@ -231,8 +231,6 @@ class Comment(BlockchainObject):
231
231
  output["json_metadata"] = json.dumps(output["json_metadata"], separators=[",", ":"])
232
232
  if "tags" in output:
233
233
  output.pop("tags")
234
- if "community" in output:
235
- output.pop("community")
236
234
  parse_times = [
237
235
  "active",
238
236
  "cashout_time",
@@ -317,6 +315,14 @@ class Comment(BlockchainObject):
317
315
  else:
318
316
  return ""
319
317
 
318
+ @property
319
+ def community_title(self):
320
+ """The Community title property."""
321
+ if "community_title" in self:
322
+ return self["community_title"]
323
+ else:
324
+ return ""
325
+
320
326
  @property
321
327
  def parent_author(self):
322
328
  if "parent_author" in self:
nectar/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.4"
3
+ version = "0.0.6"
nectarapi/graphenerpc.py CHANGED
@@ -46,7 +46,7 @@ log = logging.getLogger(__name__)
46
46
 
47
47
 
48
48
  class SessionInstance(object):
49
- """Singelton for the Session Instance"""
49
+ """Singleton for the Session Instance"""
50
50
 
51
51
  instance = None
52
52
 
@@ -59,7 +59,7 @@ def set_session_instance(instance):
59
59
  def shared_session_instance():
60
60
  """Get session instance"""
61
61
  if REQUEST_MODULE is None:
62
- raise Exception()
62
+ raise Exception("Requests module is not available.")
63
63
  if not SessionInstance.instance:
64
64
  SessionInstance.instance = requests.Session()
65
65
  return SessionInstance.instance
@@ -68,7 +68,7 @@ def shared_session_instance():
68
68
  def create_ws_instance(use_ssl=True, enable_multithread=True):
69
69
  """Get websocket instance"""
70
70
  if WEBSOCKET_MODULE is None:
71
- raise Exception()
71
+ raise Exception("WebSocket module is not available.")
72
72
  if use_ssl:
73
73
  ssl_defaults = ssl.get_default_verify_paths()
74
74
  sslopt_ca_certs = {"ca_certs": ssl_defaults.cafile}
@@ -79,47 +79,24 @@ def create_ws_instance(use_ssl=True, enable_multithread=True):
79
79
 
80
80
  class GrapheneRPC(object):
81
81
  """
82
- This class allows to call API methods synchronously, without callbacks.
82
+ This class allows calling API methods synchronously, without callbacks.
83
83
 
84
84
  It logs warnings and errors.
85
85
 
86
86
  :param str urls: Either a single Websocket/Http URL, or a list of URLs
87
87
  :param str user: Username for Authentication
88
88
  :param str password: Password for Authentication
89
- :param int num_retries: Try x times to num_retries to a node on disconnect, -1 for indefinitely (default is 100)
90
- :param int num_retries_call: Repeat num_retries_call times a rpc call on node error (default is 5)
91
- :param int timeout: Timeout setting for https nodes (default is 60)
92
- :param bool autoconnect: When set to false, connection is performed on the first rpc call (default is True)
93
- :param bool use_condenser: Use the old condenser_api rpc protocol on nodes with version
94
- 0.19.4 or higher. The settings has no effect on nodes with version of 0.19.3 or lower.
95
- :param bool use_tor: When set to true, 'socks5h://localhost:9050' is set as proxy
96
- :param dict custom_chains: custom chain which should be added to the known chains
97
-
98
- Available APIs:
99
-
100
- * database
101
- * network_node
102
- * network_broadcast
103
-
104
- Usage:
105
-
106
- .. code-block:: python
107
-
108
- from nectarapi.graphenerpc import GrapheneRPC
109
- ws = GrapheneRPC("wss://steemd.pevo.science","","")
110
- print(ws.get_account_count())
111
-
112
- ws = GrapheneRPC("https://api.steemit.com","","")
113
- print(ws.get_account_count())
114
-
115
- .. note:: This class allows to call methods available via
116
- websocket. If you want to use the notification
117
- subsystem, please use ``GrapheneWebsocket`` instead.
118
-
89
+ :param int num_retries: Number of retries for node connection (default is 100)
90
+ :param int num_retries_call: Number of retries for RPC calls on node error (default is 5)
91
+ :param int timeout: Timeout setting for HTTP nodes (default is 60)
92
+ :param bool autoconnect: Automatically connect on initialization (default is True)
93
+ :param bool use_condenser: Use the old condenser_api RPC protocol
94
+ :param bool use_tor: Use Tor proxy for connections
95
+ :param dict custom_chains: Custom chains to add to known chains
119
96
  """
120
97
 
121
98
  def __init__(self, urls, user=None, password=None, **kwargs):
122
- """Init."""
99
+ """Initialize the RPC client."""
123
100
  self.rpc_methods = {"offline": -1, "ws": 0, "jsonrpc": 1, "wsappbase": 2, "appbase": 3}
124
101
  self.current_rpc = self.rpc_methods["ws"]
125
102
  self._request_id = 0
@@ -454,11 +431,12 @@ class GrapheneRPC(object):
454
431
  :raises ValueError: if the server does not respond in proper JSON format
455
432
  :raises RPCError: if the server returns an error
456
433
  """
457
- log.debug(json.dumps(payload))
434
+ log.debug(f"Payload: {json.dumps(payload)}")
458
435
  if self.nodes.working_nodes_count == 0:
459
- raise WorkingNodeMissing
436
+ raise WorkingNodeMissing("No working nodes available.")
460
437
  if self.url is None:
461
438
  raise RPCConnection("RPC is not connected!")
439
+
462
440
  reply = {}
463
441
  response = None
464
442
  while True:
@@ -488,13 +466,9 @@ class GrapheneRPC(object):
488
466
  except KeyboardInterrupt:
489
467
  raise
490
468
  except WebSocketConnectionClosedException as e:
491
- if self.nodes.num_retries_call_reached:
492
- self.nodes.increase_error_cnt()
493
- self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
494
- self.rpcconnect()
495
- else:
496
- # self.nodes.sleep_and_check_retries(str(e), sleep=True, call_retry=True)
497
- self.rpcconnect(next_url=False)
469
+ self.nodes.increase_error_cnt()
470
+ self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
471
+ self.rpcconnect()
498
472
  except ConnectionError as e:
499
473
  self.nodes.increase_error_cnt()
500
474
  self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
@@ -508,48 +482,47 @@ class GrapheneRPC(object):
508
482
  self.nodes.sleep_and_check_retries(str(e), sleep=False, call_retry=False)
509
483
  self.rpcconnect()
510
484
 
511
- ret = {}
512
485
  try:
513
486
  if response is None:
514
- ret = json.loads(reply, strict=False, encoding="utf-8")
487
+ try:
488
+ ret = json.loads(reply, strict=False)
489
+ except ValueError:
490
+ log.error(f"Non-JSON response: {reply} Node: {self.url}")
491
+ self._check_for_server_error(reply)
492
+ raise RPCError("Invalid response format")
515
493
  else:
516
494
  ret = response.json()
517
495
  except ValueError:
518
496
  self._check_for_server_error(reply)
519
497
 
520
- log.debug(json.dumps(reply))
498
+ log.debug(f"Reply: {json.dumps(reply)}")
521
499
 
522
500
  if isinstance(ret, dict) and "error" in ret:
523
- if "detail" in ret["error"]:
524
- raise RPCError(ret["error"]["detail"])
525
- else:
526
- raise RPCError(ret["error"]["message"])
527
- else:
528
- if isinstance(ret, list):
529
- ret_list = []
530
- for r in ret:
531
- if isinstance(r, dict) and "error" in r:
532
- if "detail" in r["error"]:
533
- raise RPCError(r["error"]["detail"])
534
- else:
535
- raise RPCError(r["error"]["message"])
536
- elif isinstance(r, dict) and "result" in r:
537
- ret_list.append(r["result"])
538
- else:
539
- ret_list.append(r)
540
- self.nodes.reset_error_cnt_call()
541
- return ret_list
542
- elif isinstance(ret, dict) and "result" in ret:
543
- self.nodes.reset_error_cnt_call()
544
- return ret["result"]
545
- elif isinstance(ret, int):
546
- raise RPCError(
547
- "Client returned invalid format. Expected JSON! Output: %s" % (str(ret))
501
+ if isinstance(ret["error"], dict):
502
+ error_message = ret["error"].get(
503
+ "detail", ret["error"].get("message", "Unknown error")
548
504
  )
549
- else:
550
- self.nodes.reset_error_cnt_call()
551
- return ret
552
- return ret
505
+ raise RPCError(error_message)
506
+ elif isinstance(ret, list):
507
+ ret_list = []
508
+ for r in ret:
509
+ if isinstance(r, dict) and "error" in r:
510
+ error_message = r["error"].get(
511
+ "detail", r["error"].get("message", "Unknown error")
512
+ )
513
+ raise RPCError(error_message)
514
+ elif isinstance(r, dict) and "result" in r:
515
+ ret_list.append(r["result"])
516
+ else:
517
+ ret_list.append(r)
518
+ self.nodes.reset_error_cnt_call()
519
+ return ret_list
520
+ elif isinstance(ret, dict) and "result" in ret:
521
+ self.nodes.reset_error_cnt_call()
522
+ return ret["result"]
523
+ else:
524
+ log.error(f"Unexpected response format: {ret} Node: {self.url}")
525
+ raise RPCError(f"Unexpected response format: {ret}")
553
526
 
554
527
  # End of Deprecated methods
555
528
  ####################################################################
nectarapi/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.4"
3
+ version = "0.0.6"
nectarbase/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.4"
3
+ version = "0.0.6"
@@ -1,3 +1,3 @@
1
1
  """THIS FILE IS GENERATED FROM nectar PYPROJECT.TOML."""
2
2
 
3
- version = "0.0.4"
3
+ version = "0.0.6"