naeural-client 2.6.4__py3-none-any.whl → 2.6.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.
naeural_client/_ver.py CHANGED
@@ -1,4 +1,4 @@
1
- __VER__ = "2.6.4"
1
+ __VER__ = "2.6.6"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -50,6 +50,10 @@ class GenericSession(BaseDecentrAIObject):
50
50
  A Session manages `Pipelines` and handles all messages received from the communication server.
51
51
  The Session handles all callbacks that are user-defined and passed as arguments in the API calls.
52
52
  """
53
+
54
+ START_TIMEOUT = 30
55
+
56
+
53
57
  default_config = {
54
58
  "CONFIG_CHANNEL": {
55
59
  "TOPIC": "{}/{}/config"
@@ -165,6 +169,9 @@ class GenericSession(BaseDecentrAIObject):
165
169
  This is the root of the topics used by the SDK. It is used to create the topics for the communication channels.
166
170
  Defaults to "naeural"
167
171
  """
172
+
173
+ self.__at_least_one_node_peered = False
174
+ self.__at_least_a_netmon_received = False
168
175
 
169
176
  # TODO: maybe read config from file?
170
177
  self._config = {**self.default_config, **config}
@@ -466,21 +473,59 @@ class GenericSession(BaseDecentrAIObject):
466
473
  self._dct_node_addr_name[node_addr] = node_id
467
474
  return
468
475
 
469
- def __track_allowed_node(self, node_addr, dict_msg):
476
+ def __track_allowed_node_by_hb(self, node_addr, dict_msg):
470
477
  """
471
- Track if this session is allowed to send messages to node.
478
+ Track if this session is allowed to send messages to node using hb data
472
479
 
473
480
  Parameters
474
481
  ----------
475
482
  node_addr : str
476
483
  The address of the Naeural Edge Protocol edge node that sent the message.
484
+
477
485
  dict_msg : dict
478
- The message received from the communication server.
486
+ The message received from the communication server as a heartbeat of the object from netconfig
479
487
  """
480
488
  node_whitelist = dict_msg.get(HB.EE_WHITELIST, [])
481
489
  node_secured = dict_msg.get(HB.SECURED, False)
490
+
491
+ client_is_allowed = self.bc_engine.contains_current_address(node_whitelist)
482
492
 
483
- self._dct_can_send_to_node[node_addr] = not node_secured or self.bc_engine.address_no_prefix in node_whitelist or self.bc_engine.address == node_addr
493
+ self._dct_can_send_to_node[node_addr] = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
494
+ return
495
+
496
+ def __track_allowed_node_by_netmon(self, node_addr, dict_msg):
497
+ """
498
+ Track if this session is allowed to send messages to node using net-mon data
499
+
500
+ Parameters
501
+ ----------
502
+ node_addr : str
503
+ The address of the Naeural Edge Protocol edge node that sent the message.
504
+
505
+ dict_msg : dict
506
+ The message received from the communication server as a heartbeat of the object from netconfig
507
+ """
508
+ node_whitelist = dict_msg.get(PAYLOAD_DATA.NETMON_WHITELIST, [])
509
+ node_secured = dict_msg.get(PAYLOAD_DATA.NETMON_NODE_SECURED, False)
510
+
511
+ client_is_allowed = self.bc_engine.contains_current_address(node_whitelist)
512
+
513
+ self._dct_can_send_to_node[node_addr] = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
514
+ return
515
+
516
+
517
+ def __process_node_pipelines(self, node_addr, pipelines):
518
+ """
519
+ Given a list of pipeline configurations, create or update the pipelines for a node.
520
+ """
521
+ for config in pipelines:
522
+ pipeline_name = config[PAYLOAD_DATA.NAME]
523
+ pipeline: Pipeline = self._dct_online_nodes_pipelines[node_addr].get(pipeline_name, None)
524
+ if pipeline is not None:
525
+ pipeline._sync_configuration_with_remote({k.upper(): v for k, v in config.items()})
526
+ else:
527
+ self._dct_online_nodes_pipelines[node_addr][pipeline_name] = self.__create_pipeline_from_config(
528
+ node_addr, config)
484
529
  return
485
530
 
486
531
  def __on_heartbeat(self, dict_msg: dict, msg_node_addr, msg_pipeline, msg_signature, msg_instance):
@@ -516,19 +561,20 @@ class GenericSession(BaseDecentrAIObject):
516
561
 
