naeural-client 2.0.1__tar.gz → 2.0.2__tar.gz

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.
Files changed (117) hide show
  1. naeural_client-2.0.2/.devcontainer/Dockerfile +26 -0
  2. naeural_client-2.0.2/.devcontainer/devcontainer.json +21 -0
  3. {naeural_client-2.0.1 → naeural_client-2.0.2}/.gitignore +1 -2
  4. {naeural_client-2.0.1 → naeural_client-2.0.2}/PKG-INFO +1 -1
  5. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/_ver.py +1 -1
  6. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/generic_session.py +11 -1
  7. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/plugin_template.py +31 -0
  8. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/code_cheker/base.py +29 -2
  9. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/instance/custom_web_app_01_plugin.py +50 -17
  10. {naeural_client-2.0.1 → naeural_client-2.0.2}/pyproject.toml +1 -1
  11. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/1. connect_to_network.py +8 -2
  12. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/2. first_deploy.py +7 -2
  13. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/3. custom_code_on_one_remote__example_1.py +9 -1
  14. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/4. custom_code_on_one_remote__example_2.py +8 -1
  15. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/5. custom_code_on_one_remote__example_3.py +8 -1
  16. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/6. custom_code_on_multiple_remotes__example_1.py +4 -0
  17. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/7. custom_code_on_multiple_remotes__example_2.py +5 -0
  18. naeural_client-2.0.2/tutorials/8. custom_web_app.py +111 -0
  19. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/9. code_sandbox_from_scratch.py +8 -1
  20. naeural_client-2.0.1/tutorials/8. custom_web_app.py +0 -67
  21. {naeural_client-2.0.1 → naeural_client-2.0.2}/.gitattributes +0 -0
  22. {naeural_client-2.0.1 → naeural_client-2.0.2}/.github/workflows/python-publish.yml +0 -0
  23. {naeural_client-2.0.1 → naeural_client-2.0.2}/LICENSE +0 -0
  24. {naeural_client-2.0.1 → naeural_client-2.0.2}/README.md +0 -0
  25. {naeural_client-2.0.1 → naeural_client-2.0.2}/TODOs.md +0 -0
  26. {naeural_client-2.0.1 → naeural_client-2.0.2}/__init__.py +0 -0
  27. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/__init__.py +0 -0
  28. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/__init__.py +0 -0
  29. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/distributed_custom_code_presets.py +0 -0
  30. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/instance.py +0 -0
  31. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/payload/__init__.py +0 -0
  32. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/payload/payload.py +0 -0
  33. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/pipeline.py +0 -0
  34. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/responses.py +0 -0
  35. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base/transaction.py +0 -0
  36. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/base_decentra_object.py +0 -0
  37. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/bc/__init__.py +0 -0
  38. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/bc/base.py +0 -0
  39. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/bc/chain.py +0 -0
  40. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/bc/ec.py +0 -0
  41. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/certs/__init__.py +0 -0
  42. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/certs/r9092118.ala.eu-central-1.emqxsl.com.crt +0 -0
  43. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/code_cheker/__init__.py +0 -0
  44. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/code_cheker/checker.py +0 -0
  45. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/comm/__init__.py +0 -0
  46. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/comm/amqp_wrapper.py +0 -0
  47. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/comm/mqtt_wrapper.py +0 -0
  48. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/README.md +0 -0
  49. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/__init__.py +0 -0
  50. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/base.py +0 -0
  51. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/comms.py +0 -0
  52. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/environment.py +0 -0
  53. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/formatter.py +0 -0
  54. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/heartbeat.py +0 -0
  55. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/misc.py +0 -0
  56. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/const/payload.py +0 -0
  57. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/__init__.py +0 -0
  58. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/instance/__init__.py +0 -0
  59. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/instance/chain_dist_custom_job_01_plugin.py +0 -0
  60. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/instance/net_mon_01_plugin.py +0 -0
  61. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/instance/view_scene_01_plugin.py +0 -0
  62. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/default/session/mqtt_session.py +0 -0
  63. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/__init__.py +0 -0
  64. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/base/__init__.py +0 -0
  65. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/base/base_formatter.py +0 -0
  66. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/default/__init__.py +0 -0
  67. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/default/a_dummy.py +0 -0
  68. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/default/aixp1.py +0 -0
  69. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/default/default.py +0 -0
  70. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/io_formatter/io_formatter_manager.py +0 -0
  71. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/__init__.py +0 -0
  72. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/base_logger.py +0 -0
  73. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/__init__.py +0 -0
  74. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/class_instance_mixin.py +0 -0
  75. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/computer_vision_mixin.py +0 -0
  76. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/datetime_mixin.py +0 -0
  77. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/download_mixin.py +0 -0
  78. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/general_serialization_mixin.py +0 -0
  79. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/json_serialization_mixin.py +0 -0
  80. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/pickle_serialization_mixin.py +0 -0
  81. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/process_mixin.py +0 -0
  82. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/resource_size_mixin.py +0 -0
  83. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/timers_mixin.py +0 -0
  84. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/upload_mixin.py +0 -0
  85. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/logger_mixins/utils_mixin.py +0 -0
  86. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/small_logger.py +0 -0
  87. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/tzlocal/__init__.py +0 -0
  88. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/tzlocal/unix.py +0 -0
  89. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/tzlocal/utils.py +0 -0
  90. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/tzlocal/win32.py +0 -0
  91. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/logging/tzlocal/windows_tz.py +0 -0
  92. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/plugins_manager_mixin.py +0 -0
  93. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/utils/__init__.py +0 -0
  94. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/utils/comm_utils.py +0 -0
  95. {naeural_client-2.0.1 → naeural_client-2.0.2}/naeural_client/utils/dotenv.py +0 -0
  96. {naeural_client-2.0.1 → naeural_client-2.0.2}/requirements.txt +0 -0
  97. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/.example_env +0 -0
  98. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/8. custom_code_fastapi_assets/index.html +0 -0
  99. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/9. code_sandbox_from_scratch_assets/index.html +0 -0
  100. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/_example_pk_sdk.pem +0 -0
  101. {naeural_client-2.0.1 → naeural_client-2.0.2}/tutorials/video_presentation/1. hello_world.ipynb +0 -0
  102. {naeural_client-2.0.1 → naeural_client-2.0.2}/winrun.bat +0 -0
  103. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/.example_env +0 -0
  104. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/README.md +0 -0
  105. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/_archive/test.py +0 -0
  106. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/_tutorials/3. simple_real_time_custom_code.py +0 -0
  107. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/_tutorials/4. real_time_custom_code_2.py +0 -0
  108. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/_tutorials/8. chatbot.py +0 -0
  109. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/attach_example.py +0 -0
  110. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/decentralized/chain_dist_example.py +0 -0
  111. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/decentralized/chain_dist_example_initiator.py +0 -0
  112. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/decentralized/chain_dist_example_worker.py +0 -0
  113. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/ex1.py +0 -0
  114. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/hello.py +0 -0
  115. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/remote_exec.py +0 -0
  116. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/save_images.py +0 -0
  117. {naeural_client-2.0.1 → naeural_client-2.0.2}/xperimental/utils/get_documentation.py +0 -0
