naeural-client 2.7.5__py3-none-any.whl → 2.7.7__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.7.5"
1
+ __VER__ = "2.7.7"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -42,6 +42,7 @@ from ..utils.config import (
42
42
 
43
43
 
44
44
  DEBUG_MQTT_SERVER = "r9092118.ala.eu-central-1.emqxsl.com"
45
+ SDK_NETCONFIG_REQUEST_DELAY = 300
45
46
 
46
47
 
47
48
  class GenericSession(BaseDecentrAIObject):
@@ -88,6 +89,7 @@ class GenericSession(BaseDecentrAIObject):
88
89
  on_notification=None,
89
90
  on_heartbeat=None,
90
91
  debug_silent=True,
92
+ debug=False,
91
93
  silent=False,
92
94
  verbosity=1,
93
95
  dotenv_path=None,
@@ -156,8 +158,13 @@ class GenericSession(BaseDecentrAIObject):
156
158
  As arguments, it has a reference to this Session object, the node name and the heartbeat payload.
157
159
  Defaults to None.
158
160
 
159
- debug_silent : bool, optional
161
+ debug_silent : bool, optional
160
162
  This flag will disable debug logs, set to 'False` for a more verbose log, by default True
163
+ Observation: Obsolete, will be removed
164
+
165
+ debug : bool, optional
166
+ This flag will enable debug logs, set to 'False` for a more verbose log, by default False
167
+
161
168
 
162
169
  silent : bool, optional
163
170
  This flag will disable all logs, set to 'False` for a more verbose log, by default False
@@ -174,9 +181,11 @@ class GenericSession(BaseDecentrAIObject):
174
181
  Defaults to True.
175
182
  """
176
183
 
184
+ debug = debug or not debug_silent
185
+
177
186
  self.__at_least_one_node_peered = False
178
187
  self.__at_least_a_netmon_received = False
179
-
188
+
180
189
  # TODO: maybe read config from file?
181
190
  self._config = {**self.default_config, **config}
182
191
 
@@ -204,6 +213,9 @@ class GenericSession(BaseDecentrAIObject):
204
213
  self._dct_can_send_to_node: dict[str, bool] = {}
205
214
  self._dct_node_last_seen_time = {} # key is node address
206
215
  self._dct_node_addr_name = {}
216
+
217
+ self._dct_netconfig_pipelines_requests = {}
218
+
207
219
  self.online_timeout = 60
208
220
  self.filter_workers = filter_workers
209
221
  self.__show_commands = show_commands
@@ -260,7 +272,7 @@ class GenericSession(BaseDecentrAIObject):
260
272
 
261
273
  super(GenericSession, self).__init__(
262
274
  log=log,
263
- DEBUG=not debug_silent,
275
+ DEBUG=debug,
264
276
  create_logger=True,
265
277
  silent=self.silent,
266
278
  local_cache_base_folder=local_cache_base_folder,
@@ -528,8 +540,7 @@ class GenericSession(BaseDecentrAIObject):
528
540
  **kwargs
529
541
  )
530
542
  self.bc_engine.sign(msg_to_send)
531
- if not self.silent:
532
- self.P(f'Sending encrypted payload to <{node_addr}>', color='y')
543
+ self.P(f'Sending encrypted payload to <{node_addr}>', color='d')
533
544
  self._send_payload(msg_to_send)
534
545
  return
535
546
 
@@ -551,10 +562,12 @@ class GenericSession(BaseDecentrAIObject):
551
562
  additional_data = {
552
563
  PAYLOAD_DATA.EE_PAYLOAD_PATH: [self.bc_engine.address, DEFAULT_PIPELINES.ADMIN_PIPELINE, PLUGIN_SIGNATURES.NET_CONFIG_MONITOR, None]
553
564
  }
565
+ self.D("Sending net-config request to <{}>".format(node_addr), color='y')
554
566
  self.send_encrypted_payload(
555
567
  node_addr=node_addr, payload=payload,
556
568
  additional_data=additional_data
557
569
  )
570
+ self._dct_netconfig_pipelines_requests[node_addr] = tm()
558
571
  return
559
572
 
560
573
  def __track_allowed_node_by_netmon(self, node_addr, dict_msg):
@@ -578,9 +591,17 @@ class GenericSession(BaseDecentrAIObject):
578
591
  self.__track_online_node(node_addr, node_alias)
579
592
 
580
593
  client_is_allowed = self.bc_engine.contains_current_address(node_whitelist)
581
- can_send = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
594
+ can_send = not node_secured or client_is_allowed or self.bc_engine.address == node_addr
582
595
  if node_addr not in self._dct_can_send_to_node and can_send:
583
- self.__request_pipelines_from_net_config_monitor(node_addr)
596
+ if node_online:
597
+ # only attempt to request pipelines if the node is online and if not recently requested
598
+ last_requested_by_netmon = self._dct_netconfig_pipelines_requests.get(node_addr, 0)
599
+ if tm() - last_requested_by_netmon > SDK_NETCONFIG_REQUEST_DELAY:
600
+ self.__request_pipelines_from_net_config_monitor(node_addr)
601
+ else:
602
+ self.D(f"Node <{node_addr}> is online but pipelines were recently requested", color='y')
603
+ else:
604
+ self.D(f"Node <{node_addr}> is offline thus NOT sending net-config request", color='y')
584
605
  # endif node seen for the first time
585
606
 
586
607
  self._dct_can_send_to_node[node_addr] = can_send
@@ -623,6 +644,7 @@ class GenericSession(BaseDecentrAIObject):
623
644
  The name of the instance that sent the message.
624
645
  """
625
646
  # extract relevant data from the message
647
+ self.D("<HB> Received hb from: {}".format(msg_node_addr), verbosity=2)
626
648
 
627
649
  if dict_msg.get(HB.HEARTBEAT_VERSION) == HB.V2:
628
650
  str_data = self.log.decompress_text(dict_msg[HB.ENCODED_DATA])
@@ -647,7 +669,7 @@ class GenericSession(BaseDecentrAIObject):
647
669
  # this is for legacy and custom implementation where heartbeats still contain
648
670
  # the pipeline configuration.
649
671
  pipeline_names = [x.get(PAYLOAD_DATA.NAME, None) for x in msg_active_configs]
650
- self.D(f'<HB>Received pipelines from <{msg_node_addr}>:{pipeline_names}', color='y')
672
+ self.D(f'<HB> Processing pipelines from <{msg_node_addr}>:{pipeline_names}', color='y')
651
673
  self.__process_node_pipelines(msg_node_addr, msg_active_configs)
652
674
 
653
675
  # TODO: move this call in `__on_message_default_callback`
@@ -661,7 +683,7 @@ class GenericSession(BaseDecentrAIObject):
661
683
  for transaction in open_transactions_copy:
662
684
  transaction.handle_heartbeat(dict_msg)
663
685
 
664
- self.D("Received hb from: {}".format(msg_node_addr), verbosity=2)
686
+ self.D("<HB> Received hb from: {}".format(msg_node_addr), verbosity=2)
665
687
 
666
688
  self.__track_allowed_node_by_hb(msg_node_addr, dict_msg)
667
689
 
@@ -746,27 +768,31 @@ class GenericSession(BaseDecentrAIObject):
746
768
  current_network = dict_msg.get(PAYLOAD_DATA.NETMON_CURRENT_NETWORK, {})
747
769
  if current_network:
748
770
  self.__at_least_a_netmon_received = True
749
- all_addresses = [
750
- x[PAYLOAD_DATA.NETMON_ADDRESS] for x in current_network.values()
751
- ]
752
- online_addresses = [
753
- x[PAYLOAD_DATA.NETMON_ADDRESS] for x in current_network.values()
754
- if x[PAYLOAD_DATA.NETMON_STATUS_KEY] == PAYLOAD_DATA.NETMON_STATUS_ONLINE
755
- ]
756
- self.P(f"Net config from <{sender_addr}> `{ee_id}`: {len(online_addresses)}/{len(all_addresses)}", color='y')
757
771
  self.__current_network_statuses[sender_addr] = current_network
758
-
772
+ online_addresses = []
773
+ all_addresses = []
759
774
  for _ , node_data in current_network.items():
760
- node_addr = node_data.get("address", None)
775
+ node_addr = node_data.get(PAYLOAD_DATA.NETMON_ADDRESS, None)
776
+ all_addresses.append(node_addr)
777
+ is_online = node_data.get(PAYLOAD_DATA.NETMON_STATUS_KEY) == PAYLOAD_DATA.NETMON_STATUS_ONLINE
778
+ node_alias = node_data.get(PAYLOAD_DATA.NETMON_EEID, None)
779
+ if is_online:
780
+ # no need to call here __track_online_node as it is already called
781
+ # in below in __track_allowed_node_by_netmon
782
+ online_addresses.append(node_addr)
783
+ # end if is_online
761
784
  if node_addr is not None:
762
785
  self.__track_allowed_node_by_netmon(node_addr, node_data)
763
- nr_peers = sum([v for k, v in self._dct_can_send_to_node.items()])
764
- if nr_peers > 0 and not self.__at_least_one_node_peered:
765
- self.__at_least_one_node_peered = True
766
- self.P(
767
- 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)}",
768
- color='g'
769
- )
786
+ # end if node_addr
787
+ # end for each node in network map
788
+ nr_peers = sum(self._dct_can_send_to_node.values())
789
+ self.P(f"Net config from <{sender_addr}> `{ee_id}`: {len(online_addresses)}/{len(all_addresses)}", color='y')
790
+ if nr_peers > 0 and not self.__at_least_one_node_peered:
791
+ self.__at_least_one_node_peered = True
792
+ self.P(
793
+ 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)}",
794
+ color='g'
795
+ )
770
796
  # end for each node in network map
