naeural-client 2.6.15__py3-none-any.whl → 2.6.16__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.15"
1
+ __VER__ = "2.6.16"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -18,6 +18,9 @@ DAUTH_VARS = [DAUTH_NONCE, BCctbase.SIGN, BCctbase.SENDER, BCctbase.HASH]
18
18
 
19
19
  ETH_ENABLED_ENV_KEY = 'EE_ETH_ENABLED'
20
20
 
21
+ EE_EPOCH_INTERVALS_KEY = 'EE_EPOCH_INTERVALS'
22
+ EE_EPOCH_INTERVAL_SECONDS_KEY = 'EE_EPOCH_INTERVAL_SECONDS'
23
+
21
24
 
22
25
  class LocalInfo:
23
26
  LOCAL_INFO_FILE = 'local_info.json'
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: naeural_client
3
+ Version: 2.6.16
4
+ Summary: `naeural_client` is the Python SDK required for client app development for the Naeural Edge Protocol Edge Protocol framework
5
+ Project-URL: Homepage, https://github.com/NaeuralEdgeProtocol/naeural_client
6
+ Project-URL: Bug Tracker, https://github.com/NaeuralEdgeProtocol/naeural_client/issues
7
+ Author-email: Andrei Ionut Damian <andrei.damian@me.com>, Cristan Bleotiu <cristibleotiu@gmail.com>, Stefan Saraev <saraevstefan@gmail.com>
8
+ License-File: LICENSE
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.8
13
+ Requires-Dist: cryptography>=39.0.0
14
+ Requires-Dist: numpy
15
+ Requires-Dist: paho-mqtt
16
+ Requires-Dist: pandas
17
+ Requires-Dist: pika
18
+ Requires-Dist: pyaml
19
+ Requires-Dist: pyopenssl>=23.0.0
20
+ Requires-Dist: python-dateutil
21
+ Requires-Dist: web3
22
+ Description-Content-Type: text/markdown
23
+
24
+ # Ratio1 SDK
25
+
26
+ Welcome to the **Ratio1 SDK** repository, formerly known as the **naeural_client SDK**. The Ratio1 SDK is a crucial component of the Ratio1 ecosystem, designed to facilitate interactions, development, and deployment of jobs within the Ratio1 network. By enabling low-code development, the SDK allows developers to build and deploy end-to-end AI (and beyond) cooperative application pipelines seamlessly within the Ratio1 Edge Nodes ecosystem.
27
+
28
+ ## Overview
29
+
30
+ The **Ratio1 SDK** is engineered to enhance the Ratio1 protocol and ecosystem, aiming to improve the functionality and performance of the Ratio1 Edge Node through dedicated research and community contributions. This SDK serves as an essential tool for developers looking to integrate their applications with the Ratio1 network, enabling them to leverage the decentralized, secure, and privacy-preserving capabilities of Ratio1 Edge Nodes.
31
+
32
+ Key functionalities of the Ratio1 SDK include:
33
+
34
+ - **Job Interactions**: Facilitate the development and management of computation tasks within the Ratio1 network.
35
+ - **Development Tools**: Provide low-code solutions for creating and deploying AI-driven application pipelines.
36
+ - **Ecosystem Integration**: Seamlessly integrate with Ratio1 Edge Nodes to utilize their computational resources effectively.
37
+ - **Collaboration and Deployment**: Enable cooperative application development and deployment across multiple edge nodes within the Ratio1 ecosystem.
38
+
39
+ Unlike the Ratio1 Core Packages, which are intended solely for protocol and ecosystem enhancements and are not meant for standalone installation, the Ratio1 SDK is designed for both client-side development and sending workloads to Ratio1 Edge Nodes, making it an indispensable tool for developers within the ecosystem.
40
+
41
+ ## Dependencies
42
+
43
+ The Ratio1 SDK relies on several key packages to function effectively. These dependencies are automatically managed when installing the SDK via pip:
44
+
45
+ - `pika`
46
+ - `paho-mqtt`
47
+ - `numpy`
48
+ - `pyopenssl>=23.0.0`
49
+ - `cryptography>=39.0.0`
50
+ - `python-dateutil`
51
+ - `pyaml`
52
+
53
+ ## Installation
54
+
55
+ Installing the Ratio1 SDK is straightforward and is intended for development and integration into your projects. Use the following pip commands to install the SDK:
56
+
57
+ ### Standard Installation
58
+
59
+ To install the Ratio1 SDK, run:
60
+
61
+ ```shell
62
+ pip install ratio1_sdk --upgrade
63
+ ```
64
+
65
+ ### Development Installation
66
+
67
+ For development purposes, you can clone the repository and set up the SDK in an editable mode:
68
+
69
+ ```shell
70
+ git clone https://github.com/Ratio1/ratio1_sdk
71
+ cd ratio1_sdk
72
+ pip install -e .
73
+ ```
74
+
75
+ This allows you to make modifications to the SDK and have them reflected immediately without reinstalling.
76
+
77
+ ## Documentation
78
+
79
+ Comprehensive documentation for the Ratio1 SDK is currently a work in progress. Minimal documentation is available here, with detailed code examples located in the `tutorials` folder within the project's repository. We encourage developers to explore these examples to understand the SDK's capabilities and integration methods.
80
+
81
+ ## Quick Start Guides
82
+
83
+ Starting with version 2.6+, the Ratio1 SDK automatically performs self-configuration using **dAuth**—the Ratio1 decentralized self-authentication system. To begin integrating with the Ratio1 network, follow these steps:
84
+
85
+ ### 1. Start a Local Edge Node
86
+
87
+ Launch a local Ratio1 Edge Node using Docker:
88
+
89
+ ```bash
90
+ docker run -d --name=local_node ratio1/edge_node:develop
91
+ ```
92
+
93
+ After a few seconds, the node will be online. Retrieve the node's address by running:
94
+
95
+ ```bash
96
+ docker exec local_node get_node_info
97
+ ```
98
+
99
+ The output will resemble:
100
+
101
+ ```json
102
+ {
103
+ "address": "0xai_AtMvIwaEPi5M8cnkdbaZ3tbUhCzKbGKEYuZ1xFtCjT_6",
104
+ "alias": "6dd74472642e",
105
+ "eth_address": "0x98FE7c0d8CeC2E97B932D2bDC1bb73B395C9Dfd7"
106
+ }
107
+ ```
108
+
109
+ ### 2. Develop and Deploy Jobs
110
+
111
+ Use the SDK to develop and send workloads to the Edge Nodes. Below are examples of both local and remote execution.
112
+
113
+ ## Examples
114
+
115
+ ### Local Execution
116
+
117
+ This example demonstrates how to find all 168 prime numbers in the interval 1 - 1000 using local execution. The code leverages multiple threads to perform prime number generation efficiently.
118
+
119
+ ```python
120
+ import numpy as np
121
+ from concurrent.futures import ThreadPoolExecutor
122
+
123
+ def local_brute_force_prime_number_generator():
124
+ def is_prime(n):
125
+ if n <= 1:
126
+ return False
127
+ for i in range(2, int(np.sqrt(n)) + 1):
128
+ if n % i == 0:
129
+ return False
130
+ return True
131
+
132
+ random_numbers = np.random.randint(1, 1000, 20)
133
+
134
+ thread_pool = ThreadPoolExecutor(max_workers=4)
135
+ are_primes = list(thread_pool.map(is_prime, random_numbers))
136
+
137
+ prime_numbers = []
138
+ for i in range(len(random_numbers)):
139
+ if are_primes[i]:
140
+ prime_numbers.append(random_numbers[i])
141
+
142
+ return prime_numbers
143
+
144
+ if __name__ == "__main__":
145
+ found_so_far = []
146
+ print_step = 0
147
+
148
+ while len(found_so_far) < 168:
149
+ # Compute a batch of prime numbers
150
+ prime_numbers = local_brute_force_prime_number_generator()
151
+
152
+ # Keep only the new prime numbers
153
+ for prime_number in prime_numbers:
154
+ if prime_number not in found_so_far:
155
+ found_so_far.append(prime_number)
156
+
157
+ # Show progress
158
+ if print_step % 50 == 0:
159
+ print("Found so far: {}: {}\n".format(len(found_so_far), sorted(found_so_far)))
160
+
161
+ print_step += 1
162
+
163
+ # Show final result
164
+ print("Found so far: {}: {}\n".format(len(found_so_far), sorted(found_so_far)))
165
+ ```
166
+
167
+ ### Remote Execution
168
+
169
+ To accelerate prime number discovery, this example demonstrates deploying the task across multiple edge nodes within the Ratio1 network. Minimal code changes are required to transition from local to remote execution.
170
+
171
+ #### 1. Modify the Prime Number Generator
172
+
173
+ ```python
174
+ from ratio1_sdk import CustomPluginTemplate
175
+
176
+ def remote_brute_force_prime_number_generator(plugin: CustomPluginTemplate):
177
+ def is_prime(n):
178
+ if n <= 1:
179
+ return False
180
+ for i in range(2, int(plugin.np.sqrt(n)) + 1):
181
+ if n % i == 0:
182
+ return False
183
+ return True
184
+
185
+ random_numbers = plugin.np.random.randint(1, 1000, 20)
186
+ are_primes = plugin.threadapi_map(is_prime, random_numbers, n_threads=4)
187
+
188
+ prime_numbers = []
189
+ for i in range(len(random_numbers)):
190
+ if are_primes[i]:
191
+ prime_numbers.append(random_numbers[i])
192
+
193
+ return prime_numbers
194
+ ```
195
+
196
+ #### 2. Connect to the Network and Select a Node
197
+
198
+ ```python
199
+ from ratio1_sdk import Session
200
+ from time import sleep
201
+
202
+ def on_heartbeat(session: Session, node: str, heartbeat: dict):
203
+ session.P("{} is online".format(node))
204
+ return
205
+
206
+ if __name__ == '__main__':
207
+ session = Session(
208
+ on_heartbeat=on_heartbeat
209
+ )
210
+
211
+ # Run the program for 15 seconds to detect online nodes
212
+ sleep(15)
213
+
214
+ # Retrieve and select an online node
215
+ node = "0xai_A8SY7lEqBtf5XaGyB6ipdk5C30vSf3HK4xELp3iplwLe" # naeural-1
216
+ ```
217
+
218
+ #### 3. Deploy the Distributed Job
219
+
220
+ ```python
221
+ from ratio1_sdk import DistributedCustomCodePresets as Presets
222
+
223
+ _, _ = session.create_chain_dist_custom_job(
224
+ node=node,
225
+ main_node_process_real_time_collected_data=Presets.PROCESS_REAL_TIME_COLLECTED_DATA__KEEP_UNIQUES_IN_AGGREGATED_COLLECTED_DATA,
226
+ main_node_finish_condition=Presets.FINISH_CONDITION___AGGREGATED_DATA_MORE_THAN_X,
227
+ main_node_finish_condition_kwargs={"X": 167},
228
+ main_node_aggregate_collected_data=Presets.AGGREGATE_COLLECTED_DATA___AGGREGATE_COLLECTED_DATA,
229
+ nr_remote_worker_nodes=2,
230
+ worker_node_code=remote_brute_force_prime_number_generator,
231
+ on_data=locally_process_partial_results,
232
+ deploy=True
233
+ )
234
+ ```
235
+
236
+ #### 4. Close the Session Upon Completion
237
+
238
+ ```python
239
+ # Wait until the finished flag is set to True
240
+ session.run(wait=lambda: not finished, close_pipelines=True)
241
+ ```
242
+
243
+ ## Project Financing Disclaimer
244
+
245
+ This project incorporates open-source components developed with the support of financing grants **SMIS 143488** and **SMIS 156084**, provided by the Romanian Competitiveness Operational Programme. We extend our sincere gratitude for this support, which has been instrumental in advancing our work and enabling us to share these resources with the community.
246
+
247
+ The content and information within this repository are solely the responsibility of the authors and do not necessarily reflect the views of the funding agencies. The grants have specifically supported certain aspects of this open-source project, facilitating broader dissemination and collaborative development.
248
+
249
+ For any inquiries regarding the funding and its impact on this project, please contact the authors directly.
250
+
251
+ ## License
252
+
253
+ This project is licensed under the **Apache 2.0 License**. For more details, please refer to the [LICENSE](LICENSE) file.
254
+
255
+ ## Contact
256
+
257
+ For more information, visit our website at [https://ratio1.ai](https://ratio1.ai) or reach out to us via email at [support@ratio1.ai](mailto:support@ratio1.ai).
258
+
259
+ ## Citation
260
+
261
+ If you use the Ratio1 SDK in your research or projects, please cite it as follows:
262
+
263
+ ```bibtex
264
+ @misc{Ratio1SDK,
265
+ author = {Ratio1.AI},
266
+ title = {Ratio1 SDK},
267
+ year = {2024-2025},
268
+ howpublished = {\url{https://github.com/NaeuralEdgeProtocol/naeural_client}},
269
+ }
270
+ ```
271
+
272
+ ```bibtex
273
+ @misc{Ratio1EdgeNode,
274
+ author = {Ratio1.AI},
275
+ title = {Ratio1: Edge Node},
276
+ year = {2024-2025},
277
+ howpublished = {\url{https://github.com/NaeuralEdgeProtocol/edge_node}},
278
+ }
279
+ ```
@@ -1,5 +1,5 @@
1
1
  naeural_client/__init__.py,sha256=YimqgDbjLuywsf8zCWE0EaUXH4MBUrqLxt0TDV558hQ,632
2
- naeural_client/_ver.py,sha256=s5A-FwAfqI4BeZ8fzrRTwGs3LEc-m4EQ8BufoeG3kSI,331
2
+ naeural_client/_ver.py,sha256=eM7t0xRbVJaaGjrh0O9tmQF7K_usWv_3wk3hVZ27_Qs,331
3
3
  naeural_client/base_decentra_object.py,sha256=C4iwZTkhKNBS4VHlJs5DfElRYLo4Q9l1V1DNVSk1fyQ,4412
4
4
  naeural_client/plugins_manager_mixin.py,sha256=X1JdGLDz0gN1rPnTN_5mJXR8JmqoBFQISJXmPR9yvCo,11106
5
5
  naeural_client/base/__init__.py,sha256=hACh83_cIv7-PwYMM3bQm2IBmNqiHw-3PAfDfAEKz9A,259
@@ -32,7 +32,7 @@ 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=ePBiJXLuPfFOKuw-LJrT9OWbaodU7QApfDurIPNDoB4,655
35
- naeural_client/const/base.py,sha256=Ld6WuQeqm5FbARL_-xs3gXxpa46ypksHimAk1g4qanw,4467
35
+ naeural_client/const/base.py,sha256=1ScfnfNd5xeWo7tkkDgQR95vliTpcax025Naj0Lqw38,4574
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
@@ -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.15.dist-info/METADATA,sha256=F37VysVyxouaFh-B_tDEHDG_AFQMH03gNF0UbbanqKI,13176
85
- naeural_client-2.6.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
- naeural_client-2.6.15.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
- naeural_client-2.6.15.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
- naeural_client-2.6.15.dist-info/RECORD,,
84
+ naeural_client-2.6.16.dist-info/METADATA,sha256=PaCUsM0cAtvH9ZUTzfwNxZTumPu4np7e3inODMj9WLA,10362
85
+ naeural_client-2.6.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
+ naeural_client-2.6.16.dist-info/entry_points.txt,sha256=PNdyotDaQBAslZREx5luVyj0kqpQnwNACwkFNTPIHU4,55
87
+ naeural_client-2.6.16.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
88
+ naeural_client-2.6.16.dist-info/RECORD,,
@@ -1,358 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: naeural_client
3
- Version: 2.6.15
4
- Summary: `naeural_client` is the Python SDK required for client app development for the Naeural Edge Protocol Edge Protocol framework
5
- Project-URL: Homepage, https://github.com/NaeuralEdgeProtocol/naeural_client
6
- Project-URL: Bug Tracker, https://github.com/NaeuralEdgeProtocol/naeural_client/issues
7
- Author-email: Andrei Ionut Damian <andrei.damian@me.com>, Cristan Bleotiu <cristibleotiu@gmail.com>, Stefan Saraev <saraevstefan@gmail.com>
8
- License-File: LICENSE
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Classifier: Programming Language :: Python :: 3
12
- Requires-Python: >=3.8
13
- Requires-Dist: cryptography>=39.0.0
14
- Requires-Dist: numpy
15
- Requires-Dist: paho-mqtt
16
- Requires-Dist: pandas
17
- Requires-Dist: pika
18
- Requires-Dist: pyaml
19
- Requires-Dist: pyopenssl>=23.0.0
20
- Requires-Dist: python-dateutil
21
- Requires-Dist: web3
22
- Description-Content-Type: text/markdown
23
-
24
- # Ratio1 SDK (naeural_client SDK)
25
-
26
- This is the Python SDK package that allows interactions, development and deployment of jobs in Ratio1 ecosystem formely known as Naeural Edge Protocol network. The SDK enables low-code development and deployment of end-to-end AI (and not only) cooperative application pipelines within the Ratio1 Edge Nodes ecosystem.
27
-
28
- ## Dependencies
29
-
30
- This packet depends and will automatically install the following packets: `pika`, `paho-mqtt`, `numpy`, `pyopenssl>=23.0.0`, `cryptography>=39.0.0`, `python-dateutil`, `pyaml`.
31
-
32
- ## Installation
33
-
34
- ```shell
35
- pip install naeural_client --upgrade
36
- ```
37
-
38
- ### Development installation
39
-
40
- ```shell
41
- git clone https://github.com/NaeuralEdgeProtocol/naeural_client
42
- pip install -e .
43
- ```
44
-
45
- ## Documentation
46
-
47
- Minimal documentation will be presented here. The complete documentation is
48
- Work in Progress.
49
-
50
- Code examples are located in the `tutorials` folder in the project's repository.
51
-
52
- ## Quick start guides
53
-
54
- Starting with version 2.6+ the SDK will automatically perform self-configuration using the dAuth - the Ratio1 decentralized self-authentication system.
55
-
56
- In order to start a local edge node you just need to run:
57
-
58
- ```bash
59
- docker run -d --name=local_node naeural/edge_node:develop
60
- ```
61
- after a few seconds the node will be online and you can get the node's address by running:
62
-
63
- ```bash
64
- docker exec local_node get_node_info
65
- ```
66
-
67
- The output will be similar to:
68
-
69
- ```json
70
- {
71
- "address": "0xai_AtMvIwaEPi5M8cnkdbaZ3tbUhCzKbGKEYuZ1xFtCjT_6",
72
- "alias": "6dd74472642e",
73
- "eth_address": "0x98FE7c0d8CeC2E97B932D2bDC1bb73B395C9Dfd7"
74
- }
75
- ```
76
-
77
-
78
- ## Some Examples
79
-
80
- ### Local Execution
81
-
82
- We want to find all $168$ prime numbers in the interval $1$ - $1000$. For this we can run the following code on our local machine.
83
-
84
- This code has segments running on multiple threads using a ThreadPool.
85
-
86
- ```python
87
- import numpy as np
88
- from concurrent.futures import ThreadPoolExecutor
89
-
90
-
91
- def local_brute_force_prime_number_generator():
92
- def is_prime(n):
93
- if n <= 1:
94
- return False
95
- for i in range(2, int(np.sqrt(n)) + 1):
96
- if n % i == 0:
97
- return False
98
- return True
99
-
100
- random_numbers = np.random.randint(1, 1000, 20)
101
-
102
- thread_pool = ThreadPoolExecutor(max_workers=4)
103
- are_primes = list(thread_pool.map(is_prime, random_numbers))
104
-
105
- prime_numbers = []
106
- for i in range(len(random_numbers)):
107
- if are_primes[i]:
108
- prime_numbers.append(random_numbers[i])
109
-
110
- return prime_numbers
111
-
112
-
113
- if __name__ == "__main__":
114
- found_so_far = []
115
-
116
- print_step = 0
117
-
118
- while len(found_so_far) < 168:
119
- # compute a batch of prime numbers
120
- prime_numbers = local_brute_force_prime_number_generator()
121
-
122
- # keep only the new prime numbers
123
- for prime_number in prime_numbers:
124
- if prime_number not in found_so_far:
125
- found_so_far.append(prime_number)
126
- # end for
127
-
128
- # show progress
129
- if print_step % 50 == 0:
130
- print("Found so far: {}: {}\n".format(len(found_so_far), sorted(found_so_far)))
131
-
132
- print_step += 1
133
- # end while
134
-
135
- # show final result
136
- print("Found so far: {}: {}\n".format(len(found_so_far), sorted(found_so_far)))
137
- ```
138
-
139
- We can see that we have a `local_brute_force_prime_number_generator` method which will generate a random sample of $20$ numbers that will be checked if they are prime or not.
140
-
141
- The rest of the code handles how the numbers generated with this method are kept.
142
- Because we want to find $168$ unique numbers, we append to the list of found primes only the numbers that are not present yet.
143
-
144
- At the end, we want to show a list of all the numbers found.
145
-
146
- ### Remote Execution
147
-
148
- For this example we would like to use multiple edge nodes to find the prime numbers faster.
149
-
150
- To execute this code on our network, a series of changes must be made to the `local_brute_force_prime_number_generator` method.
151
- These changes are the only ones a developer has to do to deploy his own custom code on the network.
152
-
153
- For this, we will create a new method, `remote_brute_force_prime_number_generator`, which will use the exposed edge node API methods.
154
-
155
- ```python
156
- from naeural_client import CustomPluginTemplate
157
-
158
- # through the `plugin` object we get access to the edge node API
159
- # the CustomPluginTemplate class acts as a documentation for all the available methods and attributes
160
- # since we do not allow imports in the custom code due to security reasons, the `plugin` object
161
- # exposes common modules to the user
162
- def remote_brute_force_prime_number_generator(plugin: CustomPluginTemplate):
163
- def is_prime(n):
164
- if n <= 1:
165
- return False
166
- # we use the `plugin.np` instead of the `np` module
167
- for i in range(2, int(plugin.np.sqrt(n)) + 1):
168
- if n % i == 0:
169
- return False
170
- return True
171
-
172
- # we use the `plugin.np` instead of the `np` module
173
- random_numbers = plugin.np.random.randint(1, 1000, 20)
174
-
175
- # we use the `plugin.threadapi_map` instead of the `ThreadPoolExecutor.map`
176
- are_primes = plugin.threadapi_map(is_prime, random_numbers, n_threads=4)
177
-
178
- prime_numbers = []
179
- for i in range(len(random_numbers)):
180
- if are_primes[i]:
181
- prime_numbers.append(random_numbers[i])
182
-
183
- return prime_numbers
184
- ```
185
-
186
- This are all the changes we have to do to deploy this code in the network.
187
-
188
- Now lets connect to the network and see what nodes are online.
189
- We will use the `on_heartbeat` callback to print the nodes.
190
-
191
- ```python
192
- from naeural_client import Session
193
- from time import sleep
194
-
195
- def on_heartbeat(session: Session, node: str, heartbeat: dict):
196
- # the `.P` method is used to print messages in the console and store them in the log file
197
- session.P("{} is online".format(node))
198
- return
199
-
200
-
201
- if __name__ == '__main__':
202
- # create a session
203
- # the network credentials are read from the .env file automatically
204
- session = Session(
205
- on_heartbeat=on_heartbeat
206
- )
207
-
208
- # run the program for 15 seconds to show all the nodes that are online
209
- sleep(15)
210
-
211
- ```
212
-
213
- Next we will select an online node. This node will be our entrypoint in the network.
214
-
215
- The available nodes in our test net are:
216
-
217
- ```
218
- 0xai_A8SY7lEqBtf5XaGyB6ipdk5C30vSf3HK4xELp3iplwLe naeural-1
219
- 0xai_Amfnbt3N-qg2-qGtywZIPQBTVlAnoADVRmSAsdDhlQ-6 naeural-2
220
- 0xai_ApltAljEgWk3g8x2QcSa0sS3hT1P4dyCchd04zFSMy5e naeural-3
221
- ```
222
-
223
- We will send a task to this node. Since we want to distribute the task of finding prime numbers to multiple nodes, this selected node will handle distribution of tasks and collection of the results.
224
-
225
- ```python
226
- node = "0xai_A8SY7lEqBtf5XaGyB6ipdk5C30vSf3HK4xELp3iplwLe" # naeural-1
227
-
228
- # we usually wait for the node to be online before sending the task
229
- # but in this case we are sure that the node is online because we
230
- # have received heartbeats from it during the sleep period
231
-
232
- # session.wait_for_node(node)
233
- ```
234
-
235
- Our selected node will periodically output partial results with the prime numbers found so far by the worker nodes. We want to consume these results.
236
-
237
- Thus, we need to implement a callback method that will handle this.
238
-
239
- ```python
240
- from naeural_client import Pipeline
241
-
242
- # a flag used to close the session when the task is finished
243
- finished = False
244
-
245
- def locally_process_partial_results(pipeline: Pipeline, full_payload):
246
- global finished
247
- found_so_far = full_payload.get("DATA")
248
-
249
- if found_so_far:
250
- pipeline.P("Found so far: {}: {}\n\n".format(len(found_so_far), sorted(found_so_far)))
251
-
252
- progress = full_payload.get("PROGRESS")
253
- if progress == 100:
254
- pipeline.P("FINISHED\n\n")
255
- finished = True
256
-
257
- return
258
- ```
259
-
260
- Now we are ready to deploy our job to the network.
261
-
262
- ```python
263
- from naeural_client import DistributedCustomCodePresets as Presets
264
-
265
- _, _ = session.create_chain_dist_custom_job(
266
- # this is the main node, our entrypoint
267
- node=node,
268
-
269
- # this function is executed on the main node
270
- # this handles what we want to do with primes found by a worker node after an iteration
271
- # we want to store only the unique prime numbers
272
- # we cam either write a custom code to pass here or we can use a preset
273
- main_node_process_real_time_collected_data=Presets.PROCESS_REAL_TIME_COLLECTED_DATA__KEEP_UNIQUES_IN_AGGREGATED_COLLECTED_DATA,
274
-
275
- # this function is executed on the main node
276
- # this handles the finish condition of our distributed job
277
- # we want to finish when we have found 168 prime numbers
278
- # so more than 167 prime numbers
279
- # we cam either write a custom code to pass here or we can use a preset
280
- main_node_finish_condition=Presets.FINISH_CONDITION___AGGREGATED_DATA_MORE_THAN_X,
281
- main_node_finish_condition_kwargs={
282
- "X": 167
283
- },
284
-
285
- # this function is executed on the main node
286
- # this handles the final processing of the results
287
- # this function prepares data for the final result of the distributed job
288
- # we want to aggregate all the prime numbers found by the worker nodes in a single list
289
- # we cam either write a custom code to pass here or we can use a preset
290
- main_node_aggregate_collected_data=Presets.AGGREGATE_COLLECTED_DATA___AGGREGATE_COLLECTED_DATA,
291
-
292
- # how many worker nodes we want to use for this task
293
- nr_remote_worker_nodes=2,
294
-
295
- # this is the function that will be executed on the worker nodes
296
- # this function generates prime numbers using brute force
297
- # we simply pass the function reference
298
- worker_node_code=remote_brute_force_prime_number_generator,
299
-
300
- # this is the function that will be executed on the client
301
- # this is the callback function that processes the partial results
302
- # in our case we want to print the partial results
303
- on_data=locally_process_partial_results,
304
-
305
- # we want to deploy the job immediately
306
- deploy=True
307
- )
308
- ```
309
-
310
- Last but not least, we want to close the session when the distributed job finished.
311
-
312
- ```python
313
- # we wait until the finished flag is set to True
314
- # we want to release the resources allocated on the selected node when the job is finished
315
- session.run(wait=lambda: not finished, close_pipelines=True)
316
- ```
317
-
318
-
319
- # Project Financing Disclaimer
320
-
321
- This project includes open-source components that have been developed with the support of financing grants SMIS 143488 and SMIS 156084, provided by the Romanian Competitiveness Operational Programme. We are grateful for this support, which has enabled us to advance our work and share these resources with the community.
322
-
323
- The content and information provided within this repository are solely the responsibility of the authors and do not necessarily reflect the views of the funding agencies. The funding received under these grants has been instrumental in supporting specific parts of this open source project, allowing for broader dissemination and collaborative development.
324
-
325
- For any inquiries related to the funding and its impact on this project, please contact the authors directly.
326
-
327
-
328
- # Citation
329
-
330
- ```bibtex
331
- @misc{naeural_client,
332
- author = {Stefan Saraev, Andrei Damian},
333
- title = {naeural_client: Python SDK for Naeural Edge Protocol Edge Protocol},
334
- year = {2024},
335
- howpublished = {\url{https://github.com/Naeural Edge ProtocolEdgeProtocol/naeural_client}},
336
- }
337
- ```
338
-
339
- ```bibtex
340
- @misc{project_funding_acknowledgment1,
341
- author = {Damian, Bleotiu, Saraev, Constantinescu},
342
- title = {SOLIS – Sistem Omogen multi-Locație cu funcționalități Inteligente și Sustenabile”
343
- SMIS 143488},
344
- howpublished = {\url{https://github.com/Naeural Edge ProtocolEdgeProtocol/}},
345
- note = {This project includes open-source components developed with support from the Romanian Competitiveness Operational Programme under grants SMIS 143488. The content is solely the responsibility of the authors and does not necessarily reflect the views of the funding agencies.},
346
- year = {2021-2022}
347
- }
348
- ```
349
-
350
- ```bibtex
351
- @misc{project_funding_acknowledgment2,
352
- author = {Damian, Bleotiu, Saraev, Constantinescu, Milik, Lupaescu},
353
- title = {ReDeN – Rețea Descentralizată Neurală SMIS 156084},
354
- howpublished = {\url{https://github.com/Naeural Edge ProtocolEdgeProtocol/}},
355
- note = {This project includes open-source components developed with support from the Romanian Competitiveness Operational Programme under grants SMIS 143488. The content is solely the responsibility of the authors and does not necessarily reflect the views of the funding agencies.},
356
- year = {2023-2024}
357
- }
358
- ```