naeural-client 2.6.14__py3-none-any.whl → 2.6.15__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 CHANGED
@@ -1,4 +1,4 @@
1
- __VER__ = "2.6.14"
1
+ __VER__ = "2.6.15"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -23,7 +23,7 @@ from ..bc import DefaultBlockEngine, _DotDict
23
23
  from ..const import (
24
24
  COMMANDS, ENVIRONMENT, HB, PAYLOAD_DATA, STATUS_TYPE,
25
25
  PLUGIN_SIGNATURES, DEFAULT_PIPELINES,
26
- BLOCKCHAIN_CONFIG, SESSION_CT
26
+ BLOCKCHAIN_CONFIG, SESSION_CT, NET_CONFIG
27
27
  )
28
28
  from ..const import comms as comm_ct
29
29
  from ..io_formatter import IOFormatterWrapper
@@ -366,24 +366,33 @@ class GenericSession(BaseDecentrAIObject):
366
366
  """
367
367
  # check if payload is encrypted
368
368
  if dict_msg.get(PAYLOAD_DATA.EE_IS_ENCRYPTED, False):
369
- encrypted_data = dict_msg.get(PAYLOAD_DATA.EE_ENCRYPTED_DATA, None)
370
- sender_addr = dict_msg.get(comm_ct.COMM_SEND_MESSAGE.K_SENDER_ADDR, None)
369
+ destination = dict_msg.get(PAYLOAD_DATA.EE_DESTINATION, [])
370
+ if not isinstance(destination, list):
371
+ destination = [destination]
372
+ if self.bc_engine.contains_current_address(destination):
371
373
 
372
- str_data = self.bc_engine.decrypt(encrypted_data, sender_addr)
374
+ encrypted_data = dict_msg.get(PAYLOAD_DATA.EE_ENCRYPTED_DATA, None)
375
+ sender_addr = dict_msg.get(comm_ct.COMM_SEND_MESSAGE.K_SENDER_ADDR, None)
373
376
 
374
- if str_data is None:
375
- self.D("Cannot decrypt message, dropping..\n{}".format(str_data), verbosity=2)
376
- return None
377
+ str_data = self.bc_engine.decrypt(encrypted_data, sender_addr)
377
378
 
378
- try:
379
- dict_data = json.loads(str_data)
380
- except Exception as e:
381
- self.P("Error while decrypting message: {}".format(e), color='r', verbosity=1)
382
- self.D("Message: {}".format(str_data), verbosity=2)
383
- return None
379
+ if str_data is None:
380
+ self.D("Cannot decrypt message, dropping..\n{}".format(str_data), verbosity=2)
381
+ return None
384
382
 
385
- dict_msg = {**dict_data, **dict_msg}
386
- dict_msg.pop(PAYLOAD_DATA.EE_ENCRYPTED_DATA, None)
383
+ try:
384
+ dict_data = json.loads(str_data)
385
+ except Exception as e:
386
+ self.P("Error while decrypting message: {}".format(e), color='r', verbosity=1)
387
+ self.D("Message: {}".format(str_data), verbosity=2)
388
+ return None
389
+
390
+ dict_msg = {**dict_data, **dict_msg}
391
+ dict_msg.pop(PAYLOAD_DATA.EE_ENCRYPTED_DATA, None)
392
+ else:
393
+ payload_path = dict_msg.get(PAYLOAD_DATA.EE_PAYLOAD_PATH, None)
394
+ self.D(f"Message {payload_path} is encrypted but not for this address.", verbosity=2)
395
+ # endif message for us
387
396
  # end if encrypted
388
397
 
389
398
  formatter = self.formatter_wrapper \
@@ -498,6 +507,56 @@ class GenericSession(BaseDecentrAIObject):
498
507
  self._dct_can_send_to_node[node_addr] = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
499
508
  return
500
509
 
510
+ def send_encrypted_payload(self, node_addr, payload, **kwargs):
511
+ """
512
+ TODO: move in BlockChainEngine
513
+ Send an encrypted payload to a node.
514
+
515
+ Parameters
516
+ ----------
517
+ node_addr : str
518
+ The address of the edge node that will receive the message.
519
+ payload : dict
520
+ The payload dict to be sent.
521
+ **kwargs : dict
522
+ Additional data to be sent to __prepare_message.
523
+ """
524
+ msg_to_send = self.__prepare_message(
525
+ msg_data=payload,
526
+ encrypt_message=True,
527
+ destination=node_addr,
528
+ **kwargs
529
+ )
530
+ self.bc_engine.sign(msg_to_send)
531
+ if not self.silent:
532
+ self.P(f'Sending encrypted payload to <{node_addr}>', color='y')
533
+ self._send_payload(msg_to_send)
534
+ return
535
+
536
+ def __request_pipelines_from_net_config_monitor(self, node_addr):
537
+ """
538
+ Request the pipelines for a node from the net-config monitor plugin instance.
539
+ Parameters
540
+ ----------
541
+ node_addr : str
542
+ The address of the edge node that sent the message.
543
+
544
+ """
545
+ payload = {
546
+ NET_CONFIG.NET_CONFIG_DATA: {
547
+ NET_CONFIG.OPERATION: NET_CONFIG.REQUEST_COMMAND,
548
+ NET_CONFIG.DESTINATION: node_addr,
549
+ }
550
+ }
551
+ additional_data = {
552
+ PAYLOAD_DATA.EE_PAYLOAD_PATH: [self.bc_engine.address, DEFAULT_PIPELINES.ADMIN_PIPELINE, PLUGIN_SIGNATURES.NET_CONFIG_MONITOR, None]
553
+ }
554
+ self.send_encrypted_payload(
555
+ node_addr=node_addr, payload=payload,
556
+ additional_data=additional_data
557
+ )
558
+ return
559
+
501
560
  def __track_allowed_node_by_netmon(self, node_addr, dict_msg):
502
561
  """