@@ -0,0 +1,26 @@
1
+ # Simple ultr-lightweight image for python development
2
+ # Use the latest Python 3 slim image for a lightweight base
3
+ FROM python:3.11-slim
4
+
5
+ # Set the working directory
6
+ WORKDIR /workspace
7
+
8
+ # Install system dependencies required for some Python packages
9
+ RUN apt-get update && apt-get install -y --no-install-recommends \
10
+ build-essential \
11
+ libffi-dev \
12
+ libssl-dev \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # Install the SDK requirements
16
+ RUN pip install --no-cache-dir \
17
+ pika \
18
+ paho-mqtt \
19
+ numpy \
20
+ "pyopenssl>=23.0.0" \
21
+ "cryptography>=39.0.0" \
22
+ python-dateutil \
23
+ pyaml
24
+
25
+ # Set the default command to bash (optional)
26
+ CMD ["bash"]
@@ -0,0 +1,21 @@
1
+ {
2
+ "name" : "Naeural SDK Development Container",
3
+ "dockerFile" : "Dockerfile",
4
+ // "image": "aidamian/image:tag",
5
+
6
+ "runArgs": [
7
+ //"--gpus=all",
8
+ "--hostname",
9
+ "sdk_dev"
10
+ ],
11
+
12
+
13
+ "customizations": {
14
+ "vscode" : {
15
+ "extensions": [
16
+ "ms-python.python",
17
+ "ms-toolsai.jupyter"
18
+ ]
19
+ }
20
+ }
21
+ }
@@ -143,8 +143,7 @@ inference/model_testing/_solisbox/_logs/MPTF.txt
143
143
  inference/model_testing/_solisbox/_logs/20211224_102325_MPTF_001_log.txt