771
797
  # end if current_network is valid
772
798
  # end if NET_MON_01
@@ -786,31 +812,37 @@ class GenericSession(BaseDecentrAIObject):
786
812
  if msg_pipeline.lower() == REQUIRED_PIPELINE.lower() and msg_signature.upper() == REQUIRED_SIGNATURE.upper():
787
813
  # extract data
788
814
  sender_addr = dict_msg.get(PAYLOAD_DATA.EE_SENDER, None)
815
+ short_sender_addr = sender_addr[:8] + '...' + sender_addr[-4:]
816
+ if self.client_address == sender_addr:
817
+ self.D("<NETCFG> Ignoring message from self", color='d')
789
818
  receiver = dict_msg.get(PAYLOAD_DATA.EE_DESTINATION, None)
790
819
  if not isinstance(receiver, list):
791
820
  receiver = [receiver]
792
821
  path = dict_msg.get(PAYLOAD_DATA.EE_PAYLOAD_PATH, [None, None, None, None])
793
822
  ee_id = dict_msg.get(PAYLOAD_DATA.EE_ID, None)
823
+ op = dict_msg.get(NET_CONFIG.NET_CONFIG_DATA, {}).get(NET_CONFIG.OPERATION, "UNKNOWN")
824
+ # drop any incoming request as we are not a net-config provider just a consumer
825
+ if op == NET_CONFIG.REQUEST_COMMAND:
826
+ self.P(f"<NETCFG> Dropping request from <{short_sender_addr}> `{ee_id}`", color='d')
827
+ return
794
828
 