503
562
  Track if this session is allowed to send messages to node using net-mon data
@@ -505,7 +564,7 @@ class GenericSession(BaseDecentrAIObject):
505
564
  Parameters
506
565
  ----------
507
566
  node_addr : str
508
- The address of the Naeural Edge Protocol edge node that sent the message.
567
+ The address of the edge node that sent the message.
509
568
 
510
569
  dict_msg : dict
511
570
  The message received from the communication server as a heartbeat of the object from netconfig
@@ -514,8 +573,12 @@ class GenericSession(BaseDecentrAIObject):
514
573
  node_secured = dict_msg.get(PAYLOAD_DATA.NETMON_NODE_SECURED, False)
515
574
 
516
575
  client_is_allowed = self.bc_engine.contains_current_address(node_whitelist)
576
+ can_send = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
577
+ if node_addr not in self._dct_can_send_to_node and can_send:
578
+ self.__request_pipelines_from_net_config_monitor(node_addr)
579
+ # endif node seen for the first time
517
580
 
518
- self._dct_can_send_to_node[node_addr] = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
581
+ self._dct_can_send_to_node[node_addr] = can_send
519
582
  return
520
583
 
521
584
 
@@ -523,6 +586,9 @@ class GenericSession(BaseDecentrAIObject):
523
586
  """
524
587
  Given a list of pipeline configurations, create or update the pipelines for a node.
525
588
  """
589
+ new_pipelines = []
590
+ if node_addr not in self._dct_online_nodes_pipelines:
591
+ self._dct_online_nodes_pipelines[node_addr] = {}
526
592
  for config in pipelines:
527
593
  pipeline_name = config[PAYLOAD_DATA.NAME]
528
594
  pipeline: Pipeline = self._dct_online_nodes_pipelines[node_addr].get(pipeline_name, None)
@@ -531,7 +597,8 @@ class GenericSession(BaseDecentrAIObject):
531
597
  else:
532
598
  self._dct_online_nodes_pipelines[node_addr][pipeline_name] = self.__create_pipeline_from_config(
533
599
  node_addr, config)
534
- return
600
+ new_pipelines.append(self._dct_online_nodes_pipelines[node_addr][pipeline_name])
601
+ return new_pipelines
535
602
 
536
603
  def __on_heartbeat(self, dict_msg: dict, msg_node_addr, msg_pipeline, msg_signature, msg_instance):
