naeural-client 2.1.0__py3-none-any.whl → 2.1.1__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.1.0"
1
+ __VER__ = "2.1.1"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -1724,25 +1724,32 @@ class GenericSession(BaseDecentrAIObject):
1724
1724
  **kwargs
1725
1725
  ):
1726
1726
 
1727
+ assert callable(message_handler), "The `message_handler` method parameter must be provided."
1728
+
1727
1729
  if telegram_bot_token is None:
1728
1730
  telegram_bot_token = os.getenv(telegram_bot_token_env_key)
1729
1731
  if telegram_bot_token is None:
1730
1732
  message = f"Warning! No Telegram bot token provided as via env {ENVIRONMENT.TELEGRAM_BOT_TOKEN_ENV_KEY} or explicitly as `telegram_bot_token` param."
1731
1733
  raise ValueError(message)
1732
1734
 
1733
- b64code = self._get_base64_code(message_handler)
1734
1735
 
1735
1736
  pipeline: Pipeline = self.create_pipeline(
1736
1737
  node=node,
1737
1738
  name=name,
1738
1739
  # default TYPE is "Void"
1739
1740
  )
1740
-
1741
+
1742
+ func_name, func_args, func_base64_code = pipeline._get_method_data(message_handler)
1743
+ if len(func_args) != 2:
1744
+ raise ValueError("The message handler function must have exactly 2 arguments: `instance` and `data`.")
1745
+
1741
1746
  instance = pipeline.create_plugin_instance(
1742
1747
  signature=signature,
1743
1748
  instance_id=self.log.get_unique_id(),
1744
1749
  telegram_bot_token=telegram_bot_token,
1745
- message_handler=b64code,
1750
+ message_handler=func_base64_code,
1751
+ message_handler_args=func_args, # mandatory message and user
1752
+ message_handler_name=func_name, # not mandatory
1746
1753
  **kwargs
1747
1754
  )
1748
1755
  return pipeline, instance
@@ -1852,3 +1859,10 @@ class GenericSession(BaseDecentrAIObject):
1852
1859
  # end for detach
1853
1860
 
1854
1861
  return lst_result_payload
1862
+
1863
+ def get_client_address(self):
1864
+ return self.bc_engine.address
1865
+
1866
+ @property
1867
+ def client_address(self):
1868
+ return self.get_client_address()
@@ -202,6 +202,7 @@ class Instance():
202
202
 
203
203
  return f"<Instance: {node_addr}/{pipeline_name}/{signature}/{instance_id}>"
204
204
 
205
+
205
206
  def _is_tainted(self):
206
207
  """
207
208
  Check if the instance has a proposed configuration.
@@ -213,6 +214,7 @@ class Instance():
213
214
  """
214
215
  return self.proposed_config is not None
215
216
 
217
+
216
218
  def _get_config_dictionary(self):
217
219
  """
218
220
  Get the configuration of the instance as a dictionary.
@@ -229,6 +231,7 @@ class Instance():
229
231
 
230
232
  return config_dict
231
233
 
234
+
232
235
  def _get_proposed_config_dictionary(self, full=False):
233
236
  """
234
237
  Get the proposed configuration of the instance as a dictionary.
@@ -249,6 +252,7 @@ class Instance():
249
252
 
250
253
  return proposed_config_dict
251
254
 
255
+
252
256
  def _apply_staged_config(self, verbose=False):
253
257
  """
254
258
  Apply the staged configuration to the instance.
@@ -264,6 +268,7 @@ class Instance():
264
268
  self.__staged_config = None
265
269
  return
266
270
 
271
+
267
272
  def _discard_staged_config(self, fail_reason: str):
268
273
  """
269
274
  Discard the staged configuration for the instance.
@@ -274,6 +279,7 @@ class Instance():
274
279
  self.__staged_config = None
275
280
  return
276
281
 
282
+
277
283
  def _stage_proposed_config(self):
278
284
  """
279
285
  Stage the proposed configuration for the instance.
@@ -291,6 +297,7 @@ class Instance():
291
297
  self.__was_last_operation_successful = None
292
298
  return
293
299
 
300
+
294
301
  def _handle_instance_command_success(self):
295
302
  """
296
303
  Handle the success of the instance command.
@@ -299,6 +306,7 @@ class Instance():
299
306
  self.__was_last_operation_successful = True
300
307
  return
301
308
 