144
144
 
145
145
 
146
- # vscode stuff
147
- .vscode
146
+
148
147
  plugins/libs/_cache/
149
148
  core/utils/_cache/
150
149
  plugins/business/scoring_plugins/_solisbox/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: naeural_client
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: `naeural_client` is the Python SDK required for client app development for the Naeural 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,4 +1,4 @@
1
- __VER__ = "2.0.1"
1
+ __VER__ = "2.0.2"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -1640,7 +1640,9 @@ class GenericSession(BaseDecentrAIObject):
1640
1640
  *,
1641
1641
  node,
1642
1642
  name,
1643
- signature,
1643
+ signature="CUSTOM_CODE_FASTAPI_01",
1644
+ endpoints=None,
1645
+ use_ngrok=True,
1644
1646
  **kwargs
1645
1647
  ):
1646
1648
 
@@ -1652,8 +1654,16 @@ class GenericSession(BaseDecentrAIObject):
1652
1654
  instance = pipeline.create_plugin_instance(
1653
1655
  signature=signature,
1654
1656
  instance_id=self.log.get_unique_id(),
1657
+ use_ngrok=use_ngrok,
1655
1658
  **kwargs
1656
1659
  )
1660
+
1661
+ if endpoints is not None:
1662
+ for endpoint in endpoints:
1663
+ assert isinstance(endpoint, dict), "Each endpoint must be a dictionary defining the endpoint configuration."
1664
+ instance.add_new_endpoint(**endpoint)
1665
+ # end for
1666
+ # end if we have endpoints defined in the call
1657
1667
 
1658
1668
  return pipeline, instance
1659
1669
 
@@ -1,3 +1,34 @@
1
+ """
2
+ CustomPluginTemplate
3
+ ====================
4
+
5
+ The `CustomPluginTemplate` class provides an interface to the on-edge `BasePluginExecutor`, facilitating the creation of custom plugins within the Neural Edge Protocol framework system.
6
+ It exposes all methods and properties defined on the target edge nodes, allowing developers to access any functionality needed for their custom plugins.
7
+ This interface supports code completion and documentation features, enhancing the development experience.
8
+
9
+ Note that code using this class will be executed in a dedicated thread on the edge node during the plugin execution cycle.
10
+
11
+ **Example Usage:**
12
+
13
+ ```python
14
+ def some_custom_code(plugin: CustomPluginTemplate):
15
+ plugin.P("Hello World") # Log a message on the edge node
16
+ obj = plugin.obj_cache.get('MyDict')
17
+ if obj is None:
18
+ obj = {
19
+ 'counter': 0,
20
+ 'some_data': 'some_value'
21
+ }
22
+ plugin.obj_cache['MyDict'] = obj
23
+
24
+ obj['counter'] += 1
25
+ plugin.P(f"Counter: {obj['counter']}") # Log the counter value
26
+ # Finally, send a payload from the edge node to the client
27
+ return obj
28
+ ```
29
+ """
30
+
31
+
1
32
  class CustomPluginTemplate:
2
33
  @property
3
34
  def BytesIO(self):