537
604
  """
@@ -571,14 +638,11 @@ class GenericSession(BaseDecentrAIObject):
571
638
  # as the protocol should NOT send a heartbeat with active configs to
572
639
  # the entire network, only to the interested parties via net-config
573
640
 
574
- # default action
575
- if msg_node_addr not in self._dct_online_nodes_pipelines:
576
- # this is ok here although we dont get the pipelines from the heartbeat
577
- self._dct_online_nodes_pipelines[msg_node_addr] = {}
578
-
579
641
  if len(msg_active_configs) > 0:
580
642
  # this is for legacy and custom implementation where heartbeats still contain
581
643
  # the pipeline configuration.
644
+ pipeline_names = [x.get(PAYLOAD_DATA.NAME, None) for x in msg_active_configs]
645
+ self.D(f'<HB>Received pipelines from <{msg_node_addr}>:{pipeline_names}', color='y')
582
646
  self.__process_node_pipelines(msg_node_addr, msg_active_configs)
583
647
 
584
648
  # TODO: move this call in `__on_message_default_callback`
@@ -699,8 +763,7 @@ class GenericSession(BaseDecentrAIObject):
699
763
  # end if current_network is valid
700
764
  # end if NET_MON_01
701
765
  return
702
-
703
-
766
+
704
767
  def __maybe_process_net_config(
705
768
  self,
706
769
  dict_msg: dict,
@@ -708,7 +771,39 @@ class GenericSession(BaseDecentrAIObject):
708
771
  msg_signature : str,
709
772
  sender_addr: str,
710
773
  ):
711
- return
774
+ # TODO: bleo if session is in debug mode then for each net-config show what pipelines have
775
+ # been received
776
+ REQUIRED_PIPELINE = DEFAULT_PIPELINES.ADMIN_PIPELINE
777
+ REQUIRED_SIGNATURE = PLUGIN_SIGNATURES.NET_CONFIG_MONITOR
778
+ if msg_pipeline.lower() == REQUIRED_PIPELINE.lower() and msg_signature.upper() == REQUIRED_SIGNATURE.upper():
779
+ # extract data
780
+ sender_addr = dict_msg.get(PAYLOAD_DATA.EE_SENDER, None)
781
+ receiver = dict_msg.get(PAYLOAD_DATA.EE_DESTINATION, None)
782
+ if not isinstance(receiver, list):
783
+ receiver = [receiver]
784
+ path = dict_msg.get(PAYLOAD_DATA.EE_PAYLOAD_PATH, [None, None, None, None])
785
+ ee_id = dict_msg.get(PAYLOAD_DATA.EE_ID, None)
786
+
787
+ # check if I am allowed to see this payload
788
+ if not self.bc_engine.contains_current_address(receiver):
789
+ self.P(f"Received net-config from <{sender_addr}> `{ee_id}` but I am not in the receiver list: {receiver}", color='d')
790
+ return
791
+
792
+ # decrypt payload
793
+ is_encrypted = dict_msg.get(PAYLOAD_DATA.EE_IS_ENCRYPTED, False)
794
+ if not is_encrypted:
795
+ self.P(f"Received net-config from <{sender_addr}> `{ee_id}` but it is not encrypted", color='r')
796
+ return
797
+ net_config_data = dict_msg.get(NET_CONFIG.NET_CONFIG_DATA, {})
798
+ received_pipelines = net_config_data.get('PIPELINES', [])
799
+ self.D(f"Received {len(received_pipelines)} pipelines from <{sender_addr}>")
800
+ new_pipelines = self.__process_node_pipelines(sender_addr, received_pipelines)
801
+ pipeline_names = [x.name for x in new_pipelines]
802
+ self.P(f'<NETCFG>Received pipelines from <{sender_addr}>:{pipeline_names}', color='y')
803
+ self.D(f'[DEBUG][NETCFG]Received pipelines from <{sender_addr}>:\n{new_pipelines}', color='y')
804
+
805
+ # load with same method as a hb
806
+ return True
712
807
 
713
808
 
714
809
  # TODO: maybe convert dict_msg to Payload object
@@ -908,15 +1003,38 @@ class GenericSession(BaseDecentrAIObject):
908
1003
  """
909
1004
  raise NotImplementedError
910
1005
 
911
- def _send_payload(self, to, payload):
1006
+ def _send_raw_message(self, to, msg, communicator='default'):
912
1007
  """
913
- Send a payload to a node.
1008
+ Send a message to a node.
914
1009
 
915
1010
  Parameters
916
1011
  ----------
917
1012
  to : str
918
- The name of the Naeural Edge Protocol edge node that will receive the payload.
919
- payload : dict
1013
+ The name of the Naeural Edge Protocol edge node that will receive the message.
1014
+ msg : dict or str
1015
+ The message to send.
1016
+ """
1017
+ raise NotImplementedError
1018
+
1019
+ def _send_command(self, to, command):
1020
+ """
1021
+ Send a command to a node.
1022
+
1023
+ Parametersc
1024
+ ----------
1025
+ to : str
1026
+ The name of the Naeural Edge Protocol edge node that will receive the command.
1027
+ command : str or dict
1028
+ The command to send.
1029
+ """
1030
+ raise NotImplementedError
1031
+
1032
+ def _send_payload(self, payload):
1033
+ """
1034
+ Send a payload to a node.
1035
+ Parameters
1036
+ ----------
1037
+ payload : dict or str
920
1038
  The payload to send.
921
1039
  """