795
829
  # check if I am allowed to see this payload
796
830
  if not self.bc_engine.contains_current_address(receiver):
797
- self.P(f"Received net-config from <{sender_addr}> `{ee_id}` but I am not in the receiver list: {receiver}", color='d')
831
+ self.P(f"<NETCFG> Received `{op}` from <{short_sender_addr}> `{ee_id}` but I am not in the receiver list: {receiver}", color='d')
798
832
  return
799
833
 
800
- # decrypt payload
834
+ # encryption check. By now all should be decrypted
801
835
  is_encrypted = dict_msg.get(PAYLOAD_DATA.EE_IS_ENCRYPTED, False)
802
836
  if not is_encrypted:
803
- self.P(f"Received net-config from <{sender_addr}> `{ee_id}` but it is not encrypted", color='r')
837
+ self.P(f"<NETCFG> Received from <{short_sender_addr}> `{ee_id}` but it is not encrypted", color='r')
804
838
  return
805
839
  net_config_data = dict_msg.get(NET_CONFIG.NET_CONFIG_DATA, {})
806
840
  received_pipelines = net_config_data.get('PIPELINES', [])
807
- self.D(f"Received {len(received_pipelines)} pipelines from <{sender_addr}>")
841
+ self.D(f"<NETCFG> Received {len(received_pipelines)} pipelines from <{sender_addr}>")
808
842
  new_pipelines = self.__process_node_pipelines(sender_addr, received_pipelines)
809
843
  pipeline_names = [x.name for x in new_pipelines]
810
- self.P(f'<NETCFG>Received pipelines from <{sender_addr}>:{pipeline_names}', color='y')
811
- self.D(f'[DEBUG][NETCFG]Received pipelines from <{sender_addr}>:\n{new_pipelines}', color='y')
812
-
813
- # load with same method as a hb
844
+ if len(new_pipelines) > 0:
845
+ self.P(f'<NETCFG> Received NEW pipelines from <{sender_addr}>:{pipeline_names}', color='y')
814
846
  return True
815
847
 
816
848
 
@@ -1163,7 +1195,8 @@ class GenericSession(BaseDecentrAIObject):
1163
1195
  self,
1164
1196
  seconds=10,
1165
1197
  close_session_on_timeout=True,
1166
- close_pipeline_on_timeout=False
1198
+ close_pipeline_on_timeout=False,
1199
+ **kwargs,
1167
1200
  ):