517
562
  msg_active_configs = dict_msg.get(HB.CONFIG_STREAMS)
518
563
  if msg_active_configs is None:
519
- return
564
+ msg_active_configs = []
565
+ # at this point we dont return if no active configs are present
566
+ # as the protocol should NOT send a heartbeat with active configs to
567
+ # the entire network, only to the interested parties via net-config
520
568
 
521
569
  # default action
522
570
  if msg_node_addr not in self._dct_online_nodes_pipelines:
571
+ # this is ok here although we dont get the pipelines from the heartbeat
523
572
  self._dct_online_nodes_pipelines[msg_node_addr] = {}
524
- for config in msg_active_configs:
525
- pipeline_name = config[PAYLOAD_DATA.NAME]
526
- pipeline: Pipeline = self._dct_online_nodes_pipelines[msg_node_addr].get(pipeline_name, None)
527
- if pipeline is not None:
528
- pipeline._sync_configuration_with_remote({k.upper(): v for k, v in config.items()})
529
- else:
530
- self._dct_online_nodes_pipelines[msg_node_addr][pipeline_name] = self.__create_pipeline_from_config(
531
- msg_node_addr, config)
573
+
574
+ if len(msg_active_configs) > 0:
575
+ # this is for legacy and custom implementation where heartbeats still contain
576
+ # the pipeline configuration.
577
+ self.__process_node_pipelines(msg_node_addr, msg_active_configs)
532
578
 
533
579
  # TODO: move this call in `__on_message_default_callback`
534
580
  if self.__maybe_ignore_message(msg_node_addr):
@@ -543,7 +589,7 @@ class GenericSession(BaseDecentrAIObject):
543
589
 
544
590
  self.D("Received hb from: {}".format(msg_node_addr), verbosity=2)
545
591
 
546
- self.__track_allowed_node(msg_node_addr, dict_msg)
592
+ self.__track_allowed_node_by_hb(msg_node_addr, dict_msg)
547
593
 
548
594
  # call the custom callback, if defined
549
595
  if self.custom_on_heartbeat is not None:
@@ -613,7 +659,8 @@ class GenericSession(BaseDecentrAIObject):
613
659
  self,
614
660
  dict_msg: dict,
615
661
  msg_pipeline : str,
616
- msg_signature : str
662
+ msg_signature : str,
663
+ sender_addr: str,
617
664
  ):
618
665
  REQUIRED_PIPELINE = DEFAULT_PIPELINES.ADMIN_PIPELINE
619
666
  REQUIRED_SIGNATURE = PLUGIN_SIGNATURES.NET_MON_01
@@ -624,6 +671,7 @@ class GenericSession(BaseDecentrAIObject):
624
671
  ee_id = dict_msg.get(PAYLOAD_DATA.EE_ID, None)
625
672
  current_network = dict_msg.get(PAYLOAD_DATA.NETMON_CURRENT_NETWORK, {})
626
673
  if current_network:
674
+ self.__at_least_a_netmon_received = True
627
675
  all_addresses = [
628
676
  x[PAYLOAD_DATA.NETMON_ADDRESS] for x in current_network.values()
629
677
  ]
@@ -633,10 +681,30 @@ class GenericSession(BaseDecentrAIObject):
633
681
  ]
634
682
  self.P(f"Net config from <{sender_addr}> `{ee_id}`: {len(online_addresses)}/{len(all_addresses)}", color='y')
635
683
  self.__current_network_statuses[sender_addr] = current_network
684
+
685
+ for _ , node_data in current_network.items():
686
+ node_addr = node_data.get("address", None)
687
+ if node_addr is not None:
688
+ self.__track_allowed_node_by_netmon(node_addr, node_data)
689
+ nr_peers = sum([v for k, v in self._dct_can_send_to_node.items()])
690
+ if nr_peers > 0 and not self.__at_least_one_node_peered:
691
+ self.__at_least_one_node_peered = True
692
+ self.P(f"Received {PLUGIN_SIGNATURES.NET_MON_01} from {sender_addr}, so far {nr_peers} peers that allow me: {json.dumps(self._dct_can_send_to_node, indent=2)}", color='g')
693
+ # end for each node in network map
636
694
  # end if current_network is valid
637
695
  # end if NET_MON_01
638
696
  return
639
697
 