922
1040
  raise NotImplementedError
@@ -1241,6 +1359,68 @@ class GenericSession(BaseDecentrAIObject):
1241
1359
  result = aliases.get(node, None)
1242
1360
  return result
1243
1361
 
1362
+ def __prepare_message(
1363
+ self, msg_data, encrypt_message: bool = True,
1364
+ destination: str = None, destination_id: str = None,
1365
+ session_id: str = None, additional_data: dict = None
1366
+ ):
1367
+ """
1368
+ Prepare and maybe encrypt a message for sending.
1369
+ Parameters
1370
+ ----------
1371
+ msg_data : dict
1372
+ The message to send.
1373
+ encrypt_message : bool
1374
+ If True, will encrypt the message.
1375
+ destination : str, optional
1376
+ The destination address, by default None
1377
+ destination_id : str, optional
1378
+ The destination id, by default None
1379
+ additional_data : dict, optional
1380
+ Additional data to send, by default None
1381
+ This has to be dict!
1382
+
1383
+ Returns
1384
+ -------
1385
+ msg_to_send : dict
1386
+ The message to send.
1387
+ """
1388
+ if destination is None and destination_id is not None:
1389
+ # Initial code `str_enc_data = self.bc_engine.encrypt(str_data, destination_id)` could not work under any
1390
+ # circumstances due to the fact that encrypt requires the public key of the receiver not the alias
1391
+ # of the receiver. The code below is a workaround to encrypt the message
1392
+ # TODO: furthermore the code will be migrated to the use of the address of the worker
1393
+ destination = self.get_addr_by_name(destination_id)
1394
+ assert destination is not None, f"Unknown address for id: {destination_id}"
1395
+ # endif only destination_id provided
1396
+
1397
+ # This part is duplicated with the creation of payloads
1398
+ if encrypt_message and destination is not None:
1399
+ str_data = json.dumps(msg_data)
1400
+ str_enc_data = self.bc_engine.encrypt(str_data, destination)
1401
+ msg_data = {
1402
+ comm_ct.COMM_SEND_MESSAGE.K_EE_IS_ENCRYPTED: True,
1403
+ comm_ct.COMM_SEND_MESSAGE.K_EE_ENCRYPTED_DATA: str_enc_data,
1404
+ }
1405
+ else:
1406
+ msg_data[comm_ct.COMM_SEND_MESSAGE.K_EE_IS_ENCRYPTED] = False
1407
+ if encrypt_message:
1408
+ msg_data[comm_ct.COMM_SEND_MESSAGE.K_EE_ENCRYPTED_DATA] = "Error! No receiver address found!"
1409
+ # endif encrypt_message and destination available
1410
+ msg_to_send = {
1411
+ **msg_data,
1412
+ PAYLOAD_DATA.EE_DESTINATION: destination,
1413
+ comm_ct.COMM_SEND_MESSAGE.K_EE_ID: destination_id,
1414
+ comm_ct.COMM_SEND_MESSAGE.K_SESSION_ID: session_id or self.name,
1415
+ comm_ct.COMM_SEND_MESSAGE.K_INITIATOR_ID: self.name,
1416
+ comm_ct.COMM_SEND_MESSAGE.K_SENDER_ADDR: self.bc_engine.address,
1417
+ comm_ct.COMM_SEND_MESSAGE.K_TIME: dt.now().strftime("%Y-%m-%d %H:%M:%S.%f"),
1418
+ }
1419
+ if additional_data is not None and isinstance(additional_data, dict):
1420
+ msg_to_send.update(additional_data)
1421
+ # endif additional_data provided
1422
+ return msg_to_send
1423
+
1244
1424
  def _send_command_to_box(self, command, worker, payload, show_command=True, session_id=None, **kwargs):