1168
1201
  """
1169
1202
  Wait for a given amount of time.
@@ -1178,11 +1211,21 @@ class GenericSession(BaseDecentrAIObject):
1178
1211
 
1179
1212
  close_pipeline_on_timeout : bool, optional
1180
1213
  If `True`, will close the pipelines when the time is up, by default False
1214
+
1215
+ **kwargs : dict
1216
+ Additional or replacement parameters to be passed to the `run` method:
1217
+ `close_session` : bool - If `True` will close the session when the loop is exited.
1218
+ `close_pipelines` : bool - If `True` will close all pipelines initiated by this session when the loop is exited.
1219
+
1181
1220
  """
1221
+ if "close_pipelines" in kwargs:
1222
+ close_pipeline_on_timeout = kwargs.get("close_pipelines")
1223
+ if "close_session" in kwargs:
1224
+ close_session_on_timeout = kwargs.get("close_session")
1182
1225
  self.run(
1183
1226
  wait=seconds,
1184
1227
  close_session=close_session_on_timeout,
1185
- close_pipelines=close_pipeline_on_timeout
1228
+ close_pipelines=close_pipeline_on_timeout,
1186
1229
  )
1187
1230
  return
1188
1231
 
@@ -2388,13 +2431,13 @@ class GenericSession(BaseDecentrAIObject):
2388
2431
  if telegram_bot_token is None:
2389
2432
  telegram_bot_token = os.getenv(telegram_bot_token_env_key)
2390
2433
  if telegram_bot_token is None:
2391
- message = f"Warning! No Telegram bot token provided as via env {ENVIRONMENT.TELEGRAM_BOT_TOKEN_ENV_KEY} or explicitly as `telegram_bot_token` param."
2434
+ message = f"Warning! No Telegram bot token provided as via env '{telegram_bot_token_env_key}' or explicitly as `telegram_bot_token` param."
2392
2435
  raise ValueError(message)
2393
2436
 
2394
2437
  if telegram_bot_name is None:
2395
- telegram_bot_name = os.getenv(telegram_bot_name_env_key)
2438
+ telegram_bot_name = os.getenv(telegram_bot_name_env_key, name)
2396
2439
  if telegram_bot_name is None:
2397
- message = f"Warning! No Telegram bot name provided as via env {ENVIRONMENT.TELEGRAM_BOT_NAME_ENV_KEY} or explicitly as `telegram_bot_name` param."
2440
+ message = f"Warning! No Telegram bot name provided as via env '{telegram_bot_name_env_key}' or explicitly as `telegram_bot_name` param."
2398
2441
  raise ValueError(message)
2399
2442
 
2400
2443
 
naeural_client/bc/base.py CHANGED
@@ -1514,6 +1514,7 @@ class BaseBlockEngine:
1514
1514
  debug=False,
1515
1515
  max_tries=5,
1516
1516
  network=None,
1517
+ return_full_data=False,
1517
1518
  **kwargs
1518
1519
  ):