309
+
302
310
  def _handle_instance_command_failure(self, fail_reason: str):
303
311
  """
304
312
  Handle the failure of the instance command.
@@ -307,6 +315,7 @@ class Instance():
307
315
  self.__was_last_operation_successful = False
308
316
  return
309
317
 
318
+
310
319
  def __register_transaction_for_instance_command(self, session_id: str = None, timeout: float = 0) -> list[Transaction]:
311
320
  """
312
321
  Register a new transaction for the instance command.
@@ -340,6 +349,7 @@ class Instance():
340
349
 
341
350
  return transactions
342
351
 
352
+
343
353
  def _get_instance_update_required_responses(self):
344
354
  """
345
355
  Get the responses required to update the instance.
@@ -356,6 +366,7 @@ class Instance():
356
366
 
357
367
  return responses
358
368
 
369
+
359
370
  def _get_instance_remove_required_responses(self):
360
371
  """
361
372
  Get the responses required to delete the instance.
@@ -371,6 +382,23 @@ class Instance():
371
382
 
372
383
  return responses
373
384
 
385
+ def _get_method_data(self, method: callable):
386
+ """
387
+ Get the full signature and definition of a method.
388
+
389
+ Parameters
390
+ ----------
391
+
392
+ method : callable
393
+ The method to get the signature and definition for.
394
+
395
+ Returns
396
+ -------
397
+ tuple
398
+ A tuple containing the name, arguments and base64 code of the method.
399
+ """
400
+ return self.pipeline._get_method_data(method)
401
+
374
402
  # API
375
403
  if True:
376
404
  @property
@@ -399,10 +427,12 @@ class Instance():
399
427
  """
400
428
  return self.__was_last_operation_successful
401
429
 
430
+
402
431
  def _sync_configuration_with_remote(self, config):
403
432
  self.config = {**self.config, **config}
404
433
  return
405
434
 
435
+
406
436
  def update_instance_config(self, config={}, **kwargs):
407
437
  """
408
438
  Update the configuration of the instance.
@@ -438,6 +468,7 @@ class Instance():
438
468
 
439
469
  return
440
470
 
471
+
441
472
  def send_instance_command(self, command, payload=None, command_params=None, wait_confirmation=True, session_id=None, timeout=10):
442
473
  """
443
474
  Send a command to the instance.
@@ -495,6 +526,7 @@ class Instance():
495
526
  return transactions
496
527
  return
497
528
 
529
+
498
530
  def close(self):
499
531
  """
500
532
  Close the instance.
@@ -502,20 +534,24 @@ class Instance():
502
534
  self.pipeline.remove_plugin_instance(self)
503
535
  return
504
536
 
537
+
505
538
  def stop(self):
506
539
  """
507
540
  Close the instance. Alias for `close`.
508
541
  """
509
542
  self.close()
510
543
 
544
+
511
545
  def P(self, *args, **kwargs):
512
546
  self.log.P(*args, **kwargs)
513
547
  return
514
548
 
549
+
515
550
  def D(self, *args, **kwargs):
516
551
  self.log.D(*args, **kwargs)
517
552
  return
518
553
 
554
+
519
555
  def temporary_attach(self, on_data=None, on_notification=None):
520
556
  """
521
557
  Attach a temporary callback to the instance.
@@ -542,6 +578,7 @@ class Instance():
542
578
 
543
579
  return attachment
544
580
 
581
+
545
582
  def temporary_detach(self, attachment):
546
583
  """
547
584
  Detach a temporary callback from the instance.
@@ -555,6 +592,7 @@ class Instance():
555
592
  self._remove_temporary_on_notification_callback(attachment)
556
593
  return
557
594
 
595
+
558
596
  def convert_to_specialized_class(self, specialized_class):
559
597
  """
560
598
  Convert the object to a specialized class.
@@ -564,6 +602,7 @@ class Instance():
564
602
  self.__class__ = specialized_class
565
603
  return self
566
604
 
605
+
567
606
  def send_instance_command_and_wait_for_response_payload(self, command, payload=None, command_params=None, timeout_command=10, timeout_response_payload=3, response_params_key="COMMAND_PARAMS"):
568
607
  """
569
608
  Send a command to the instance and wait for the response payload.
@@ -664,6 +664,7 @@ class Pipeline(BaseCodeChecker):
664
664
 
665
665
  return self.code_to_base64(plain_code, verbose=False)
666
666
 