698
+
699
+ def __maybe_process_net_config(
700
+ self,
701
+ dict_msg: dict,
702
+ msg_pipeline : str,
703
+ msg_signature : str,
704
+ sender_addr: str,
705
+ ):
706
+ return
707
+
640
708
 
641
709
  # TODO: maybe convert dict_msg to Payload object
642
710
  # also maybe strip the dict from useless info for the user of the sdk
@@ -656,12 +724,16 @@ class GenericSession(BaseDecentrAIObject):
656
724
  ----------
657
725
  dict_msg : dict
658
726
  The message received from the communication server
727
+
659
728
  msg_node_addr : str
660
729
  The address of the Naeural Edge Protocol edge node that sent the message.
730
+
661
731
  msg_pipeline : str
662
732
  The name of the pipeline that sent the message.
733
+
663
734
  msg_signature : str
664
735
  The signature of the plugin that sent the message.
736
+
665
737
  msg_instance : str
666
738
  The name of the instance that sent the message.
667
739
  """
@@ -671,7 +743,19 @@ class GenericSession(BaseDecentrAIObject):
671
743
  if self.__maybe_ignore_message(msg_node_addr):
672
744
  return
673
745
 
674
- self.__maybe_process_net_mon(dict_msg, msg_pipeline, msg_signature)
746
+ self.__maybe_process_net_mon(
747
+ dict_msg=dict_msg,
748
+ msg_pipeline=msg_pipeline,
749
+ msg_signature=msg_signature,
750
+ sender_addr=msg_node_addr
751
+ )
752
+
753
+ self.__maybe_process_net_config(
754
+ dict_msg=dict_msg,
755
+ msg_pipeline=msg_pipeline,
756
+ msg_signature=msg_signature,
757
+ sender_addr=msg_node_addr
758
+ )
675
759
 
676
760
  # call the pipeline and instance defined callbacks
677
761
  for pipeline in self.own_pipelines:
@@ -727,6 +811,8 @@ class GenericSession(BaseDecentrAIObject):
727
811
 
728
812
  self.__running_main_loop_thread = True
729
813
  self._main_loop_thread.start()
814
+
815
+ # we could wait here for `self.__at_least_one_node_peered` but is not a good idea
730
816
  return
731
817
 
732
818
  def __handle_open_transactions(self):
@@ -847,10 +933,16 @@ class GenericSession(BaseDecentrAIObject):
847
933
  This method runs on a separate thread from the main thread, and it is responsible for handling all messages received from the communication server.
848
934
  We use it like this to avoid blocking the main thread, which is used by the user.
849
935
  """
936
+ self.__start_main_loop_time = tm()
850
937
  while self.__running_main_loop_thread:
851
938
  self.__maybe_reconnect()
852
939
  self.__handle_open_transactions()
853
940
  sleep(0.1)
941
+ if not self.__at_least_a_netmon_received:
942
+ if (tm() - self.__start_main_loop_time) > self.START_TIMEOUT:
943
+ msg = "Timeout waiting for NET_MON_01 message. Exiting..."
944
+ self.P(msg, color='r', show=True)
945
+ break
854
946
  # end while self.running
855
947
 
856
948
  self.P("Main loop thread exiting...", verbosity=2)
@@ -900,7 +992,7 @@ class GenericSession(BaseDecentrAIObject):
900
992
 
901
993
  return
902
994
 
903
- def sleep(self, wait=True):
995
+ def sleep(self, wait=True, close_session=True, close_pipelines=False):
904
996
  """
905
997
  Sleep for a given amount of time.
906
998
 
@@ -926,7 +1018,37 @@ class GenericSession(BaseDecentrAIObject):
926
1018
  callable_loop_condition = callable(wait) and wait()
927
1019
  except KeyboardInterrupt:
928
1020
  self.P("CTRL+C detected. Stopping loop.", color='r', verbosity=1)
1021
+
1022
+ if close_session:
1023
+ self.close(close_pipelines, wait_close=True)
929
1024
  return
1025
+
1026
+ def wait(
1027
+ self,
1028
+ seconds=10,
1029
+ close_session_on_timeout=True,
1030
+ close_pipeline_on_timeout=False
1031
+ ):
1032
+ """
1033
+ Wait for a given amount of time.
1034
+
1035
+ Parameters
1036
+ ----------
1037
+ seconds : int, float, optional
1038
+ The amount of time to wait, by default 10
1039
+
1040
+ close_session_on_timeout : bool, optional
1041
+ If `True`, will close the session when the time is up, by default True
1042
+
1043
+ close_pipeline_on_timeout : bool, optional
1044
+ If `True`, will close the pipelines when the time is up, by default False
1045
+ """
1046
+ self.run(
1047
+ wait=seconds,
1048
+ close_session=close_session_on_timeout,
1049
+ close_pipelines=close_pipeline_on_timeout
1050
+ )
1051
+ return
930
1052
 
931
1053
  # Utils
932
1054
  if True:
@@ -2352,6 +2474,7 @@ class GenericSession(BaseDecentrAIObject):
2352
2474
  allowed_only=False,
2353
2475
  supervisor=None,
2354
2476
  df_only=False,
2477
+ debug=False,
2355
2478
  ):
2356
2479
  """