1519
1520
  """
@@ -1662,4 +1663,6 @@ class BaseBlockEngine:
1662
1663
  # Invalid URL, thus dct_env will remain None
1663
1664
  self.P(f"dAuth URL is not invalid: {url}", color='r')
1664
1665
  #end if url is valid
1666
+ if return_full_data:
1667
+ return dct_response
1665
1668
  return dct_env
@@ -29,7 +29,7 @@ class ENVIRONMENT:
29
29
  EE_SECURED = 'EE_SECURED'
30
30
  AIXP_SECURED = 'AIXP_SECURED'
31
31
 
32
- TELEGRAM_BOT_TOKEN_ENV_KEY = 'TELEGRAM_BOT_TOKEN'
33
- TELEGRAM_BOT_NAME_ENV_KEY = 'TELEGRAM_BOT_NAME'
32
+ TELEGRAM_BOT_TOKEN_ENV_KEY = 'EE_TELEGRAM_BOT_TOKEN'
33
+ TELEGRAM_BOT_NAME_ENV_KEY = 'EE_TELEGRAM_BOT_NAME'
34
34
 
35
- TELEGRAM_API_AGENT_TOKEN_ENV_KEY = 'TELEGRAM_API_AGENT_TOKEN'
35
+ TELEGRAM_API_AGENT_TOKEN_ENV_KEY = 'EE_TELEGRAM_API_AGENT_TOKEN'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: naeural_client
3
- Version: 2.7.5
3
+ Version: 2.7.7
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=fzU2D33TdF4AMAfvqYcWnQR2ihxWc-UHM259WZKYV5M,330
2
+ naeural_client/_ver.py,sha256=OLKx8hnD71ZUP5b74nYB4l0k_HtixADmnEBuBvOqDu0,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=3Z7BGi1g5zIXDAUk-PCKsXVhQKaJldL9id2SDedbSIU,105872
7
+ naeural_client/base/generic_session.py,sha256=ZcfiPGYvp4hh_SU9W3Bp6N2ClwWvsB6jNB4amvwF8QI,108236
8
8
  naeural_client/base/instance.py,sha256=kcZJmjLBtx8Bjj_ysIOx1JmLA-qSpG7E28j5rq6IYus,20444
9
9
  naeural_client/base/pipeline.py,sha256=EvESG5UH5GwyAZbJWJk1irTzGYBuOUjl-8KjkCdgLVI,58574
10
10
  naeural_client/base/plugin_template.py,sha256=7YAFaND2iXoZLgtunjYkFf_TBGieFr3VdNLO3vCqzmM,138795
@@ -14,7 +14,7 @@ naeural_client/base/webapp_pipeline.py,sha256=ZNGqZ36DY076XVDfGu2Q61kCt3kxIJ4Mi4
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=sTdJs_qcg7SlanxizZ2IfPilUR_z7hsBhcFO1fl-Jw0,46457
17
+ naeural_client/bc/base.py,sha256=afXeOiPjA6_md3MGfuXwYIFTh7vErjU7vYK-rpQ_WRw,46536
18
18
  naeural_client/bc/chain.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  naeural_client/bc/ec.py,sha256=-HPfKpYAqy_eZpiJf3gWR2L4ZDDP7fZY2uwdNYYmS80,23868
20
20
  naeural_client/certs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -36,7 +36,7 @@ naeural_client/const/__init__.py,sha256=MM6Zib6i7M2qWcMkLtLx14zqU-lE-u2uPHjNvbh2
36
36
  naeural_client/const/apps.py,sha256=ePBiJXLuPfFOKuw-LJrT9OWbaodU7QApfDurIPNDoB4,655
37
37
  naeural_client/const/base.py,sha256=g3II1Ys-1sjr1OG-sDJyRCV3F48VnxKQc7zTBPn-7FE,6510
38
38
  naeural_client/const/comms.py,sha256=La6JXWHexH8CfcBCKyT4fCIoeaoZlcm7KtZ57ab4ZgU,2201
39
- naeural_client/const/environment.py,sha256=iytmTDgbOjvORPwHQmc0K0r-xJx7dnnzNnqAJJiFCDA,870
39
+ naeural_client/const/environment.py,sha256=RpdDhDgB8NgRoFTk28eODigf9y0WcT9lul6mBOD029w,879
40
40
  naeural_client/const/formatter.py,sha256=AW3bWlqf39uaqV4BBUuW95qKYfF2OkkU4f9hy3kSVhM,200
41
41
  naeural_client/const/heartbeat.py,sha256=xHZBX_NzHTklwA2_AEKR0SGdlbavMT4nirqjQg8WlTU,2550
42
42
  naeural_client/const/misc.py,sha256=VDCwwpf5bl9ltx9rzT2WPVP8B3mZFRufU1tSS5MO240,413
@@ -84,8 +84,8 @@ naeural_client/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_L
84
84
  naeural_client/utils/config.py,sha256=QDrVywnhmf1k-sAb5jIBHZ_80TjNZk02uRG-t8mYLKQ,7413
85
85
  naeural_client/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
86
86
  naeural_client/utils/oracle_sync/oracle_tester.py,sha256=GmZwu2JM9_UB2K-4rKB3o0RgWLqM-7Im6HwBnQLXmHI,25312
87
- naeural_client-2.7.5.dist-info/METADATA,sha256=_jpKW1DCVrbH8SG_EBGU0h-P_IJJt_sQlxR-swuuRwc,12353
88
- naeural_client-2.7.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
89
- naeural_client-2.7.5.dist-info/entry_points.txt,sha256=CTua17GUrRa4aXeafezGC9TiWKGKQzwTjQmB2jyj22g,91
90
- naeural_client-2.7.5.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
91
- naeural_client-2.7.5.dist-info/RECORD,,
87
+ naeural_client-2.7.7.dist-info/METADATA,sha256=sROG0Xv0ef9ZdLou3W3d4FBhy8sYOiNyknRjy6gL8oU,12353
88
+ naeural_client-2.7.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
89
+ naeural_client-2.7.7.dist-info/entry_points.txt,sha256=CTua17GUrRa4aXeafezGC9TiWKGKQzwTjQmB2jyj22g,91
90
+ naeural_client-2.7.7.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
91
+ naeural_client-2.7.7.dist-info/RECORD,,