667
+
667
668
  # Message handling
668
669
  if True:
669
670
  def _on_data(self, signature, instance_id, data):
@@ -1497,3 +1498,5 @@ class Pipeline(BaseCodeChecker):
1497
1498
  Return the node id of the pipeline.
1498
1499
  """
1499
1500
  return self.session.get_node_name(self.node_addr)
1501
+
1502
+
@@ -428,7 +428,15 @@ class BaseCodeChecker:
428
428
 
429
429
  return res
430
430
 
431
- def _get_method_from_custom_code(self, str_b64code, debug=False, result_vars=RESULT_VARS, self_var=None, modify=True, method_arguments=[]):
431
+ def _get_method_from_custom_code(
432
+ self,
433
+ str_b64code,
434
+ debug=False,
435
+ result_vars=RESULT_VARS,
436
+ self_var=None,
437
+ modify=True,
438
+ method_arguments=[]
439
+ ):
432
440
  exec_code__result_vars = result_vars
433
441
  exec_code__debug = debug
434
442
  exec_code__self_var = self_var
@@ -470,8 +478,9 @@ class BaseCodeChecker:
470
478
  exec_code__errors = ["Cannot encapsulate code in method. No return statement found."]
471
479
  return exec_code__result_var, exec_code__errors, exec_code__warnings
472
480
  # endif can encapsulate code in method
473
-
474
- exec(exec_code__code)
481
+ if exec_code__debug:
482
+ self.__msg("DEBUG EXEC: Encapsulated code: \n{}".format(exec_code__code))
483
+ exec(exec_code__code) # now we execute the method definition code not the actual method
475
484
  if exec_code__debug:
476
485
  self.__msg("DEBUG EXEC: locals(): \n{}".format(locals()))
477
486
  for _var in exec_code__result_vars:
@@ -521,11 +530,37 @@ class BaseCodeChecker:
521
530
  plain_code = '\n'.join([line.rstrip()[indent:] for line in plain_code])
522
531
 
523
532
  return plain_code
533
+
534
+ def _get_method_data(self, method: callable):
535
+ """
536
+ Get the full signature and definition of a method.
537
+
538
+ Parameters
539
+ ----------
540
+
541
+ method : callable
542
+ The method to get the signature and definition for.
543
+
544
+ Returns
545
+ -------
546
+ tuple
547
+ A tuple containing the name, arguments and base64 code of the method.
548
+ """
549
+ import inspect
550
+
551
+ name = method.__name__
552
+ args = list(map(str, inspect.signature(method).parameters.values()))
553
+ if args[0] in ['self', 'cls', 'plugin']:
554
+ args = args[1:]
555
+ source = self.get_function_source_code(method)
556
+ base64_code = self.code_to_base64(source)
557
+
558
+ return name, args, base64_code
524
559
 
525
560
 
526
561
  if __name__ == '__main__':
527
562
 
528
- def some_function(x):
563
+ def some_function(plugin, x):
529
564
  """
530
565
  A simple function that adds 1 to the input.
531
566
 
@@ -539,9 +574,44 @@ if __name__ == '__main__':
539
574
  _type_
540
575
  _description_