2357
2480
  This function will return a Pandas dataframe known nodes in the network based on
@@ -2475,6 +2598,9 @@ class GenericSession(BaseDecentrAIObject):
2475
2598
  SESSION_CT.NETSTATS_NR_SUPERVISORS : len(self.__current_network_statuses),
2476
2599
  SESSION_CT.NETSTATS_ELAPSED : elapsed,
2477
2600
  })
2601
+ if debug:
2602
+ self.P(f"Peering:\n{json.dumps(self._dct_can_send_to_node, indent=2)}", color='y')
2603
+ self.P(f"Used netmon data from {best_super} ({best_super_alias}):\n{json.dumps(best_info, indent=2)}", color='y')
2478
2604
  if df_only:
2479
2605
  return dct_result[SESSION_CT.NETSTATS_REPORT]
2480
2606
  return dct_result
naeural_client/bc/base.py CHANGED
@@ -16,7 +16,7 @@ from cryptography.hazmat.primitives import serialization
16
16
 
17
17
  from ..utils.config import get_user_folder
18
18
 
19
- from ..const.base import BCctbase, BCct, DAUTH_SUBKEY, DAUTH_URL
19
+ from ..const.base import BCctbase, BCct, DAUTH_SUBKEY, DAUTH_URL, DAUTH_ENV_KEY
20
20
 
21
21
 
22
22
 
@@ -1217,6 +1217,7 @@ class BaseBlockEngine:
1217
1217
 
1218
1218
 
1219
1219
  def dauth_autocomplete(self, dauth_endp=None, add_env=True, debug=False, max_tries=5):
1220
+ MIN_LEN = 10
1220
1221
  dct_env = {}
1221
1222
  dct_result = {}
1222
1223
  done = False
@@ -1224,16 +1225,20 @@ class BaseBlockEngine:
1224
1225
  in_env = False
1225
1226
  url = dauth_endp
1226
1227
 
1227
- if url is None:
1228
+ if not isinstance(url, str) or len(url) < MIN_LEN:
1228
1229
  if isinstance(DAUTH_URL, str) and len(DAUTH_URL) > 0:
1229
1230
  url = DAUTH_URL
1230
- else:
1231
- url = os.environ.get('DAUTH_URL')
1231
+
1232
+ if DAUTH_ENV_KEY in os.environ:
1232
1233
  in_env = True
1234
+ url = os.environ[DAUTH_ENV_KEY]
1233
1235
 
1234
1236
  if isinstance(url, str) and len(url) > 0:
1235
1237
  if dauth_endp is None:
1236
- self.P("Found dAuth URL in environment: '{}'".format(url), color='g')
1238
+ if in_env:
1239
+ self.P("Found dAuth URL in environment: '{}'".format(url), color='g')
1240
+ else:
1241
+ self.P("Using default dAuth URL: '{}'".format(url), color='g')
1237
1242
 
1238
1243
  while not done:
1239
1244
  self.P(f"Trying dAuth `{url}` information... (try {tries})")
@@ -1275,4 +1280,7 @@ class BaseBlockEngine:
1275
1280
  if tries >= max_tries:
1276
1281
  done = True
1277
1282
  #end while
1283
+ else:
1284
+ self.P(f"dAuth URL is not invalid: {url}", color='r')
1285
+ #end if url is valid
1278
1286
  return dct_env
@@ -4,6 +4,7 @@ SB_ID = 'SB_ID' # change to SB_ID = EE_ID post mod from sb to ee
4
4
 