1245
1425
  """
1246
1426
  Send a command to a node.
@@ -1273,37 +1453,12 @@ class GenericSession(BaseDecentrAIObject):
1273
1453
  comm_ct.COMM_SEND_MESSAGE.K_PAYLOAD: payload,
1274
1454
  }
1275
1455
 
1276
- # This part is duplicated with the creation of payloads
1277
- encrypt_payload = self.encrypt_comms
1278
- if encrypt_payload and worker is not None:
1279
- str_data = json.dumps(critical_data)
1280
-
1281
- # Initial code `str_enc_data = self.bc_engine.encrypt(str_data, worker)` could not work under any
1282
- # circumstances due to the fact that encrypt requires the public key of the receiver not the alias
1283
- # of the receiver. The code below is a workaround to encrypt the message
1284
- # TODO: furthermore the code will be migrated to the use of the address of the worker
1285
- worker_addr = self.get_addr_by_name(worker)
1286
- assert worker_addr is not None, f"Unknown worker address: {worker} - {worker_addr}"
1287
-
1288
- str_enc_data = self.bc_engine.encrypt(str_data, worker_addr)
1289
- critical_data = {
1290
- comm_ct.COMM_SEND_MESSAGE.K_EE_IS_ENCRYPTED: True,
1291
- comm_ct.COMM_SEND_MESSAGE.K_EE_ENCRYPTED_DATA: str_enc_data,
1292
- }
1293
- else:
1294
- critical_data[comm_ct.COMM_SEND_MESSAGE.K_EE_IS_ENCRYPTED] = False
1295
- if encrypt_payload:
1296
- critical_data[comm_ct.COMM_SEND_MESSAGE.K_EE_ENCRYPTED_DATA] = "Error! No receiver address found!"
1297
-
1298
- # endif
1299
- msg_to_send = {
1300
- **critical_data,
1301
- comm_ct.COMM_SEND_MESSAGE.K_EE_ID: worker,
1302
- comm_ct.COMM_SEND_MESSAGE.K_SESSION_ID: session_id or self.name,
1303
- comm_ct.COMM_SEND_MESSAGE.K_INITIATOR_ID: self.name,
1304
- comm_ct.COMM_SEND_MESSAGE.K_SENDER_ADDR: self.bc_engine.address,
1305
- comm_ct.COMM_SEND_MESSAGE.K_TIME: dt.now().strftime("%Y-%m-%d %H:%M:%S.%f"),
1306
- }
1456
+ msg_to_send = self.__prepare_message(
1457
+ msg_data=critical_data,
1458
+ encrypt_message=self.encrypt_comms,
1459
+ destination_id=worker,
1460
+ session_id=session_id,
1461
+ )
1307
1462
  self.bc_engine.sign(msg_to_send, use_digest=True)
1308
1463
  if show_command:
1309
1464
  self.P(
@@ -1311,7 +1466,7 @@ class GenericSession(BaseDecentrAIObject):
1311
1466
  color='y',
1312
1467
  verbosity=1
1313
1468
  )
1314
- self._send_payload(worker, msg_to_send)
1469
+ self._send_command(worker, msg_to_send)
1315
1470
  return
1316
1471
 
1317
1472
  def _send_command_create_pipeline(self, worker, pipeline_config, **kwargs):
@@ -2470,6 +2625,35 @@ class GenericSession(BaseDecentrAIObject):
2470
2625
  def client_address(self):
2471
2626
  return self.get_client_address()
2472
2627
 
2628
+ def __wait_for_supervisors_net_mon_data(
2629
+ self,
2630
+ supervisor=None,
2631
+ timeout=10,
2632
+ min_supervisors=2
2633
+ ):
2634
+ # the following loop will wait for the desired number of supervisors to appear online
2635
+ # for the current session
2636
+ start = tm()
2637
+ result = False
2638
+ while (tm() - start) < timeout:
2639
+ if supervisor is not None:
2640
+ if supervisor in self.__current_network_statuses:
2641
+ result = True
2642
+ break
2643
+ elif len(self.__current_network_statuses) >= min_supervisors:
2644
+ result = True
2645
+ break
2646
+ sleep(0.1)
2647
+ elapsed = tm() - start
2648
+ # end while
2649
+ # done waiting for supervisors
2650
+ return result, elapsed
2651
+
2652
+
2653
+ def get_all_nodes_pipelines(self):
2654
+ # TODO: Bleo inject this function in __on_hb and maybe_process_net_config and dump result
2655
+ return self._dct_online_nodes_pipelines
2656
+
2473
2657
  def get_network_known_nodes(
2474
2658
  self,
2475
2659
  timeout=10,
@@ -2540,19 +2724,11 @@ class GenericSession(BaseDecentrAIObject):
2540
2724
  for k in mapping:
2541
2725
  res[k] = []
2542
2726
 
2543
- # the following loop will wait for the desired number of supervisors to appear online
2544
- # for the current session
2545
- start = tm()
2546
- while (tm() - start) < timeout:
2547
- if supervisor is not None:
2548
- if supervisor in self.__current_network_statuses:
2549
- break
2550
- elif len(self.__current_network_statuses) >= min_supervisors:
2551
- break
2552
- sleep(0.1)
2553
- elapsed = tm() - start
2554
- # end while
2555
- # done waiting for supervisors
2727
+ result, elapsed = self.__wait_for_supervisors_net_mon_data(
2728
+ supervisor=supervisor,
2729
+ timeout=timeout,
2730
+ min_supervisors=min_supervisors,
2731
+ )
2556
2732
  best_super = 'ERROR'
2557
2733
  best_super_alias = 'ERROR'
2558
2734
 
naeural_client/bc/base.py CHANGED
@@ -1314,4 +1314,4 @@ class BaseBlockEngine:
1314
1314
  else:
1315
1315
  self.P(f"dAuth URL is not invalid: {url}", color='r')
1316
1316
  #end if url is valid
1317
- return dct_env
1317
+ return dct_env
@@ -10,6 +10,7 @@ class PLUGIN_SIGNATURES:
10
10
  CHAIN_DIST_CUSTOM_JOB_01 = 'PROCESS_REAL_TIME_COLLECTED_DATA_CUSTOM_EXEC_CHAIN_DIST'
11
11
  TELEGRAM_BASIC_BOT_01 = 'TELEGRAM_BASIC_BOT_01'
12
12
  TELEGRAM_CONVERSATIONAL_BOT_01 = 'TELEGRAM_CONVERSATIONAL_BOT_01'
13
+ NET_CONFIG_MONITOR = 'NET_CONFIG_MONITOR'
13
14
  # INSERT_NEW_PLUGIN_HERE
14
15
 
15
16
 
@@ -10,7 +10,7 @@ class MqttSession(GenericSession):
10
10
  self._default_communicator = MQTTWrapper(
11
11
  log=self.log,
12
12
  config=self._config,
13
- send_channel_name=comm_ct.COMMUNICATION_CONFIG_CHANNEL,
13
+ send_channel_name=comm_ct.COMMUNICATION_PAYLOADS_CHANNEL,
14
14
  recv_channel_name=comm_ct.COMMUNICATION_PAYLOADS_CHANNEL,
15
15
  comm_type=comm_ct.COMMUNICATION_DEFAULT,
16
16
  recv_buff=self._payload_messages,
@@ -21,6 +21,7 @@ class MqttSession(GenericSession):
21
21
  self._heartbeats_communicator = MQTTWrapper(
22
22
  log=self.log,
23
23
  config=self._config,
24
+ send_channel_name=comm_ct.COMMUNICATION_CONFIG_CHANNEL,
24
25
  recv_channel_name=comm_ct.COMMUNICATION_CTRL_CHANNEL,
25
26
  comm_type=comm_ct.COMMUNICATION_HEARTBEATS,
26
27
  recv_buff=self._hb_messages,
@@ -37,6 +38,11 @@ class MqttSession(GenericSession):
37
38
  connection_name=self.name,
38
39
  verbosity=self._verbosity,
39
40
  )
41
+ self.__communicators = {
42
+ 'default': self._default_communicator,
43
+ 'heartbeats': self._heartbeats_communicator,
44
+ 'notifications': self._notifications_communicator,
45
+ }
40
46
  return super(MqttSession, self).startup()
41
47
 
42
48
  @property
@@ -64,9 +70,18 @@ class MqttSession(GenericSession):
64
70
  self._notifications_communicator.release()
65
71
  return
66
72
 
67
- def _send_payload(self, to, msg):
73
+ def _send_raw_message(self, to, msg, communicator='default'):
68
74
  payload = json.dumps(msg)
75
+ communicator_obj = self.__communicators.get(communicator, self._default_communicator)
76
+ communicator_obj._send_to = to
77
+ communicator_obj.send(payload)
78
+ return
69
79
 
70
- self._default_communicator._send_to = to
71
- self._default_communicator.send(payload)
80
+ def _send_payload(self, payload):
81
+ # `to` parameter will be added after migrating to segregated payloads.
82
+ self._send_raw_message(to=None, msg=payload, communicator='default')
72
83
  return
84
+
85
+ def _send_command(self, to, command):
86
+ self._send_raw_message(to, command, communicator='heartbeats')
87
+ return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: naeural_client
3
- Version: 2.6.14
3
+ Version: 2.6.15
4
4
  Summary: `naeural_client` is the Python SDK required for client app development for the Naeural Edge Protocol Edge Protocol framework
5
5
  Project-URL: Homepage, https://github.com/NaeuralEdgeProtocol/naeural_client
6
6
  Project-URL: Bug Tracker, https://github.com/NaeuralEdgeProtocol/naeural_client/issues
@@ -1,10 +1,10 @@
1
1
  naeural_client/__init__.py,sha256=YimqgDbjLuywsf8zCWE0EaUXH4MBUrqLxt0TDV558hQ,632
2
- naeural_client/_ver.py,sha256=suKXv38GGYBJ0RcB_6qcC-hc1VP14y80oKWh1Ov0_Xg,331
2
+ naeural_client/_ver.py,sha256=s5A-FwAfqI4BeZ8fzrRTwGs3LEc-m4EQ8BufoeG3kSI,331
3
3
  naeural_client/base_decentra_object.py,sha256=C4iwZTkhKNBS4VHlJs5DfElRYLo4Q9l1V1DNVSk1fyQ,4412
4
4
  naeural_client/plugins_manager_mixin.py,sha256=X1JdGLDz0gN1rPnTN_5mJXR8JmqoBFQISJXmPR9yvCo,11106
5
5
  naeural_client/base/__init__.py,sha256=hACh83_cIv7-PwYMM3bQm2IBmNqiHw-3PAfDfAEKz9A,259
6
6
  naeural_client/base/distributed_custom_code_presets.py,sha256=cvz5R88P6Z5V61Ce1vHVVh8bOkgXd6gve_vdESDNAsg,2544
7
- naeural_client/base/generic_session.py,sha256=p7NZoMZJEW-2Zb0CrJyXIgtlpqZcRW9If6p3R_EfzzE,97509
7
+ naeural_client/base/generic_session.py,sha256=Vw08ywfW03aN0_5kmXOF5-VkRthl7FwAXqJu3M3NDMs,104275
8
8
  naeural_client/base/instance.py,sha256=kcZJmjLBtx8Bjj_ysIOx1JmLA-qSpG7E28j5rq6IYus,20444
9
9
  naeural_client/base/pipeline.py,sha256=b4uNHrEIOlAtw4PGUx20dxwBhDck5__SrVXaHcSi8ZA,58251
10
10
  naeural_client/base/plugin_template.py,sha256=qGaXByd_JZFpjvH9GXNbT7KaitRxIJB6-1IhbKrZjq4,138123
@@ -14,7 +14,7 @@ naeural_client/base/webapp_pipeline.py,sha256=QmPLVmhP0CPdi0YuvbZEH4APYz2Amtw3gy
14
14
  naeural_client/base/payload/__init__.py,sha256=y8fBI8tG2ObNfaXFWjyWZXwu878FRYj_I8GIbHT4GKE,29
15
15
  naeural_client/base/payload/payload.py,sha256=x-au7l67Z_vfn_4R2C_pjZCaFuUVXHngJiGOfIAYVdE,2690
16
16
  naeural_client/bc/__init__.py,sha256=FQj23D1PrY06NUOARiKQi4cdj0-VxnoYgYDEht8lpr8,158
17
- naeural_client/bc/base.py,sha256=hVdk_Vxi94jMy6OJfbYVrbQgMCNNi3BgVOj_NCw5cKc,36159
17
+ naeural_client/bc/base.py,sha256=KC-wtymP9tEvXGG6wfiRirgshjW7_y58ylWjbe_lUWo,36160
18
18
  naeural_client/bc/chain.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  naeural_client/bc/ec.py,sha256=qI8l7YqiS4MNftlx-tF7IZUswrSeQc7KMn5OZ0fEaJs,23370
20
20
  naeural_client/certs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -31,7 +31,7 @@ naeural_client/comm/amqp_wrapper.py,sha256=hzj6ih07DnLQy2VSfA88giDIFHaCp9uSdGLTA
31
31
  naeural_client/comm/mqtt_wrapper.py,sha256=Ig3bFZkCbWd4y_Whn2PPa91Z3aLgNbNPau6Tn5yLPZ8,16167
32
32
  naeural_client/const/README.md,sha256=6OHesr-f5NBuuJGryEoi_TCu2XdlhfQYlDKx_IJoXeg,177
33
33
  naeural_client/const/__init__.py,sha256=MM6Zib6i7M2qWcMkLtLx14zqU-lE-u2uPHjNvbh2jAM,478
34
- naeural_client/const/apps.py,sha256=gIONTZUkqPveu3DwelyJWpbFMeIR9l6DlaNg-xEfK1A,611
34
+ naeural_client/const/apps.py,sha256=ePBiJXLuPfFOKuw-LJrT9OWbaodU7QApfDurIPNDoB4,655
35
35
  naeural_client/const/base.py,sha256=Ld6WuQeqm5FbARL_-xs3gXxpa46ypksHimAk1g4qanw,4467
36
36
  naeural_client/const/comms.py,sha256=La6JXWHexH8CfcBCKyT4fCIoeaoZlcm7KtZ57ab4ZgU,2201
37
37
  naeural_client/const/environment.py,sha256=iytmTDgbOjvORPwHQmc0K0r-xJx7dnnzNnqAJJiFCDA,870
@@ -47,7 +47,7 @@ naeural_client/default/instance/net_mon_01_plugin.py,sha256=u85i2AiYHkLJnam0wOx-
47
47
  naeural_client/default/instance/telegram_basic_bot_01_plugin.py,sha256=P_W2K_ng7svbhoIoYGvkGxa4v9UUoxuOAAgtoM36wDo,161
48
48
  naeural_client/default/instance/telegram_conversational_bot_01_plugin.py,sha256=XkyE-uNbtFnTSGA1nOf-XNmUipAUjhg0xXV1glRb7gc,179
49
49
  naeural_client/default/instance/view_scene_01_plugin.py,sha256=5kMhd23kL5AYCdOJzrdCqi2ohoQNvmpv8oE6hWQtUWk,720
50
- naeural_client/default/session/mqtt_session.py,sha256=dpQcBhhVZDo458v0IqJMZb1CsTn-TxXhYjNlyJp9Rp8,2414
50
+ naeural_client/default/session/mqtt_session.py,sha256=QdL0LPCqV3Fw0VSNgnsXWKJoxnkl17BtSYvEmhNU_zM,3079
51
51
  naeural_client/io_formatter/__init__.py,sha256=_wy7c-Z9kgb26jN7uNTDq88G7xZ3wI_ObuQd3QWNPkQ,85
52
52
  naeural_client/io_formatter/io_formatter_manager.py,sha256=MiZ70cGVD6hR99QiEk9wvJ_vADxpI-y2bTb0ITlMNI0,3451
53
53
  naeural_client/io_formatter/base/__init__.py,sha256=VmLHY35NCRR46lgjhcrwtFxmJIVOjX2ADV9wOXt9CKA,41
@@ -81,8 +81,8 @@ naeural_client/utils/__init__.py,sha256=mAnke3-MeRzz3nhQvhuHqLnpaaCSmDxicd7Ck9uw
81
81
  naeural_client/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_LtMyCY,1072
82
82
  naeural_client/utils/config.py,sha256=v7xHikr6Z5Sbvf3opYeMhYzGWD2pe0HlRwa-aGJzUh8,6323
83
83
  naeural_client/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
84
- naeural_client-2.6.14.dist-info/METADATA,sha256=tI-zL6Ld5JvnTFP9JDWK8sfx788VwVGABqbmCfubxUQ,13176
85
- naeural_client-2.6.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
- naeural_client-2.6.14.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
- naeural_client-2.6.14.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
- naeural_client-2.6.14.dist-info/RECORD,,
84
+ naeural_client-2.6.15.dist-info/METADATA,sha256=F37VysVyxouaFh-B_tDEHDG_AFQMH03gNF0UbbanqKI,13176
85
+ naeural_client-2.6.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
+ naeural_client-2.6.15.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
+ naeural_client-2.6.15.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
+ naeural_client-2.6.15.dist-info/RECORD,,