541
576
  """
577
+ print(f"Called by: {plugin}")
542
578
  return x + 1
543
579
 
580
+
581
+ class SomeClass:
582
+ def __init__(self, eng : BaseCodeChecker, str_b64code, func_args):
583
+ self.eng : BaseCodeChecker = eng
584
+ self._func, _, _ = eng._get_method_from_custom_code(
585
+ str_b64code=str_b64code,
586
+ self_var='plugin',
587
+ method_arguments=["plugin"] + func_args,
588
+ debug=False
589
+ )
590
+ return
591
+
592
+
593
+ def my_func(self, a):
594
+ res = self._func(x=a, plugin=self)
595
+ return res
596
+
597
+
544
598
  checker = BaseCodeChecker()
545
599
  source_code = checker.get_function_source_code(some_function)
546
600
  print("some_function:\n" + source_code)
601
+
602
+ name, args, b64code = checker._get_method_data(some_function)
603
+ print(f"Method name: {name}")
604
+ print(f"Method args: {args}")
605
+ print(f"Method code: {b64code}")
606
+
607
+ target = SomeClass(checker, str_b64code=b64code, func_args=args)
608
+
609
+ print(some_function(x=9.1, plugin=None))
610
+ print(target.my_func(9.1))
611
+
612
+
613
+
614
+
615
+
616
+
547
617
 
@@ -3,3 +3,5 @@ from ...const import PLUGIN_SIGNATURES
3
3
 
4
4
  class BasicTelegramBot01(Instance):
5
5
  signature = PLUGIN_SIGNATURES.BASIC_TELEGRAM_BOT_01
6
+
7
+
@@ -12,13 +12,10 @@ class CustomWebApp01(Instance):
12
12
  return deepcopy(self.config.get("ENDPOINTS", []))
13
13
 
14
14
  def get_endpoint_fields(self, method: callable):
15
- import inspect
16
-
17
- name = method.__name__
18
- args = list(map(str, inspect.signature(method).parameters.values()))[1:]
19
- base64_code = self.pipeline._get_base64_code(method)
20
-
21
- return name, args, base64_code
15
+ """
16
+ A aliast for get_method_data: it returns the name, args and base64 code of a method.
17
+ """
18
+ return self._get_method_data(method)
22
19
 
23
20
 
24
21
  def get_proposed_assets(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: naeural_client
3
- Version: 2.1.0
3
+ Version: 2.1.1
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/Naeural Edge ProtocolEdgeProtocol/naeural_client
6
6
  Project-URL: Bug Tracker, https://github.com/Naeural Edge ProtocolEdgeProtocol/naeural_client/issues
@@ -1,12 +1,12 @@
1
1
  naeural_client/__init__.py,sha256=UKEDGS0wFYyxwmhEAKJGecO2vYbIfRYUP4SQgnK10IE,578
2
- naeural_client/_ver.py,sha256=PKIJgoKWB4wskSQA9KvdwJkGx2b-A3tKTo2Rq6DMhdw,330
2
+ naeural_client/_ver.py,sha256=uXJ6vSOerh941OWnXiM13FiA3hI-oi_0TjiaLu54uAQ,330
3
3
  naeural_client/base_decentra_object.py,sha256=qDBpitcyhr1eEXPD8cGFtcNPNf71fqNRsmOEcCpx4sM,4180
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=azhJGCXstzBFQjWqW1z5OjwtSn2nkoPCNsSIcag5hIE,69231
8
- naeural_client/base/instance.py,sha256=m6IKOWuT5GsZVSdFNdcR-ImJTpTdHqNoMe8KQlEK3Gc,19970
9
- naeural_client/base/pipeline.py,sha256=fWwSNUvvrVvJYzxRBCKTt1f9_pci1hCBiG2LtoyOpMU,57512
7
+ naeural_client/base/generic_session.py,sha256=kjeLYdsq9Z8vnbCL9JA8abbFqBb-hhYsL4imRIBGPbU,69818
8
+ naeural_client/base/instance.py,sha256=kcZJmjLBtx8Bjj_ysIOx1JmLA-qSpG7E28j5rq6IYus,20444
9
+ naeural_client/base/pipeline.py,sha256=KwcPWD2XMvHotWFMpcnIycFhqiNnZuyUTUWiLU0PM5Y,57519
10
10
  naeural_client/base/plugin_template.py,sha256=qGaXByd_JZFpjvH9GXNbT7KaitRxIJB6-1IhbKrZjq4,138123
11
11
  naeural_client/base/responses.py,sha256=ZKBZmRhYDv8M8mQ5C_ahGsQvtWH4b9ImRcuerQdZmNw,6937
12
12
  naeural_client/base/transaction.py,sha256=bfs6td5M0fINgPQNxhrl_AUjb1YiilLDQ-Cd_o3OR_E,5146
@@ -19,7 +19,7 @@ naeural_client/bc/ec.py,sha256=8ryEvc3__lVXSoYxd1WoTy9c8uC5Q_8R1uME7CeloIg,8578
19
19
  naeural_client/certs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  naeural_client/certs/r9092118.ala.eu-central-1.emqxsl.com.crt,sha256=y-6io0tseyx9-a4Pmde1z1gPULtJNSYUpG_YFkYaMKU,1337
21
21
  naeural_client/code_cheker/__init__.py,sha256=pwkdeZGVL16ZA4Qf2mRahEhoOvKhL7FyuQbMFLr1E5M,33
22
- naeural_client/code_cheker/base.py,sha256=WIHP8LICypTBt7HR0FeC1KtIQ-PASTPaeFmCKvT5vuU,17190
22
+ naeural_client/code_cheker/base.py,sha256=toYgYFziH5x4Gqo0VedEMsANsBZAJd13mvKhRf28AQc,18907
23
23
  naeural_client/code_cheker/checker.py,sha256=QWupeM7ToancVIq1tRUxRNUrI8B5l5eoY0kDU4-O5aE,7365
24
24
  naeural_client/comm/__init__.py,sha256=za3B2HUKNXzYtjElMgGM9xbxNsdQfFY4JB_YzdyFkVU,76
25
25
  naeural_client/comm/amqp_wrapper.py,sha256=hzj6ih07DnLQy2VSfA88giDIFHaCp9uSdGLTA-IFE4s,8535
@@ -36,9 +36,9 @@ naeural_client/const/misc.py,sha256=1ypROmZsOyp_8zG2LARwPeo-YfXuyYqZnml0elTP4kw,
36
36
  naeural_client/const/payload.py,sha256=k24vH9iJIBBPnCXx7HAEuli2fNAETK7h8ZuVKyKLgbk,5725
37
37
  naeural_client/default/__init__.py,sha256=ozU6CMMuWl0LhG8Ae3LrZ65a6tLrptfscVYGf83zjxM,46
38
38
  naeural_client/default/instance/__init__.py,sha256=pHR9_5t3xv9ug3nu-8202yW-rqq-KR3C_L5N2xaADTA,548
39
- naeural_client/default/instance/basic_telegram_bot_01_plugin.py,sha256=STaIwtGCnEZdvxm7cF9NIQeZL5Zlru1c4cMSHKJc5pQ,159
39
+ naeural_client/default/instance/basic_telegram_bot_01_plugin.py,sha256=4674YFg5DfGO8_bYA1Uo77duZgKYGFX1J0Xp8YzjyPM,161
40
40
  naeural_client/default/instance/chain_dist_custom_job_01_plugin.py,sha256=QtHi3uXKsVs9eyMgbnvBVbMylErhV1Du4X2-7zDL7Y0,1915
41
- naeural_client/default/instance/custom_web_app_01_plugin.py,sha256=JblmfDa8ICppHItzEqU2HBSgT0nzZy9NWzgUHQ2sffw,4854
41
+ naeural_client/default/instance/custom_web_app_01_plugin.py,sha256=ZDe-QXmr6KLyUx5wzA3xVrMPg8yHnWLUbGjZtB0PFgg,4785
42
42
  naeural_client/default/instance/net_mon_01_plugin.py,sha256=u85i2AiYHkLJnam0wOx-m71hlp0EYyNtk3JwbkOrvHg,1208
43
43
  naeural_client/default/instance/view_scene_01_plugin.py,sha256=5kMhd23kL5AYCdOJzrdCqi2ohoQNvmpv8oE6hWQtUWk,720
44
44
  naeural_client/default/session/mqtt_session.py,sha256=dpQcBhhVZDo458v0IqJMZb1CsTn-TxXhYjNlyJp9Rp8,2414
@@ -74,7 +74,7 @@ naeural_client/logging/tzlocal/windows_tz.py,sha256=Sv9okktjZJfRGGUOOppsvQuX_eXy
74
74
  naeural_client/utils/__init__.py,sha256=mAnke3-MeRzz3nhQvhuHqLnpaaCSmDxicd7Ck9uwpmI,77
75
75
  naeural_client/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_LtMyCY,1072
76
76
  naeural_client/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
77
- naeural_client-2.1.0.dist-info/METADATA,sha256=I71wSC0lZI0XDuh8j1mIcyHoxL8Y5SNcB0d_K31BTP0,14457
78
- naeural_client-2.1.0.dist-info/WHEEL,sha256=wukiCwsxxsuzcQTdnC_ZWHZECE4wwOh3xCCrap6i6Ts,87
79
- naeural_client-2.1.0.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
80
- naeural_client-2.1.0.dist-info/RECORD,,
77
+ naeural_client-2.1.1.dist-info/METADATA,sha256=lW6p8iUe_boomUpBmtX-aNHx0k_zRquY3qpS8DecAJw,14457
78
+ naeural_client-2.1.1.dist-info/WHEEL,sha256=3U_NnUcV_1B1kPkYaPzN-irRckL5VW_lytn0ytO_kRY,87
79
+ naeural_client-2.1.1.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
80
+ naeural_client-2.1.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.0
2
+ Generator: hatchling 1.26.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any