5
5
  DAUTH_URL = 'https://dauth.ratio1.ai/get_auth_data'
6
6
  DAUTH_SUBKEY = 'auth'
7
+ DAUTH_ENV_KEY = 'DAUTH_URL'
7
8
 
8
9
  class LocalInfo:
9
10
  LOCAL_INFO_FILE = 'local_info.json'
@@ -23,6 +23,7 @@ EE_ADDR = 'EE_ADDR'
23
23
  EE_WHITELIST = 'EE_WHITELIST'
24
24
  EE_IS_SUPER = 'EE_IS_SUPER'
25
25
  EE_FORMATTER = 'EE_FORMATTER'
26
+ EE_ID = 'EE_ID'
26
27
 
27
28
  SECURED = 'SECURED'
28
29
 
@@ -205,6 +205,7 @@ class PAYLOAD_DATA:
205
205
  NETMON_LAST_SEEN = 'last_seen_sec'
206
206
  NETMON_IS_SUPERVISOR = 'is_supervisor'
207
207
  NETMON_WHITELIST = 'whitelist'
208
+ NETMON_NODE_SECURED = 'secured'
208
209
 
209
210
 
210
211
  class NET_CONFIG:
@@ -212,4 +213,5 @@ class NET_CONFIG:
212
213
  REQUEST_COMMAND = "GET_CONFIG"
213
214
  NET_CONFIG_DATA = 'NET_CONFIG_DATA'
214
215
  OPERATION = 'OP'
215
- DESTINATION = 'DEST'
216
+ DESTINATION = 'DEST'
217
+ DATA = 'DATA'
@@ -91,6 +91,7 @@ class BaseLogger(object):
91
91
  if os.name == 'nt':
92
92
  os.system('color')
93
93
  self.__lib__ = lib_name
94
+ self.__folder_setup_done = False
94
95
  self.append_spaces = append_spaces
95
96
  self.show_time = show_time
96
97
  self.no_folders_no_save = no_folders_no_save
@@ -1055,8 +1056,14 @@ class BaseLogger(object):
1055
1056
  if dropbox and not "/DATA/" in upper:
1056
1057
  base_folder = self.get_dropbox_drive()
1057
1058
  return base_folder
1059
+
1060
+ def reload_config(self):
1061
+ self._configure_data_and_dirs(self.config_file, self.config_file_encoding)
1062
+ return
1058
1063
 
1059
1064
  def _configure_data_and_dirs(self, config_file, config_file_encoding=None):
1065
+ self.config_file_encoding = config_file_encoding
1066
+
1060
1067
  if self.no_folders_no_save:
1061
1068
  return
1062
1069
 
@@ -1082,7 +1089,7 @@ class BaseLogger(object):
1082
1089
  #endif no defaults for base/app folders
1083
1090
 
1084
1091
  if not self.silent:
1085
- print("Loaded config [{}]".format(config_file), flush=True)
1092
+ BaseLogger.print_color("Loaded config [{}]".format(config_file))
1086
1093
  self.config_file = config_file
1087
1094
  else:
1088
1095
  self.config_data = {
@@ -1090,8 +1097,9 @@ class BaseLogger(object):
1090
1097
  'APP_FOLDER' : self._app_folder
1091
1098
  }
1092
1099
  self.config_file = "default_config.txt"
1100
+
1093
1101
  if not self.silent:
1094
- print("No config file provided. Using default config.", flush=True)
1102
+ BaseLogger.print_color("No config file provided. Using default config.")
1095
1103
  #endif have or not config file
1096
1104
 
