naeural-client 3.1.5__py3-none-any.whl → 3.2.2__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.
- naeural_client/_ver.py +1 -1
- naeural_client/base/generic_session.py +402 -89
- naeural_client/base/instance.py +38 -0
- naeural_client/base/pipeline.py +82 -6
- naeural_client/base_decentra_object.py +4 -2
- naeural_client/bc/__init__.py +1 -1
- naeural_client/bc/base.py +9 -9
- naeural_client/bc/evm.py +10 -1
- naeural_client/cli/cli.py +1 -0
- naeural_client/cli/cli_commands.py +19 -2
- naeural_client/cli/nodes.py +100 -8
- naeural_client/cli/oracles.py +6 -0
- naeural_client/comm/mqtt_wrapper.py +4 -2
- naeural_client/const/base.py +2 -0
- naeural_client/const/environment.py +3 -0
- naeural_client/const/payload.py +7 -1
- naeural_client/utils/config.py +64 -75
- naeural_client/utils/oracle_sync/oracle_tester.py +1 -1
- {naeural_client-3.1.5.dist-info → naeural_client-3.2.2.dist-info}/METADATA +4 -4
- {naeural_client-3.1.5.dist-info → naeural_client-3.2.2.dist-info}/RECORD +23 -23
- {naeural_client-3.1.5.dist-info → naeural_client-3.2.2.dist-info}/WHEEL +0 -0
- {naeural_client-3.1.5.dist-info → naeural_client-3.2.2.dist-info}/entry_points.txt +0 -0
- {naeural_client-3.1.5.dist-info → naeural_client-3.2.2.dist-info}/licenses/LICENSE +0 -0
naeural_client/base/instance.py
CHANGED
@@ -49,6 +49,7 @@ class Instance():
|
|
49
49
|
self.log = log
|
50
50
|
self.pipeline = pipeline
|
51
51
|
self.instance_id = instance_id
|
52
|
+
self.last_known_status = None
|
52
53
|
self.signature = signature.upper()
|
53
54
|
self.config = {}
|
54
55
|
self.__debug = debug
|
@@ -673,3 +674,40 @@ class Instance():
|
|
673
674
|
self.temporary_detach(attachment)
|
674
675
|
|
675
676
|
return result_payload
|
677
|
+
|
678
|
+
def get_status(self):
|
679
|
+
"""
|
680
|
+
Get the status of the instance.
|
681
|
+
|
682
|
+
Returns
|
683
|
+
-------
|
684
|
+
dict
|
685
|
+
The status of the instance with keys from `PLUGIN_INFO` class constants
|
686
|
+
|
687
|
+
Example:
|
688
|
+
--------
|
689
|
+
```json
|
690
|
+
{
|
691
|
+
"CURRENT_EXEC_ITERATION": 2147088,
|
692
|
+
"CURRENT_PROCESS_ITERATION": 0,
|
693
|
+
"EXEC_TIMESTAMP": "2025-02-28 07:06:40.612999",
|
694
|
+
"FIRST_ERROR_TIME": null,
|
695
|
+
"FREQUENCY": null,
|
696
|
+
"INFO": null,
|
697
|
+
"INIT_TIMESTAMP": "2025-02-27 10:24:56.622480",
|
698
|
+
"INSTANCE_ID": "RECE01_default",
|
699
|
+
"LAST_CONFIG_TIMESTAMP": "2025-02-27 10:24:56.622340",
|
700
|
+
"LAST_ERROR_TIME": null,
|
701
|
+
"LAST_PAYLOAD_TIME": "2025-02-27 10:24:56",
|
702
|
+
"OUTSIDE_WORKING_HOURS": false,
|
703
|
+
"PROCESS_DELAY": 1,
|
704
|
+
"SIGNATURE": "REST_CUSTOM_EXEC_01",
|
705
|
+
"STREAM_ID": "admin_pipeline",
|
706
|
+
"TOTAL_PAYLOAD_COUNT": 1
|
707
|
+
}
|
708
|
+
```
|
709
|
+
"""
|
710
|
+
result = {} if self.last_known_status is None else self.last_known_status
|
711
|
+
if self.last_known_status is None:
|
712
|
+
self.Pd(f'Instance <{self.instance_id}> has no status yet')
|
713
|
+
return result
|
naeural_client/base/pipeline.py
CHANGED
@@ -40,6 +40,7 @@ class Pipeline(BaseCodeChecker):
|
|
40
40
|
on_notification=None,
|
41
41
|
is_attached=False,
|
42
42
|
existing_config=None,
|
43
|
+
plugins_statuses=None,
|
43
44
|
debug=False,
|
44
45
|
**kwargs
|
45
46
|
) -> None:
|
@@ -118,6 +119,9 @@ class Pipeline(BaseCodeChecker):
|
|
118
119
|
self.proposed_config = self.__pop_ignored_keys_from_config(self.proposed_config)
|
119
120
|
self.__staged_config = None
|
120
121
|
|
122
|
+
|
123
|
+
self.__update_plugins_statuses_data(plugins_statuses)
|
124
|
+
|
121
125
|
self.__was_last_operation_successful = None
|
122
126
|
|
123
127
|
self.proposed_remove_instances = []
|
@@ -172,6 +176,10 @@ class Pipeline(BaseCodeChecker):
|
|
172
176
|
is_attached,
|
173
177
|
debug=False,
|
174
178
|
):
|
179
|
+
"""
|
180
|
+
This method is used to create a new instance of a plugin and add it to the pipeline.
|
181
|
+
|
182
|
+
"""
|
175
183
|
instance_class = None
|
176
184
|
str_signature = None
|
177
185
|
if isinstance(signature, str):
|
@@ -202,8 +210,10 @@ class Pipeline(BaseCodeChecker):
|
|
202
210
|
----------
|
203
211
|
plugins : List | None
|
204
212
|
The list of plugins, as they are found in the pipeline configuration dictionary in the heartbeat.
|
213
|
+
|
205
214
|
is_attached : bool
|
206
215
|
This is used internally to allow the user to create or attach to a pipeline, and then use the same objects in the same way.
|
216
|
+
|
207
217
|
|
208
218
|
"""
|
209
219
|
if plugins is None:
|
@@ -215,10 +225,52 @@ class Pipeline(BaseCodeChecker):
|
|
215
225
|
for dct_instance in instances:
|
216
226
|
config = {k.upper(): v for k, v in dct_instance.items()}
|
217
227
|
instance_id = config.pop('INSTANCE_ID')
|
218
|
-
self.__init_instance(signature, instance_id, config, None, None, is_attached=is_attached)
|
228
|
+
instance_object = self.__init_instance(signature, instance_id, config, None, None, is_attached=is_attached)
|
229
|
+
# now we update the status of the plugin instance with the last known status
|
230
|
+
self._update_plugin_status(instance_object)
|
219
231
|
# end for dct_instance
|
220
232
|
# end for dct_signature_instances
|
221
233
|
return
|
234
|
+
|
235
|
+
def __update_plugins_statuses_data(self, plugins_statuses):
|
236
|
+
if plugins_statuses is not None:
|
237
|
+
self.last_plugins_statuses = plugins_statuses
|
238
|
+
self.last_plugins_statuses_time = time()
|
239
|
+
else:
|
240
|
+
self.last_plugins_statuses = None
|
241
|
+
self.last_plugins_statuses_time = 0
|
242
|
+
return
|
243
|
+
|
244
|
+
|
245
|
+
def __get_recent_plugin_instance_status(self, signature, instance_id):
|
246
|
+
"""
|
247
|
+
Get the most recent status of a plugin instance.
|
248
|
+
"""
|
249
|
+
result = None
|
250
|
+
if self.last_plugins_statuses is not None:
|
251
|
+
for plugin_status in self.last_plugins_statuses:
|
252
|
+
if (
|
253
|
+
plugin_status['SIGNATURE'] == signature and
|
254
|
+
plugin_status['INSTANCE_ID'] == instance_id and
|
255
|
+
plugin_status['STREAM_ID'] == self.name
|
256
|
+
):
|
257
|
+
result = plugin_status
|
258
|
+
break
|
259
|
+
return result
|
260
|
+
|
261
|
+
|
262
|
+
def _update_plugin_status(self, instance_object : Instance):
|
263
|
+
"""
|
264
|
+
Update the status of a plugin instance using any existing last known status.
|
265
|
+
|
266
|
+
"""
|
267
|
+
signature = instance_object.signature
|
268
|
+
instance_id = instance_object.instance_id
|
269
|
+
plugin_status = self.__get_recent_plugin_instance_status(signature, instance_id)
|
270
|
+
if plugin_status is not None:
|
271
|
+
instance_object.last_known_status = plugin_status
|
272
|
+
return
|
273
|
+
|
222
274
|
|
223
275
|
def __get_proposed_pipeline_config(self):
|
224
276
|
"""
|
@@ -464,8 +516,22 @@ class Pipeline(BaseCodeChecker):
|
|
464
516
|
-------
|
465
517
|
dict
|
466
518
|
The configuration dictionary without the ignored keys.
|
519
|
+
|
520
|
+
Observations
|
521
|
+
------------
|
522
|
+
|
523
|
+
Initially the ignored keys were:
|
524
|
+
[
|
525
|
+
"INITIATOR_ADDR",
|
526
|
+
"INITIATOR_ID",
|
527
|
+
"LAST_UPDATE_TIME",
|
528
|
+
"MODIFIED_BY_ADDR",
|
529
|
+
"MODIFIED_BY_ID"
|
530
|
+
]
|
531
|
+
However these keys are essential for the pipeline configuration for app
|
532
|
+
monitoring purposes
|
467
533
|
"""
|
468
|
-
ignored_keys = [
|
534
|
+
ignored_keys = []
|
469
535
|
return {k: v for k, v in config.items() if k not in ignored_keys}
|
470
536
|
|
471
537
|
def __get_instance_object(self, signature, instance_id):
|
@@ -1492,13 +1558,21 @@ class Pipeline(BaseCodeChecker):
|
|
1492
1558
|
**kwargs
|
1493
1559
|
)
|
1494
1560
|
return instance
|
1495
|
-
|
1496
|
-
|
1561
|
+
|
1562
|
+
|
1563
|
+
def _sync_configuration_with_remote(self, config={}, plugins_statuses : list = None):
|
1564
|
+
"""
|
1565
|
+
Given a configuration, update the pipeline configuration and the
|
1566
|
+
instances configuration.
|
1567
|
+
|
1568
|
+
"""
|
1497
1569
|
config.pop('NAME', None)
|
1498
1570
|
config.pop('TYPE', None)
|
1499
1571
|
plugins = config.pop('PLUGINS', {})
|
1500
1572
|
|
1501
1573
|
self.config = {**self.config, **config}
|
1574
|
+
|
1575
|
+
self.__update_plugins_statuses_data(plugins_statuses)
|
1502
1576
|
|
1503
1577
|
active_plugins = []
|
1504
1578
|
for dct_signature_instances in plugins:
|
@@ -1509,9 +1583,11 @@ class Pipeline(BaseCodeChecker):
|
|
1509
1583
|
active_plugins.append((signature, instance_id))
|
1510
1584
|
instance_object = self.__get_instance_object(signature, instance_id)
|
1511
1585
|
if instance_object is None:
|
1512
|
-
self.__init_instance(signature, instance_id, dct_instance, None, None, is_attached=True)
|
1586
|
+
instance_object = self.__init_instance(signature, instance_id, dct_instance, None, None, is_attached=True) # here the plugin status is updated if data is available
|
1513
1587
|
else:
|
1514
|
-
instance_object._sync_configuration_with_remote(dct_instance)
|
1588
|
+
instance_object._sync_configuration_with_remote(dct_instance)
|
1589
|
+
# next we update the plugin status from known plugins statuses
|
1590
|
+
self._update_plugin_status(instance_object)
|
1515
1591
|
# end for dct_instance
|
1516
1592
|
# end for dct_signature_instances
|
1517
1593
|
|
@@ -91,9 +91,11 @@ class BaseDecentrAIObject(object):
|
|
91
91
|
_r = self.log.P(msg, show_time=t, color=color, **kwargs)
|
92
92
|
return _r
|
93
93
|
|
94
|
-
def D(self, s, t=False, color=None, prefix=False, **kwargs):
|
94
|
+
def D(self, s, t=False, color=None, prefix=False, forced_debug=False, **kwargs):
|
95
95
|
_r = -1
|
96
|
-
if self.DEBUG:
|
96
|
+
if self.DEBUG or forced_debug:
|
97
|
+
if color is None:
|
98
|
+
color = 'd'
|
97
99
|
if self.show_prefixes:
|
98
100
|
msg = "[DEBUG] {}: {}".format(self.__name__, s)
|
99
101
|
else:
|
naeural_client/bc/__init__.py
CHANGED
naeural_client/bc/base.py
CHANGED
@@ -319,7 +319,7 @@ class BaseBlockEngine(_EVMMixin):
|
|
319
319
|
self.__config = config
|
320
320
|
self.__ensure_ascii_payloads = ensure_ascii_payloads
|
321
321
|
|
322
|
-
self.
|
322
|
+
self._eth_enabled = eth_enabled
|
323
323
|
|
324
324
|
if user_config:
|
325
325
|
user_folder = get_user_folder()
|
@@ -328,7 +328,7 @@ class BaseBlockEngine(_EVMMixin):
|
|
328
328
|
pem_name = config.get(BCct.K_PEM_FILE, BCct.DEFAULT_PEM_FILE)
|
329
329
|
pem_folder = config.get(BCct.K_PEM_LOCATION, BCct.DEFAULT_PEM_LOCATION)
|
330
330
|
pem_fn = os.path.join(log.get_target_folder(pem_folder), pem_name)
|
331
|
-
#endif pem is defined in ~/.
|
331
|
+
#endif pem is defined in ~/.ratio1/ or in the data folder of the _local_cache
|
332
332
|
self.__pem_file = pem_fn
|
333
333
|
self._init()
|
334
334
|
return
|
@@ -350,12 +350,12 @@ class BaseBlockEngine(_EVMMixin):
|
|
350
350
|
|
351
351
|
@property
|
352
352
|
def eth_enabled(self):
|
353
|
-
return self.
|
353
|
+
return self._eth_enabled
|
354
354
|
|
355
355
|
|
356
356
|
def set_eth_flag(self, value):
|
357
|
-
if value != self.
|
358
|
-
self.
|
357
|
+
if value != self._eth_enabled:
|
358
|
+
self._eth_enabled = value
|
359
359
|
self.log.P("Changed eth_enabled to {}".format(value), color='d')
|
360
360
|
return
|
361
361
|
|
@@ -377,7 +377,7 @@ class BaseBlockEngine(_EVMMixin):
|
|
377
377
|
|
378
378
|
def _init(self):
|
379
379
|
self.P(
|
380
|
-
f"Initializing BC-engine (ETH_ENABLED={self.
|
380
|
+
f"Initializing BC-engine (ETH_ENABLED={self._eth_enabled})...", verbosity=1
|
381
381
|
)
|
382
382
|
|
383
383
|
if True:
|
@@ -414,9 +414,9 @@ class BaseBlockEngine(_EVMMixin):
|
|
414
414
|
self.__eth_address = self._get_eth_address()
|
415
415
|
self.__eth_account = self._get_eth_account()
|
416
416
|
### end Ethereum
|
417
|
-
if self.
|
417
|
+
if self._eth_enabled:
|
418
418
|
self.P(
|
419
|
-
"
|
419
|
+
"{} / ETH: {} ({})".format(self.address, self.eth_address, self.evm_network), boxed=True, verbosity=1,
|
420
420
|
color='g'
|
421
421
|
)
|
422
422
|
else:
|
@@ -1212,7 +1212,7 @@ class BaseBlockEngine(_EVMMixin):
|
|
1212
1212
|
dct_data[BCct.SIGN] = result
|
1213
1213
|
dct_data[BCct.SENDER] = self.address
|
1214
1214
|
|
1215
|
-
if self.
|
1215
|
+
if self._eth_enabled:
|
1216
1216
|
dct_data[BCct.ETH_SENDER] = self.eth_address
|
1217
1217
|
### add eth signature
|
1218
1218
|
dct_data[BCct.ETH_SIGN] = "0xBEEF"
|
naeural_client/bc/evm.py
CHANGED
@@ -191,8 +191,17 @@ class _EVMMixin:
|
|
191
191
|
|
192
192
|
"""
|
193
193
|
if EE_VPN_IMPL:
|
194
|
-
return "VPN"
|
194
|
+
return "VPN"
|
195
195
|
network = os.environ.get(dAuth.DAUTH_NET_ENV_KEY, dAuth.DAUTH_SDK_NET_DEFAULT)
|
196
|
+
|
197
|
+
if not self._first_checks_done[dAuth.DAUTH_NET_ENV_KEY]:
|
198
|
+
if dAuth.DAUTH_NET_ENV_KEY not in os.environ:
|
199
|
+
self.P(f"Using default {network=}...", verbosity=2)
|
200
|
+
else:
|
201
|
+
self.P(f"Using {network=} from `{dAuth.DAUTH_NET_ENV_KEY}` env key...", verbosity=2)
|
202
|
+
self._first_checks_done[dAuth.DAUTH_NET_ENV_KEY] = True
|
203
|
+
# done first checks
|
204
|
+
|
196
205
|
if not hasattr(self, "current_evm_network") or self.current_evm_network != network:
|
197
206
|
self.current_evm_network = network
|
198
207
|
network_data = self.get_network_data(network)
|
naeural_client/cli/cli.py
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
from naeural_client.cli.nodes import (
|
2
2
|
get_nodes, get_supervisors,
|
3
3
|
restart_node, shutdown_node,
|
4
|
+
get_apps
|
4
5
|
)
|
5
6
|
from naeural_client.cli.oracles import get_availability
|
6
7
|
from naeural_client.utils.config import (
|
7
8
|
show_config, reset_config, show_address, get_set_network,
|
8
|
-
|
9
|
+
get_networks, get_set_alias, get_eth_addr
|
9
10
|
)
|
10
11
|
|
11
12
|
# Define the available commands
|
@@ -27,6 +28,13 @@ CLI_COMMANDS = {
|
|
27
28
|
"supervisors": {
|
28
29
|
"func": get_supervisors, # DONE
|
29
30
|
},
|
31
|
+
"eth" : {
|
32
|
+
"func": get_eth_addr,
|
33
|
+
"description": "Get the ETH address given a node address",
|
34
|
+
"params": {
|
35
|
+
"node": "The node address to get the ETH address for"
|
36
|
+
}
|
37
|
+
},
|
30
38
|
"avail": {
|
31
39
|
"func": get_availability,
|
32
40
|
"params": {
|
@@ -43,7 +51,8 @@ CLI_COMMANDS = {
|
|
43
51
|
"func": get_apps,
|
44
52
|
"description": "Get the apps running on a given node, if the client is allowed on that node.",
|
45
53
|
"params": {
|
46
|
-
"node": "The ETH address or the specific address of the node to get the apps from",
|
54
|
+
"--node": "The ETH address or the specific address of the node to get the apps from",
|
55
|
+
"--owner" : "Get the apps for a particular owner/initiator",
|
47
56
|
"--full": "Include admin apps (flag)",
|
48
57
|
"--json": "Output the entire JSON config of applications (flag)",
|
49
58
|
}
|
@@ -80,6 +89,14 @@ CLI_COMMANDS = {
|
|
80
89
|
"--set": "The network to set either 'mainnet' or 'testnet' (same as --new)",
|
81
90
|
}
|
82
91
|
},
|
92
|
+
|
93
|
+
"alias" :{
|
94
|
+
"func": get_set_alias, # DONE
|
95
|
+
"description": "Show and sets the current client alias",
|
96
|
+
"params": {
|
97
|
+
"--set": "The alias to set for this SDK client",
|
98
|
+
}
|
99
|
+
}
|
83
100
|
},
|
84
101
|
"restart": {
|
85
102
|
"func": restart_node, # TODO
|
naeural_client/cli/nodes.py
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
import os
|
2
|
+
import json
|
3
|
+
|
2
4
|
from time import time
|
3
5
|
from naeural_client.utils.config import log_with_color
|
4
6
|
from naeural_client.const import SESSION_CT, COMMANDS, BASE_CT
|
7
|
+
from naeural_client._ver import __VER__ as version
|
8
|
+
|
9
|
+
from pandas import DataFrame
|
10
|
+
from datetime import datetime
|
5
11
|
|
6
12
|
|
7
13
|
def _get_netstats(
|
@@ -53,32 +59,41 @@ def get_nodes(args):
|
|
53
59
|
4. Get the active nodes union via Session and display the nodes marking those peered vs non-peered.
|
54
60
|
"""
|
55
61
|
supervisor_addr = args.supervisor
|
62
|
+
online = args.online
|
63
|
+
online = True # always online, flag deprecated
|
56
64
|
wide = args.wide
|
57
65
|
if args.verbose:
|
58
66
|
log_with_color(f"Getting nodes from supervisor <{supervisor_addr}>...", color='b')
|
59
67
|
|
60
68
|
res = _get_netstats(
|
61
69
|
silent=not args.verbose,
|
62
|
-
online_only=
|
70
|
+
online_only=online or args.peered,
|
63
71
|
allowed_only=args.peered,
|
64
72
|
supervisor=supervisor_addr,
|
65
73
|
eth=args.eth,
|
66
74
|
all_info=wide,
|
75
|
+
return_session=True,
|
67
76
|
)
|
68
|
-
df, supervisor, super_alias, nr_supers, elapsed = res
|
77
|
+
df, supervisor, super_alias, nr_supers, elapsed, sess = res
|
69
78
|
if args.online:
|
70
79
|
FILTERED = ['State']
|
71
80
|
df = df[[c for c in df.columns if c not in FILTERED]]
|
72
81
|
|
73
|
-
prefix = "Online n" if (
|
74
|
-
network = os.environ.get(BASE_CT.dAuth.DAUTH_NET_ENV_KEY, BASE_CT.dAuth.DAUTH_SDK_NET_DEFAULT)
|
82
|
+
prefix = "Online n" if (online or args.peered) else "N"
|
83
|
+
# network = os.environ.get(BASE_CT.dAuth.DAUTH_NET_ENV_KEY, BASE_CT.dAuth.DAUTH_SDK_NET_DEFAULT)
|
84
|
+
network = sess.bc_engine.evm_network
|
75
85
|
if supervisor == "ERROR":
|
76
86
|
log_with_color(f"No supervisors or no comms available in {elapsed:.1f}s. Please check your settings.", color='r')
|
77
87
|
else:
|
78
|
-
log_with_color(f"
|
88
|
+
log_with_color(f"Ratio1 client v{version}:\n", color='b')
|
89
|
+
log_with_color(
|
90
|
+
"{}odes on '{}' reported by <{}> '{}' in {:.1f}s ({} supervisors seen):".format(
|
91
|
+
prefix, network, supervisor, super_alias, elapsed, nr_supers),
|
92
|
+
color='b'
|
93
|
+
)
|
79
94
|
import pandas as pd
|
80
95
|
pd.set_option('display.float_format', '{:.4f}'.format)
|
81
|
-
log_with_color(f"{df}")
|
96
|
+
log_with_color(f"{df}\n")
|
82
97
|
return
|
83
98
|
|
84
99
|
|
@@ -93,18 +108,95 @@ def get_supervisors(args):
|
|
93
108
|
silent=not args.verbose,
|
94
109
|
online_only=True,
|
95
110
|
supervisors_only=True,
|
111
|
+
return_session=True,
|
96
112
|
)
|
97
|
-
df, supervisor, super_alias, nr_supers, elapsed = res
|
113
|
+
df, supervisor, super_alias, nr_supers, elapsed, sess = res
|
98
114
|
FILTERED = ['Oracle', 'State']
|
99
115
|
df = df[[c for c in df.columns if c not in FILTERED]]
|
100
116
|
|
101
117
|
if supervisor == "ERROR":
|
102
118
|
log_with_color(f"No supervisors or no comms available in {elapsed:.1f}s. Please check your settings.", color='r')
|
103
119
|
else:
|
104
|
-
log_with_color(
|
120
|
+
log_with_color(
|
121
|
+
"Supervisors on '{}' reported by <{}> '{}' in {:.1f}s".format(
|
122
|
+
sess.bc_engine.evm_network, supervisor, super_alias, elapsed),
|
123
|
+
color='b'
|
124
|
+
)
|
105
125
|
log_with_color(f"{df}")
|
106
126
|
return
|
107
127
|
|
128
|
+
|
129
|
+
def get_apps(args):
|
130
|
+
"""
|
131
|
+
Shows the apps running on a given node, if the client is allowed on that node.
|
132
|
+
Parameters
|
133
|
+
----------
|
134
|
+
args : argparse.Namespace
|
135
|
+
Arguments passed to the function.
|
136
|
+
|
137
|
+
"""
|
138
|
+
verbose = args.verbose
|
139
|
+
node = args.node
|
140
|
+
show_full = args.full
|
141
|
+
as_json = args.json
|
142
|
+
owner = args.owner
|
143
|
+
|
144
|
+
# 1. Init session
|
145
|
+
from naeural_client import Session
|
146
|
+
sess = Session(
|
147
|
+
silent=not verbose
|
148
|
+
)
|
149
|
+
|
150
|
+
res = sess.get_nodes_apps(
|
151
|
+
node=node, owner=owner, show_full=show_full,
|
152
|
+
as_json=as_json, as_df=not as_json
|
153
|
+
)
|
154
|
+
if res is not None:
|
155
|
+
network = sess.bc_engine.evm_network
|
156
|
+
node_alias = sess.get_node_alias(node) if node else None
|
157
|
+
if as_json:
|
158
|
+
log_with_color(json.dumps(res, indent=2))
|
159
|
+
else:
|
160
|
+
df_apps = res
|
161
|
+
if df_apps.shape[0] == 0:
|
162
|
+
log_with_color(
|
163
|
+
"No user apps found on node <{}> '{}' of network '{}'".format(
|
164
|
+
node, node_alias, network
|
165
|
+
),
|
166
|
+
color='r'
|
167
|
+
)
|
168
|
+
return
|
169
|
+
# remove Node column
|
170
|
+
if node is not None and owner is None:
|
171
|
+
df_apps.drop(columns=['Node'], inplace=True)
|
172
|
+
|
173
|
+
if node is None and owner is not None:
|
174
|
+
df_apps.drop(columns=['Owner'], inplace=True)
|
175
|
+
|
176
|
+
if node is not None:
|
177
|
+
last_seen = sess.get_last_seen_time(node)
|
178
|
+
last_seen_str = datetime.fromtimestamp(last_seen).strftime('%Y-%m-%d %H:%M:%S') if last_seen else None
|
179
|
+
is_online = sess.check_node_online(node)
|
180
|
+
node_status = 'Online' if is_online else 'Offline'
|
181
|
+
else:
|
182
|
+
last_seen_str = "N/A"
|
183
|
+
node_status = "N/A"
|
184
|
+
#end if node
|
185
|
+
if node == None:
|
186
|
+
node = "[All available]"
|
187
|
+
by_owner = f" by owner <{owner}>" if owner else ""
|
188
|
+
log_with_color(f"Ratio1 client v{version}:\n", color='b')
|
189
|
+
log_with_color(
|
190
|
+
"Apps on <{}> ({}) [Status: {}| Last seen: {}]{}:".format(
|
191
|
+
node, network, node_status, last_seen_str, by_owner
|
192
|
+
),
|
193
|
+
color='b'
|
194
|
+
)
|
195
|
+
log_with_color(f"{df_apps}\n")
|
196
|
+
#end if as_json
|
197
|
+
#end if res is not None
|
198
|
+
return
|
199
|
+
|
108
200
|
def _send_command_to_node(args, command, ignore_not_found=False):
|
109
201
|
node = args.node
|
110
202
|
silent = not args.verbose
|
naeural_client/cli/oracles.py
CHANGED
@@ -133,11 +133,17 @@ def get_availability(args):
|
|
133
133
|
# endif full
|
134
134
|
|
135
135
|
tester = oracle_tester_init()
|
136
|
+
|
137
|
+
if not tester.bc.is_valid_eth_address(node):
|
138
|
+
node = tester.bc.node_address_to_eth_address(node)
|
139
|
+
|
136
140
|
log_with_color("Checking {}availability of node <{}> from {} to {}.".format(
|
137
141
|
"(DEBUG MODE) " if rounds > 1 else "", node, start,
|
138
142
|
end if end else "last epoch"
|
139
143
|
), color='b'
|
140
144
|
)
|
145
|
+
|
146
|
+
|
141
147
|
res = tester.execute_command(
|
142
148
|
node_eth_addr=node,
|
143
149
|
start=start,
|
@@ -41,11 +41,11 @@ class MQTTWrapper(object):
|
|
41
41
|
self._config = config
|
42
42
|
self._recv_buff = recv_buff
|
43
43
|
self._mqttc = None
|
44
|
-
self.debug_errors = debug_errors
|
44
|
+
self.debug_errors = debug_errors if verbosity <=1 else True
|
45
45
|
self._thread_name = None
|
46
46
|
self.connected = False
|
47
47
|
self.disconnected = False
|
48
|
-
self.__verbosity = verbosity
|
48
|
+
self.__verbosity = verbosity
|
49
49
|
self._send_to = None
|
50
50
|
self._nr_full_retries = 0
|
51
51
|
self.__nr_dropped_messages = 0
|
@@ -240,6 +240,8 @@ class MQTTWrapper(object):
|
|
240
240
|
return
|
241
241
|
|
242
242
|
def __create_mqttc_object(self, comtype, client_uid):
|
243
|
+
if self.__verbosity > 1:
|
244
|
+
self.P(f"Creating MQTT client: {self._connection_name} - {comtype} - {client_uid}")
|
243
245
|
client_id = self._connection_name + '_' + comtype + '_' + client_uid
|
244
246
|
if mqtt_version.startswith('2'):
|
245
247
|
mqttc = mqtt.Client(
|
naeural_client/const/base.py
CHANGED
@@ -28,8 +28,11 @@ class ENVIRONMENT:
|
|
28
28
|
|
29
29
|
EE_SECURED = 'EE_SECURED'
|
30
30
|
AIXP_SECURED = 'AIXP_SECURED'
|
31
|
+
EE_MQTT_SECURED = 'EE_MQTT_SECURED'
|
31
32
|
|
32
33
|
TELEGRAM_BOT_TOKEN_ENV_KEY = 'EE_TELEGRAM_BOT_TOKEN'
|
33
34
|
TELEGRAM_BOT_NAME_ENV_KEY = 'EE_TELEGRAM_BOT_NAME'
|
34
35
|
|
35
36
|
TELEGRAM_API_AGENT_TOKEN_ENV_KEY = 'EE_TELEGRAM_API_AGENT_TOKEN'
|
37
|
+
|
38
|
+
EE_ROOT_TOPIC_ENV_KEY = 'EE_ROOT_TOPIC'
|
naeural_client/const/payload.py
CHANGED
@@ -209,6 +209,8 @@ class PAYLOAD_DATA:
|
|
209
209
|
NETMON_NODE_SECURED = 'secured'
|
210
210
|
NETMON_NODE_VERSION = 'version'
|
211
211
|
|
212
|
+
|
213
|
+
|
212
214
|
|
213
215
|
class NET_CONFIG:
|
214
216
|
STORE_COMMAND = "SET_CONFIG"
|
@@ -216,4 +218,8 @@ class NET_CONFIG:
|
|
216
218
|
NET_CONFIG_DATA = 'NET_CONFIG_DATA'
|
217
219
|
OPERATION = 'OP'
|
218
220
|
DESTINATION = 'DEST'
|
219
|
-
DATA = 'DATA'
|
221
|
+
DATA = 'DATA'
|
222
|
+
|
223
|
+
PIPELINES = "PIPELINES"
|
224
|
+
PLUGINS_STATUSES = "PLUGIN_STATUSES"
|
225
|
+
|