@@ -9,7 +9,10 @@ import ctypes
9
9
  import threading
10
10
  import queue
11
11
 
12
- from .checker import ASTChecker, CheckerConstants
12
+ try:
13
+ from .checker import ASTChecker, CheckerConstants
14
+ except:
15
+ from naeural_client.code_cheker.checker import ASTChecker, CheckerConstants
13
16
 
14
17
  __VER__ = '0.6.1'
15
18
 
@@ -496,7 +499,7 @@ class BaseCodeChecker:
496
499
 
497
500
  def get_function_source_code(self, func):
498
501
  """
499
- Get the source code of a function and remove the indentation.
502
+ Get the source code of a function including the docstring and remove the indentation.
500
503
 
501
504
  Parameters
502
505
  ----------
@@ -518,3 +521,27 @@ class BaseCodeChecker:
518
521
  plain_code = '\n'.join([line.rstrip()[indent:] for line in plain_code])
519
522
 
520
523
  return plain_code
524
+
525
+
526
+ if __name__ == '__main__':
527
+
528
+ def some_function(x):
529
+ """
530
+ A simple function that adds 1 to the input.
531
+
532
+ Parameters
533
+ ----------
534
+ x : _type_
535
+ _description_
536
+
537
+ Returns
538
+ -------
539
+ _type_
540
+ _description_
541
+ """
542
+ return x + 1
543
+
544
+ checker = BaseCodeChecker()
545
+ source_code = checker.get_function_source_code(some_function)
546
+ print("some_function:\n" + source_code)
547
+
@@ -20,7 +20,54 @@ class CustomWebApp01(Instance):
20
20
 
21
21
  return name, args, base64_code
22
22
 
23
- def add_new_endpoint(self, function, method="get"):
23
+
24
+ def get_proposed_assets(self):
25
+ from copy import deepcopy
26
+ proposed_config = self._get_proposed_config_dictionary(full=True)
27
+ if "ASSETS" in proposed_config:
28
+ return deepcopy(proposed_config["ASSETS"])
29
+ return deepcopy(self.config.get("ASSETS", {}))
30
+
31
+
32
+ def get_proposed_jinja_args(self):
33
+ from copy import deepcopy
34
+ proposed_config = self._get_proposed_config_dictionary(full=True)
35
+ if "JINJA_ARGS" in proposed_config:
36
+ return deepcopy(proposed_config["JINJA_ARGS"])
37
+ return deepcopy(self.config.get("JINJA_ARGS", {}))
38
+
39
+
40
+ def add_new_endpoint(self, endpoint_type="default", **kwargs):
41
+ """
42
+ Add a new endpoint to a existing web app instance.
43
+
44
+ Parameters
45
+ ----------
46
+ endpoint_type : str, optional
47
+ The type of the endpoint. Can be "default", "file" or "html". The default is "default".
48
+
49
+ Raises
50
+ ------
51
+ ValueError
52
+ If the endpoint_type is invalid.
53
+ """
54
+ self.P("Attempting to add a new `{}` endpoint: {}".format(endpoint_type, kwargs))
55
+ if endpoint_type == "default":
56
+ self.add_new_function_endpoint(**kwargs)
57
+ elif endpoint_type == "file":
58
+ self.add_new_file_endpoint(**kwargs)
59
+ elif endpoint_type == "html":
60
+ self.add_new_html_endpoint(**kwargs)
61
+ else:
62
+ raise ValueError("Invalid endpoint type.")
63
+ return
64
+
65
+
66
+ def add_new_file_endpoint(self, str_code, file_name, endpoint_name):
67
+ raise NotImplementedError("This method is not implemented yet.")
68
+
69
+
70
+ def add_new_function_endpoint(self, function, method="get"):
24
71
  name, args, base64_code = self.get_endpoint_fields(function)
25
72
  dct_endpoint = {
26
73
  "NAME": name
@@ -40,23 +87,8 @@ class CustomWebApp01(Instance):
40
87
  dct_endpoint["ARGS"] = args
41
88
 
42
89
  self.update_instance_config(config={"ENDPOINTS": proposed_endpoints})
90
+ return
43
91
 
44
- def get_proposed_assets(self):
45
- from copy import deepcopy
46
- proposed_config = self._get_proposed_config_dictionary(full=True)
47
- if "ASSETS" in proposed_config:
48
- return deepcopy(proposed_config["ASSETS"])
49
- return deepcopy(self.config.get("ASSETS", {}))
50
-
51
- def get_proposed_jinja_args(self):
52
- from copy import deepcopy
53
- proposed_config = self._get_proposed_config_dictionary(full=True)
54
- if "JINJA_ARGS" in proposed_config:
55
- return deepcopy(proposed_config["JINJA_ARGS"])
56
- return deepcopy(self.config.get("JINJA_ARGS", {}))
57
-
58
- def add_new_file_endpoint(self, str_code, file_name, endpoint_name):
59
- raise NotImplementedError("This method is not implemented yet.")
60
92
 
61
93
  def add_new_html_endpoint(self, html_path, web_app_file_name, endpoint_route):
62
94
  str_code = None
@@ -116,3 +148,4 @@ class CustomWebApp01(Instance):
116
148
  dict_name_route_method["route"] = endpoint_route
117
149
 
118
150
  self.update_instance_config(config={"ASSETS": proposed_assets, "JINJA_ARGS": proposed_jinja_args})
151
+ return
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "naeural_client"
7
- version = "2.0.1"
7
+ version = "2.0.2"
8
8
  authors = [
9
9
  { name="Stefan Saraev", email="saraevstefan@gmail.com" },
10
10
  { name="Andrei Ionut Damian", email="andrei.damian@me.com" },
@@ -20,6 +20,12 @@ if __name__ == '__main__':
20
20
  on_heartbeat=on_heartbeat
21
21
  )
22
22
 
23
- # run the program for 10 seconds, then close the session
24
- session.run(wait=10, close_session=True)
23
+
24
+ # Observation:
25
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
26
+ # in production, you would not need this code as the script can close after the pipeline will be sent
27
+ session.run(
28
+ wait=60, # wait for the user to stop the execution or a given time
29
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
30
+ )
25
31
  session.P("Main thread exiting...")
@@ -55,6 +55,11 @@ if __name__ == '__main__':
55
55
 
56
56
  pipeline.deploy()
57
57
 
58
- # run the program for 30 seconds, then close the session
59
- session.run(wait=30, close_session=True, close_pipelines=True)
58
+ # Observation:
59
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
60
+ # in production, you would not need this code as the script can close after the pipeline will be sent
61
+ session.run(
62
+ wait=60, # wait for the user to stop the execution or a given time
63
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
64
+ )
60
65
  session.P("Main thread exiting...")
@@ -71,4 +71,12 @@ if __name__ == "__main__":
71
71
 
72
72
  p.deploy()
73
73
 
74
- s.run(wait=60, close_pipelines=True)
74
+
75
+ # Observation:
76
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
77
+ # in production, you would not need this code as the script can close after the pipeline will be sent
78
+ s.run(
79
+ wait=60, # wait for the user to stop the execution or a given time
80
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
81
+ )
82
+
@@ -94,4 +94,11 @@ if __name__ == "__main__":
94
94
 
95
95
  pipeline.deploy()
96
96
 
97
- session.run(wait=60, close_pipelines=True)
97
+
98
+ # Observation:
99
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
100
+ # in production, you would not need this code as the script can close after the pipeline will be sent
101
+ session.run(
102
+ wait=60, # wait for the user to stop the execution or a given time
103
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
104
+ )
@@ -129,4 +129,11 @@ if __name__ == "__main__":
129
129
 
130
130
  p.deploy()
131
131
 
132
- s.run(wait=60, close_pipelines=True)
132
+
133
+ # Observation:
134
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
135
+ # in production, you would not need this code as the script can close after the pipeline will be sent
136
+ s.run(
137
+ wait=60, # wait for the user to stop the execution or a given time
138
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
139
+ )
@@ -95,6 +95,10 @@ if __name__ == "__main__":
95
95
  deploy=True
96
96
  )
97
97
 
98
+
99
+ # Observation:
100
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
101
+ # in production, you would not need this code as the script can close after the pipeline will be sent
98
102
  # process incoming messages until the finish condition is met
99
103
  s.run(wait=lambda: len(final_result) == 0, close_pipelines=True, close_session=True)
100
104
 
@@ -173,6 +173,11 @@ if __name__ == "__main__":
173
173
 
174
174
  p.deploy()
175
175
 
176
+
177
+ # Observation:
178
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
179
+ # in production, you would not need this code as the script can close after the pipeline will be sent
180
+
176
181
  # process incoming messages until the finish condition is met
177
182
  s.run(wait=lambda: len(final_result) == 0, close_pipelines=True, close_session=True)
178
183
 
@@ -0,0 +1,111 @@
1
+ from naeural_client import CustomPluginTemplate, Session
2
+ from naeural_client.default.instance import CustomWebApp01
3
+
4
+ # this tutorial can be run only on the local edge node
5
+ # because it uses ngrok to expose the fastapi server
6
+ # and this requires an ngrok auth token
7
+
8
+ # See https://naeural-013.ngrok.app/docs
9
+
10
+
11
+ def hello_world(plugin, name: str = "naeural_developer"):
12
+ # name is a query parameter
13
+ return f"Hello, {name}! I am {plugin.e2_addr}"
14
+
15
+
16
+ def get_uuid(plugin: CustomPluginTemplate):
17
+ return f"New uuid: {plugin.uuid()}!"
18
+
19
+
20
+ def get_addr(plugin: CustomPluginTemplate):
21
+ return plugin.node_addr
22
+
23
+
24
+ def predict(plugin: CustomPluginTemplate, series: list[int], steps: int) -> list:
25
+ """
26
+ This function is used to predict the next `steps` values of the time series `series`.
27
+
28
+ Parameters
29
+ ----------
30
+ series : list[int]
31
+ A list of integers representing the time series.
32
+ steps : int
33
+ The number of steps to predict.
34
+
35
+ Returns
36
+ -------
37
+ list
38
+ A list of integers representing the predicted values.
39
+ """
40
+ result = plugin.basic_ts_fit_predict(series, steps)
41
+ result = list(map(int, result))
42
+ return result
43
+
44
+
45
+ if __name__ == "__main__":
46
+ session = Session()
47
+
48
+ node = "INSERT_YOUR_NODE_ADDRESS_HERE"
49
+ session.wait_for_node(node)
50
+
51
+ instance: CustomWebApp01
52
+ pipeline, instance = session.create_web_app(
53
+ node=node,
54
+ name="naeural_predict_app",
55
+ ngrok_edge_label="INSERT_YOUR_NGROK_EDGE_LABEL_HERE",
56
+ endpoints=[
57
+ {
58
+ # we omit the "endpoint_type" key, because the default value is "default" ie the "function" type
59
+ "function": hello_world,
60
+ "method": "get",
61
+ },
62
+ {
63
+ "function": get_uuid,
64
+ "method": "get",
65
+ },
66
+ {
67
+ "function": get_addr,
68
+ "method": "get",
69
+ },
70
+ {
71
+ "function": predict,
72
+ "method": "post",
73
+ },
74
+ {
75
+ "endpoint_type": "html",
76
+ "html_path": "tutorials/8. custom_code_fastapi_assets/index.html",
77
+ "web_app_file_name": "index.html",
78
+ "endpoint_route": "/",
79
+ }
80
+ ]
81
+ )
82
+
83
+ # we could have added the endpoints one by one
84
+ # # GET request on <domain>/hello_world?name=naeural_developer
85
+ # instance.add_new_endpoint(hello_world)
86
+
87
+ # # GET request on <domain>/get_uuid
88
+ # instance.add_new_endpoint(get_uuid, method="get")
89
+
90
+ # # GET request on <domain>/get_addr
91
+ # instance.add_new_endpoint(get_addr, method="get")
92
+
93
+ # # POST request on <domain>/forecasting (with body as json with 2 keys: series and steps)
94
+ # instance.add_new_endpoint(predict, method="post")
95
+
96
+ # # add an html file to the web app, accessible at <domain>/
97
+ # instance.add_new_html_endpoint(
98
+ # html_path="tutorials/8. custom_code_fastapi_assets/index.html",
99
+ # web_app_file_name="index.html",
100
+ # endpoint_route="/",
101
+ # )
102
+
103
+ pipeline.deploy()
104
+
105
+ # Observation:
106
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
107
+ # in production, you would not need this code as the script can close after the pipeline will be sent
108
+ session.run(
109
+ wait=True, # wait for the user to stop the execution
110
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
111
+ )
@@ -44,4 +44,11 @@ if __name__ == "__main__":
44
44
 
45
45
  pipeline.deploy()
46
46
 
47
- session.run(close_pipelines=True)
47
+
48
+ # Observation:
49
+ # next code is not mandatory - it is used to keep the session open and cleanup the resources
50
+ # in production, you would not need this code as the script can close after the pipeline will be sent
51
+ session.run(
52
+ wait=True, # wait for the user to stop the execution or a given time
53
+ close_pipelines=True # when the user stops the execution, the remote edge-node pipelines will be closed
54
+ )
@@ -1,67 +0,0 @@
1
- from naeural_client import CustomPluginTemplate, Session
2
- from naeural_client.default.instance import CustomWebApp01
3
-
4
- # this tutorial can be run only on the local edge node
5
- # because it uses ngrok to expose the fastapi server
6
- # and this requires an ngrok auth token
7
-
8
- # See https://naeural-013.ngrok.app/docs
9
-
10
-
11
- def hello_world(plugin, name: str = "naeural_developer"):
12
- # name is a query parameter
13
- return f"Hello, {name}! I am {plugin.e2_addr}"
14
-
15
-
16
- def get_uuid(plugin: CustomPluginTemplate):
17
- return f"New uuid: {plugin.uuid()}!"
18
-
19
-
20
- def get_addr(plugin: CustomPluginTemplate):
21
- return plugin.node_addr
22
-
23
-
24
- def predict(plugin: CustomPluginTemplate, series: list[int], steps: int) -> list:
25
- result = plugin.basic_ts_fit_predict(series, steps)
26
- result = list(map(int, result))
27
- return result
28
-
29
-
30
- if __name__ == "__main__":
31
- session = Session()
32
-
33
- node = "INSERT_YOUR_NODE_ADDRESS_HERE"
34
- session.wait_for_node(node)
35
-
36
- instance: CustomWebApp01
37
- pipeline, instance = session.create_web_app(
38
- node=node,
39
- name="naeural_predict_app",
40
- signature=CustomWebApp01,
41
-
42
- ngrok_edge_label="INSERT_YOUR_NGROK_EDGE_LABEL_HERE",
43
- use_ngrok=True,
44
- )
45
-
46
- # GET request on <domain>/hello_world?name=naeural_developer
47
- instance.add_new_endpoint(hello_world)
48
-
49
- # GET request on <domain>/get_uuid
50
- instance.add_new_endpoint(get_uuid, method="get")
51
-
52
- # GET request on <domain>/get_addr
53
- instance.add_new_endpoint(get_addr, method="get")
54
-
55
- # POST request on <domain>/forecasting (with body as json with 2 keys: series and steps)
56
- instance.add_new_endpoint(predict, method="post")
57
-
58
- # add an html file to the web app, accessible at <domain>/
59
- instance.add_new_html_endpoint(
60
- html_path="tutorials/8. custom_code_fastapi_assets/index.html",
61
- web_app_file_name="index.html",
62
- endpoint_route="/",
63
- )
64
-
65
- pipeline.deploy()
66
-
67
- session.run(close_pipelines=True)
File without changes
File without changes
File without changes