1097
1105
  self.config_data = {
@@ -1102,39 +1110,44 @@ class BaseLogger(object):
1102
1110
  matches = self.replace_secrets(self.config_data, allow_missing=True)
1103
1111
  if not self.silent:
1104
1112
  if len(matches) > 0:
1105
- print(" Config modified with following env vars: {}".format(matches))
1113
+ BaseLogger.print_color(" Config modified with following env vars: {}".format(matches))
1106
1114
  else:
1107
- print(" No secrets/template found in config")
1108
-
1109
- self._base_folder = self.expand_tilda(self._base_folder)
1110
- self._base_folder = self._get_cloud_base_folder(self._base_folder)
1111
- self._root_folder = os.path.abspath(self._base_folder)
1112
- self._base_folder = os.path.join(self._base_folder, self._app_folder)
1113
- if not self.silent:
1114
- print("BASE: {}".format(self._base_folder), flush=True)
1115
-
1116
- self._normalize_path_sep()
1117
-
1118
- if not os.path.isdir(self._base_folder):
1119
- print("{color_start}WARNING! Invalid app base folder '{base_folder}'! We create it automatically!{color_end}".format(
1120
- color_start=COLORS['r'],
1121
- base_folder=self._base_folder,
1122
- color_end=COLORS['__end__']
1123
- ), flush=True)
1124
- #endif
1115
+ BaseLogger.print_color(" No secrets/template found in config")
1116
+
1117
+ if not self.__folder_setup_done:
1118
+ # if not already done lets setup de folders
1119
+ self._base_folder = self.expand_tilda(self._base_folder)
1120
+ self._base_folder = self._get_cloud_base_folder(self._base_folder)
1121
+ self._root_folder = os.path.abspath(self._base_folder)
1122
+ self._base_folder = os.path.join(self._base_folder, self._app_folder)
1123
+
1124
+ if not self.silent:
1125
+ BaseLogger.print_color("BASE: {}".format(self._base_folder))
1125
1126
 
1126
- self._logs_dir = os.path.join(self._base_folder, self.get_logs_dir_name())
1127
- self._outp_dir = os.path.join(self._base_folder, self.get_output_dir_name())
1128
- self._data_dir = os.path.join(self._base_folder, self.get_data_dir_name())
1129
- self._modl_dir = os.path.join(self._base_folder, self.get_models_dir_name())
1127
+ self._normalize_path_sep()
1130
1128
 
1131
- self._setup_folders([
1132
- self._outp_dir,
1133
- self._logs_dir,
1134
- self._data_dir,
1135
- self._modl_dir
1136
- ])
1129
+ if not os.path.isdir(self._base_folder):
1130
+ BaseLogger.print_color(
1131
+ f"WARNING! Invalid app base folder '{self._base_folder}'! We create it automatically!",
1132
+ color='r'
1133
+ )
1134
+ #endif
1137
1135
 
1136
+ self._logs_dir = os.path.join(self._base_folder, self.get_logs_dir_name())
1137
+ self._outp_dir = os.path.join(self._base_folder, self.get_output_dir_name())
1138
+ self._data_dir = os.path.join(self._base_folder, self.get_data_dir_name())
1139
+ self._modl_dir = os.path.join(self._base_folder, self.get_models_dir_name())
1140
+
1141
+ self._setup_folders([
1142
+ self._outp_dir,
1143
+ self._logs_dir,
1144
+ self._data_dir,
1145
+ self._modl_dir
1146
+ ])
1147
+ self.__folder_setup_done = True
1148
+ else:
1149
+ BaseLogger.print_color("Folders already configured.", color='y')
1150
+ #endif apply only first time
1138
1151
  return
1139
1152
 
1140
1153
  @staticmethod
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: naeural_client
3
- Version: 2.6.4
3
+ Version: 2.6.6
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=PjIkiMwxccYumKTmIilKwwr-ukjI-vjW09AHPfEu9BM,330
2
+ naeural_client/_ver.py,sha256=UMYFIwE4ZXTXGAjXHvaICoKOZ23qedlElzJItHT6NXw,330
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=o-qY5Ml72597qM04cgugqzkN9n74LBLrDVOUEZmmgUs,92433
7
+ naeural_client/base/generic_session.py,sha256=Qkc7XTRcrlKT6vd4N28jGobnQuCSZ33phu16VPC5rg8,97074
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=Nlt-8PQrUcN5W2j67hZYmUNRZVQh-QXTqya06rwlFoA,34733
17
+ naeural_client/bc/base.py,sha256=kkRGYkAJ6ZCEUSKyUNpj8NW2kvhAtiuNNKe3ci3Py1s,35028
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
@@ -32,13 +32,13 @@ naeural_client/comm/mqtt_wrapper.py,sha256=Ig3bFZkCbWd4y_Whn2PPa91Z3aLgNbNPau6Tn
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
34
  naeural_client/const/apps.py,sha256=gIONTZUkqPveu3DwelyJWpbFMeIR9l6DlaNg-xEfK1A,611
35
- naeural_client/const/base.py,sha256=ToCqp_JW6mq3J2Ul2dJ3Xhp8gxSg7rg4nTYjIPtvDOI,4220
35
+ naeural_client/const/base.py,sha256=rlma-zwAXLtdLmHAHYuntxEgJyaJt_6N_Y5XjL-R7Gg,4248
36
36
  naeural_client/const/comms.py,sha256=La6JXWHexH8CfcBCKyT4fCIoeaoZlcm7KtZ57ab4ZgU,2201
37
37
  naeural_client/const/environment.py,sha256=iytmTDgbOjvORPwHQmc0K0r-xJx7dnnzNnqAJJiFCDA,870
38
38
  naeural_client/const/formatter.py,sha256=AW3bWlqf39uaqV4BBUuW95qKYfF2OkkU4f9hy3kSVhM,200
39
- naeural_client/const/heartbeat.py,sha256=jGHmKfeHTFOXJaKUT3o_ocnQyF-EpcLeunW-ifkYKfU,2534
39
+ naeural_client/const/heartbeat.py,sha256=xHZBX_NzHTklwA2_AEKR0SGdlbavMT4nirqjQg8WlTU,2550
40
40
  naeural_client/const/misc.py,sha256=VDCwwpf5bl9ltx9rzT2WPVP8B3mZFRufU1tSS5MO240,413
41
- naeural_client/const/payload.py,sha256=vHKxSrPXnfBTBwD_xp9Aw7nue0_gxz4r01YjXRYiTIM,6479
41
+ naeural_client/const/payload.py,sha256=40d5yKtiS_WnpWFXCFtEfOQ4ET6tCUVuwzXrghN23eI,6529
42
42
  naeural_client/default/__init__.py,sha256=ozU6CMMuWl0LhG8Ae3LrZ65a6tLrptfscVYGf83zjxM,46
43
43
  naeural_client/default/instance/__init__.py,sha256=w1de6OMj9a5GPGF-Wl1b_I_YAy9fWBEss2QnyPPyaB0,546
44
44
  naeural_client/default/instance/chain_dist_custom_job_01_plugin.py,sha256=QtHi3uXKsVs9eyMgbnvBVbMylErhV1Du4X2-7zDL7Y0,1915
@@ -57,7 +57,7 @@ naeural_client/io_formatter/default/a_dummy.py,sha256=qr9eUizQ-NN5jdXVzkaZKMaf9K
57
57
  naeural_client/io_formatter/default/aixp1.py,sha256=MX0TeUR4APA-qN3vUC6uzcz8Pssz5lgrQWo7td5Ri1A,3052
58
58
  naeural_client/io_formatter/default/default.py,sha256=gEy78cP2D5s0y8vQh4aHuxqz7D10gGfuiKF311QhrpE,494
59
59
  naeural_client/logging/__init__.py,sha256=b79X45VC6c37u32flKB2GAK9f-RR0ocwP0JDCy0t7QQ,33
60
- naeural_client/logging/base_logger.py,sha256=9H4ShdG4gsUCyznwficU4iym_kLZdNaxRAD_INfLV68,66392
60
+ naeural_client/logging/base_logger.py,sha256=a5_8SG6SZFmWKpD5gPemDWbWoin66-GZasHrqj0WUNA,66859
61
61
  naeural_client/logging/small_logger.py,sha256=m12hCb_H4XifJYYfgCAOUDkcXm-h4pSODnFf277OFVI,2937
62
62
  naeural_client/logging/logger_mixins/__init__.py,sha256=yQO7umlRvz63FeWpi-F9GRmC_MOHcNW6R6pwvZZBy3A,600
63
63
  naeural_client/logging/logger_mixins/class_instance_mixin.py,sha256=xUXE2VZgmrlrSrvw0f6GF1jlTnVLeVkIiG0bhlBfq3o,2741
@@ -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.4.dist-info/METADATA,sha256=pK2L5nmZU0IwXd8W6th-0_e5Qg4R73bFX9tbI0m3UoE,14618
85
- naeural_client-2.6.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
- naeural_client-2.6.4.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
- naeural_client-2.6.4.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
- naeural_client-2.6.4.dist-info/RECORD,,
84
+ naeural_client-2.6.6.dist-info/METADATA,sha256=SYrLhTGgqPaIAtgwU_GypoGDSo08qew0oOeokjbV4IY,14618
85
+ naeural_client-2.6.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
+ naeural_client-2.6.6.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
+ naeural_client-2.6.6.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
+ naeural_client-2.6.6.dist-info/RECORD,,