naeural-client 2.2.6__tar.gz → 2.3.1__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.
- {naeural_client-2.2.6 → naeural_client-2.3.1}/PKG-INFO +5 -4
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/_ver.py +1 -1
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/generic_session.py +55 -11
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base_decentra_object.py +8 -2
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/bc/base.py +63 -7
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/bc/ec.py +144 -1
- naeural_client-2.3.1/naeural_client/cli/README.md +7 -0
- naeural_client-2.3.1/naeural_client/cli/cli.py +48 -0
- naeural_client-2.3.1/naeural_client/cli/cli_commands.py +15 -0
- naeural_client-2.3.1/naeural_client/cli/nodes.py +22 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/base_logger.py +63 -27
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/small_logger.py +2 -0
- naeural_client-2.3.1/naeural_client/utils/config.py +130 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/pyproject.toml +10 -5
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex01_part2_filter.py +4 -3
- naeural_client-2.3.1/xperimental/eth/eth_sign.py +74 -0
- naeural_client-2.3.1/xperimental/eth/info.md +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.devcontainer/Dockerfile +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.devcontainer/devcontainer.json +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.gitattributes +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.github/workflows/python-publish.yml +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.gitignore +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/.vscode/launch.json +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/LICENSE +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/README.md +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/TODOs.md +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/distributed_custom_code_presets.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/instance.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/payload/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/payload/payload.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/pipeline.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/plugin_template.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/responses.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/base/transaction.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/bc/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/bc/chain.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/certs/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/certs/r9092118.ala.eu-central-1.emqxsl.com.crt +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/code_cheker/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/code_cheker/base.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/code_cheker/checker.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/comm/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/comm/amqp_wrapper.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/comm/mqtt_wrapper.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/README.md +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/apps.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/base.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/comms.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/environment.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/formatter.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/heartbeat.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/misc.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/const/payload.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/chain_dist_custom_job_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/custom_web_app_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/net_mon_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/telegram_basic_bot_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/telegram_conversational_bot_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/instance/view_scene_01_plugin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/default/session/mqtt_session.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/base/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/base/base_formatter.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/default/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/default/a_dummy.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/default/aixp1.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/default/default.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/io_formatter/io_formatter_manager.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/class_instance_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/computer_vision_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/datetime_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/download_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/general_serialization_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/json_serialization_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/pickle_serialization_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/process_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/resource_size_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/timers_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/upload_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/logger_mixins/utils_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/tzlocal/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/tzlocal/unix.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/tzlocal/utils.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/tzlocal/win32.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/logging/tzlocal/windows_tz.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/plugins_manager_mixin.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/utils/__init__.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/utils/comm_utils.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/naeural_client/utils/dotenv.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/requirements.txt +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/.example_env +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/8. custom_code_fastapi_assets/index.html +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/9. code_sandbox_from_scratch_assets/index.html +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/_example_pk_sdk.pem +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex01_part1_connect.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex02_first_deploy.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex03_custom_code_on_one_remote__example_1.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex04_custom_code_on_one_remote__example_2.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex05_custom_code_on_one_remote__example_3.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex06_custom_code_on_multiple_remotes__example_1.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex07_custom_code_on_multiple_remotes__example_2.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex08_custom_web_app.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex09_code_sandbox_from_scratch.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex10_telegram_echo_bot.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex11_telegram_blackjack_bot.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/ex12_telegram_smart_bot.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/tutorials/video_presentation/1. hello_world.ipynb +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/winrun.bat +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/.example_env +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/README.md +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/_archive/test.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/_tutorials/3. simple_real_time_custom_code.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/_tutorials/4. real_time_custom_code_2.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/_tutorials/8. chatbot.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/attach_example.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/decentralized/chain_dist_example.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/decentralized/chain_dist_example_initiator.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/decentralized/chain_dist_example_worker.py +0 -0
- {naeural_client-2.2.6/xperimental → naeural_client-2.3.1/xperimental/enc_dec}/enc_dec_test.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/ex1.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/hello.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/remote_exec.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/save_images.py +0 -0
- {naeural_client-2.2.6 → naeural_client-2.3.1}/xperimental/utils/get_documentation.py +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: naeural_client
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.3.1
|
4
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/
|
6
|
-
Project-URL: Bug Tracker, https://github.com/
|
7
|
-
Author-email:
|
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
8
|
Classifier: License :: OSI Approved :: MIT License
|
9
9
|
Classifier: Operating System :: OS Independent
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
@@ -16,6 +16,7 @@ Requires-Dist: pika
|
|
16
16
|
Requires-Dist: pyaml
|
17
17
|
Requires-Dist: pyopenssl>=23.0.0
|
18
18
|
Requires-Dist: python-dateutil
|
19
|
+
Requires-Dist: web3
|
19
20
|
Description-Content-Type: text/markdown
|
20
21
|
|
21
22
|
# naeural_client SDK
|
@@ -17,9 +17,12 @@ from ..utils import load_dotenv
|
|
17
17
|
from .payload import Payload
|
18
18
|
from .pipeline import Pipeline
|
19
19
|
from .transaction import Transaction
|
20
|
+
from ..utils.config import load_user_defined_config, get_user_config_file
|
20
21
|
|
21
22
|
# TODO: add support for remaining commands from EE
|
22
23
|
|
24
|
+
DEBUG_MQTT_SERVER = "r9092118.ala.eu-central-1.emqxsl.com"
|
25
|
+
|
23
26
|
|
24
27
|
class GenericSession(BaseDecentrAIObject):
|
25
28
|
"""
|
@@ -59,7 +62,8 @@ class GenericSession(BaseDecentrAIObject):
|
|
59
62
|
on_payload=None,
|
60
63
|
on_notification=None,
|
61
64
|
on_heartbeat=None,
|
62
|
-
|
65
|
+
debug_silent=True,
|
66
|
+
silent=False,
|
63
67
|
verbosity=1,
|
64
68
|
dotenv_path=None,
|
65
69
|
show_commands=False,
|
@@ -120,8 +124,14 @@ class GenericSession(BaseDecentrAIObject):
|
|
120
124
|
Callback that handles heartbeats received from this network.
|
121
125
|
As arguments, it has a reference to this Session object, the node name and the heartbeat payload.
|
122
126
|
Defaults to None.
|
123
|
-
|
127
|
+
|
128
|
+
debug_silent : bool, optional
|
124
129
|
This flag will disable debug logs, set to 'False` for a more verbose log, by default True
|
130
|
+
|
131
|
+
silent : bool, optional
|
132
|
+
This flag will disable all logs, set to 'False` for a more verbose log, by default False
|
133
|
+
The logs will still be recored in the log file even if this flag is set to True.
|
134
|
+
|
125
135
|
dotenv_path : str, optional
|
126
136
|
Path to the .env file, by default None. If None, the path will be searched in the current working directory and in the directories of the files from the call stack.
|
127
137
|
root_topic : str, optional
|
@@ -142,6 +152,7 @@ class GenericSession(BaseDecentrAIObject):
|
|
142
152
|
|
143
153
|
self.log = log
|
144
154
|
self.name = name
|
155
|
+
self.silent = silent
|
145
156
|
|
146
157
|
self._verbosity = verbosity
|
147
158
|
self.encrypt_comms = encrypt_comms
|
@@ -158,7 +169,10 @@ class GenericSession(BaseDecentrAIObject):
|
|
158
169
|
pwd = pwd or kwargs.get('password', kwargs.get('pass', None))
|
159
170
|
user = user or kwargs.get('username', None)
|
160
171
|
host = host or kwargs.get('hostname', None)
|
172
|
+
|
173
|
+
## now we prepare config via ~/.naeural/config or .env
|
161
174
|
self.__fill_config(host, port, user, pwd, secured, dotenv_path)
|
175
|
+
## end config
|
162
176
|
|
163
177
|
self.custom_on_payload = on_payload
|
164
178
|
self.custom_on_heartbeat = on_heartbeat
|
@@ -180,15 +194,30 @@ class GenericSession(BaseDecentrAIObject):
|
|
180
194
|
self.__open_transactions_lock = Lock()
|
181
195
|
|
182
196
|
self.__create_user_callback_threads()
|
183
|
-
super(GenericSession, self).__init__(
|
197
|
+
super(GenericSession, self).__init__(
|
198
|
+
log=log,
|
199
|
+
DEBUG=not debug_silent,
|
200
|
+
create_logger=True,
|
201
|
+
silent=self.silent,
|
202
|
+
)
|
184
203
|
return
|
185
204
|
|
186
205
|
def startup(self):
|
187
|
-
|
206
|
+
# start the blockchain engine assuming config is already set
|
207
|
+
self.__start_blockchain(
|
208
|
+
self.__bc_engine, self.__blockchain_config,
|
209
|
+
user_config=self.__user_config_loaded,
|
210
|
+
)
|
211
|
+
# end bc_engine
|
188
212
|
self.formatter_wrapper = IOFormatterWrapper(self.log, plugin_search_locations=self.__formatter_plugins_locations)
|
189
213
|
|
190
214
|
self._connect()
|
191
215
|
|
216
|
+
self.P("Created {} comms session '{}' from <{}> SDKv{}.".format(
|
217
|
+
"decrypted" if not self.encrypt_comms else "encrypted",
|
218
|
+
self.name, self.bc_engine.address, self.log.version
|
219
|
+
))
|
220
|
+
|
192
221
|
if not self.encrypt_comms:
|
193
222
|
self.P(
|
194
223
|
"Warning: Emitted messages will not be encrypted.\n"
|
@@ -546,7 +575,7 @@ class GenericSession(BaseDecentrAIObject):
|
|
546
575
|
|
547
576
|
# Main loop
|
548
577
|
if True:
|
549
|
-
def __start_blockchain(self, bc_engine, blockchain_config):
|
578
|
+
def __start_blockchain(self, bc_engine, blockchain_config, user_config=False):
|
550
579
|
if bc_engine is not None:
|
551
580
|
self.bc_engine = bc_engine
|
552
581
|
return
|
@@ -557,6 +586,7 @@ class GenericSession(BaseDecentrAIObject):
|
|
557
586
|
name=self.name,
|
558
587
|
config=blockchain_config,
|
559
588
|
verbosity=self._verbosity,
|
589
|
+
user_config=user_config,
|
560
590
|
)
|
561
591
|
except:
|
562
592
|
raise ValueError("Failure in private blockchain setup:\n{}".format(traceback.format_exc()))
|
@@ -780,15 +810,19 @@ class GenericSession(BaseDecentrAIObject):
|
|
780
810
|
host : str
|
781
811
|
The hostname of the server.
|
782
812
|
Can be retrieved from the environment variables AIXP_HOSTNAME, AIXP_HOST
|
813
|
+
|
783
814
|
port : int
|
784
815
|
The port.
|
785
816
|
Can be retrieved from the environment variable AIXP_PORT
|
817
|
+
|
786
818
|
user : str
|
787
819
|
The user name.
|
788
820
|
Can be retrieved from the environment variables AIXP_USERNAME, AIXP_USER
|
821
|
+
|
789
822
|
pwd : str
|
790
823
|
The password.
|
791
824
|
Can be retrieved from the environment variables AIXP_PASSWORD, AIXP_PASS, AIXP_PWD
|
825
|
+
|
792
826
|
dotenv_path : str, optional
|
793
827
|
Path to the .env file, by default None. If None, the path will be searched in the current working directory and in the directories of the files from the call stack.
|
794
828
|
|
@@ -798,11 +832,21 @@ class GenericSession(BaseDecentrAIObject):
|
|
798
832
|
Missing credentials
|
799
833
|
"""
|
800
834
|
|
801
|
-
#
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
835
|
+
# if the ~/.naeural/config file exists, load the credentials from there else try to load them from .env
|
836
|
+
if not load_user_defined_config():
|
837
|
+
# this method will search for the credentials in the environment variables
|
838
|
+
# the path to env file, if not specified, will be search in the following order:
|
839
|
+
# 1. current working directory
|
840
|
+
# 2-N. directories of the files from the call stack
|
841
|
+
load_dotenv(dotenv_path=dotenv_path, verbose=False)
|
842
|
+
if not self.silent:
|
843
|
+
print("Loaded credentials from environment variables.", flush=True)
|
844
|
+
self.__user_config_loaded = False
|
845
|
+
else:
|
846
|
+
if not self.silent:
|
847
|
+
print(f"Loaded credentials from `{get_user_config_file()}`.", flush=True)
|
848
|
+
self.__user_config_loaded = True
|
849
|
+
# endif config loading from ~ or ./.env
|
806
850
|
|
807
851
|
possible_user_values = [
|
808
852
|
user,
|
@@ -849,7 +893,7 @@ class GenericSession(BaseDecentrAIObject):
|
|
849
893
|
os.getenv(ENVIRONMENT.EE_HOST),
|
850
894
|
os.getenv(ENVIRONMENT.EE_MQTT_HOST),
|
851
895
|
self._config.get(comm_ct.HOST),
|
852
|
-
|
896
|
+
DEBUG_MQTT_SERVER,
|
853
897
|
]
|
854
898
|
|
855
899
|
host = next((x for x in possible_host_values if x is not None), None)
|
@@ -24,6 +24,7 @@ class BaseDecentrAIObject(object):
|
|
24
24
|
show_prefixes=False,
|
25
25
|
prefix_log=None,
|
26
26
|
log_at_startup=False,
|
27
|
+
silent=False,
|
27
28
|
**kwargs):
|
28
29
|
|
29
30
|
super(BaseDecentrAIObject, self).__init__()
|
@@ -32,7 +33,13 @@ class BaseDecentrAIObject(object):
|
|
32
33
|
if not create_logger:
|
33
34
|
raise ValueError("Logger object is invalid: {}".format(log))
|
34
35
|
else:
|
35
|
-
log = Logger(
|
36
|
+
log = Logger(
|
37
|
+
"DEF",
|
38
|
+
DEBUG=DEBUG,
|
39
|
+
base_folder='.',
|
40
|
+
app_folder='_local_cache',
|
41
|
+
silent=silent,
|
42
|
+
)
|
36
43
|
# endif
|
37
44
|
|
38
45
|
self.log = log
|
@@ -79,7 +86,6 @@ class BaseDecentrAIObject(object):
|
|
79
86
|
msg = "{} {}".format(self.prefix_log, s)
|
80
87
|
# endif
|
81
88
|
# endif
|
82
|
-
|
83
89
|
_r = self.log.P(msg, show_time=t, color=color, **kwargs)
|
84
90
|
return _r
|
85
91
|
|
@@ -12,6 +12,8 @@ from copy import deepcopy
|
|
12
12
|
|
13
13
|
from cryptography.hazmat.primitives import serialization
|
14
14
|
|
15
|
+
from ..utils.config import get_user_folder
|
16
|
+
|
15
17
|
|
16
18
|
class BCct:
|
17
19
|
SIGN = 'EE_SIGN'
|
@@ -21,6 +23,7 @@ class BCct:
|
|
21
23
|
ADDR_PREFIX_OLD = "aixp_"
|
22
24
|
ADDR_PREFIX = "0xai_"
|
23
25
|
|
26
|
+
K_USER_CONFIG_PEM_FILE = 'NAEURAL_PEM_FILE'
|
24
27
|
K_PEM_FILE = 'PEM_FILE'
|
25
28
|
K_PASSWORD = 'PASSWORD'
|
26
29
|
K_PEM_LOCATION = 'PEM_LOCATION'
|
@@ -270,7 +273,7 @@ class BaseBlockEngine:
|
|
270
273
|
_lock: Lock = Lock()
|
271
274
|
__instances = {}
|
272
275
|
|
273
|
-
def __new__(cls, name, log, config, ensure_ascii_payloads=False, verbosity=1):
|
276
|
+
def __new__(cls, name, log, config, ensure_ascii_payloads=False, verbosity=1, user_config=False):
|
274
277
|
with cls._lock:
|
275
278
|
if name not in cls.__instances:
|
276
279
|
instance = super(BaseBlockEngine, cls).__new__(cls)
|
@@ -278,6 +281,7 @@ class BaseBlockEngine:
|
|
278
281
|
name=name, log=log, config=config,
|
279
282
|
ensure_ascii_payloads=ensure_ascii_payloads,
|
280
283
|
verbosity=verbosity,
|
284
|
+
user_config=user_config,
|
281
285
|
)
|
282
286
|
cls.__instances[name] = instance
|
283
287
|
else:
|
@@ -291,6 +295,7 @@ class BaseBlockEngine:
|
|
291
295
|
log=None,
|
292
296
|
ensure_ascii_payloads=False,
|
293
297
|
verbosity=1,
|
298
|
+
user_config=False,
|
294
299
|
):
|
295
300
|
|
296
301
|
self.__name = name
|
@@ -304,11 +309,15 @@ class BaseBlockEngine:
|
|
304
309
|
self.__config = config
|
305
310
|
self.__ensure_ascii_payloads = ensure_ascii_payloads
|
306
311
|
|
307
|
-
|
308
|
-
|
309
|
-
|
312
|
+
if user_config:
|
313
|
+
user_folder = get_user_folder()
|
314
|
+
pem_fn = str(user_folder / '_naeural.pem')
|
315
|
+
else:
|
316
|
+
pem_name = config.get(BCct.K_PEM_FILE, '_pk.pem')
|
317
|
+
pem_folder = config.get(BCct.K_PEM_LOCATION, 'data')
|
318
|
+
pem_fn = os.path.join(log.get_target_folder(pem_folder), pem_name)
|
319
|
+
#endif pem is defined in ~/.naeural/config
|
310
320
|
self.__pem_file = pem_fn
|
311
|
-
|
312
321
|
self._init()
|
313
322
|
return
|
314
323
|
|
@@ -353,9 +362,13 @@ class BaseBlockEngine:
|
|
353
362
|
password=self.__password,
|
354
363
|
fn=self.__pem_file,
|
355
364
|
)
|
356
|
-
self.__public_key = self._get_pk(private_key=self.__private_key)
|
365
|
+
self.__public_key = self._get_pk(private_key=self.__private_key)
|
357
366
|
self.__address = self._pk_to_address(self.__public_key)
|
358
|
-
|
367
|
+
### Ethereum
|
368
|
+
self.__eth_address = self._get_eth_address()
|
369
|
+
self.__eth_account = self._get_eth_account()
|
370
|
+
### end Ethereum
|
371
|
+
self.P("Address: {} / ETH: {}".format(self.address, self.eth_address), boxed=True, verbosity=1)
|
359
372
|
self.P("Allowed list of senders: {}".format(self.allowed_list), verbosity=1)
|
360
373
|
return
|
361
374
|
|
@@ -363,6 +376,11 @@ class BaseBlockEngine:
|
|
363
376
|
def private_key(self):
|
364
377
|
return self.__private_key
|
365
378
|
|
379
|
+
|
380
|
+
@property
|
381
|
+
def public_key(self):
|
382
|
+
return self.private_key.public_key()
|
383
|
+
|
366
384
|
|
367
385
|
@staticmethod
|
368
386
|
def _compute_hash(data : bytes, method='SHA256'):
|
@@ -717,6 +735,32 @@ class BaseBlockEngine:
|
|
717
735
|
|
718
736
|
"""
|
719
737
|
raise NotImplementedError()
|
738
|
+
|
739
|
+
|
740
|
+
def _get_eth_address(self):
|
741
|
+
"""
|
742
|
+
Returns the Ethereum address for the current pk
|
743
|
+
|
744
|
+
Returns
|
745
|
+
-------
|
746
|
+
eth_address : str
|
747
|
+
the Ethereum address.
|
748
|
+
|
749
|
+
"""
|
750
|
+
raise NotImplementedError()
|
751
|
+
|
752
|
+
|
753
|
+
def _get_eth_acccount(self):
|
754
|
+
"""
|
755
|
+
Returns the Ethereum account for the current sk
|
756
|
+
|
757
|
+
Returns
|
758
|
+
-------
|
759
|
+
eth_account : str
|
760
|
+
the Ethereum account.
|
761
|
+
|
762
|
+
"""
|
763
|
+
raise NotImplementedError()
|
720
764
|
|
721
765
|
|
722
766
|
|
@@ -1045,3 +1089,15 @@ class BaseBlockEngine:
|
|
1045
1089
|
"""
|
1046
1090
|
raise NotImplementedError()
|
1047
1091
|
|
1092
|
+
|
1093
|
+
### Ethereum
|
1094
|
+
|
1095
|
+
@property
|
1096
|
+
def eth_address(self):
|
1097
|
+
return self.__eth_address
|
1098
|
+
|
1099
|
+
@property
|
1100
|
+
def eth_account(self):
|
1101
|
+
return self.__eth_account
|
1102
|
+
|
1103
|
+
### end Ethereum
|
@@ -11,6 +11,11 @@ from cryptography.hazmat.backends import default_backend
|
|
11
11
|
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
12
12
|
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
13
13
|
|
14
|
+
from web3 import Web3
|
15
|
+
from eth_account import Account
|
16
|
+
from eth_utils import keccak, to_checksum_address
|
17
|
+
from eth_account.messages import encode_defunct
|
18
|
+
|
14
19
|
from .base import BaseBlockEngine, VerifyMessage, BCct
|
15
20
|
|
16
21
|
|
@@ -18,6 +23,7 @@ from .base import BaseBlockEngine, VerifyMessage, BCct
|
|
18
23
|
class BaseBCEllipticCurveEngine(BaseBlockEngine):
|
19
24
|
MAX_ADDRESS_VALUE = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
20
25
|
|
26
|
+
|
21
27
|
def _get_pk(self, private_key : ec.EllipticCurvePrivateKey) -> ec.EllipticCurvePublicKey:
|
22
28
|
"""
|
23
29
|
Simple wrapper to generate pk from sk
|
@@ -233,6 +239,7 @@ class BaseBCEllipticCurveEngine(BaseBlockEngine):
|
|
233
239
|
data=bpublic_key
|
234
240
|
)
|
235
241
|
return public_key
|
242
|
+
|
236
243
|
|
237
244
|
def __derive_shared_key(self, peer_public_key : str, info : str = BCct.DEFAULT_INFO, debug : bool = False):
|
238
245
|
"""
|
@@ -266,6 +273,7 @@ class BaseBCEllipticCurveEngine(BaseBlockEngine):
|
|
266
273
|
if debug:
|
267
274
|
print('derived-shared_key: ', base64.b64encode(derived_key))
|
268
275
|
return derived_key
|
276
|
+
|
269
277
|
|
270
278
|
def encrypt(
|
271
279
|
self,
|
@@ -380,5 +388,140 @@ class BaseBCEllipticCurveEngine(BaseBlockEngine):
|
|
380
388
|
|
381
389
|
result = plaintext.decode()
|
382
390
|
except Exception as exc:
|
391
|
+
if debug:
|
392
|
+
self.P("Error decrypting from <{}> (compressed_flag `{}`): {}".format(
|
393
|
+
sender_address, compressed_flag, exc), color='r'
|
394
|
+
)
|
383
395
|
result = None
|
384
|
-
return result
|
396
|
+
return result
|
397
|
+
|
398
|
+
|
399
|
+
|
400
|
+
### ETH
|
401
|
+
|
402
|
+
def _get_eth_address(self, pk=None):
|
403
|
+
if pk is None:
|
404
|
+
pk = self.public_key
|
405
|
+
raw_public_key = pk.public_numbers()
|
406
|
+
|
407
|
+
# Compute Ethereum-compatible address
|
408
|
+
x = raw_public_key.x.to_bytes(32, 'big')
|
409
|
+
y = raw_public_key.y.to_bytes(32, 'big')
|
410
|
+
uncompressed_key = b'\x04' + x + y
|
411
|
+
keccak_hash = keccak(uncompressed_key[1:]) # Remove 0x04 prefix
|
412
|
+
eth_address = "0x" + keccak_hash[-20:].hex()
|
413
|
+
eth_address = to_checksum_address(eth_address)
|
414
|
+
return eth_address
|
415
|
+
|
416
|
+
def _get_eth_account(self):
|
417
|
+
private_key_bytes = self.private_key.private_numbers().private_value.to_bytes(32, 'big')
|
418
|
+
return Account.from_key(private_key_bytes)
|
419
|
+
|
420
|
+
|
421
|
+
def node_address_to_eth_address(self, address):
|
422
|
+
"""
|
423
|
+
Converts a node address to an Ethereum address.
|
424
|
+
|
425
|
+
Parameters
|
426
|
+
----------
|
427
|
+
address : str
|
428
|
+
The node address convert.
|
429
|
+
|
430
|
+
Returns
|
431
|
+
-------
|
432
|
+
str
|
433
|
+
The Ethereum address.
|
434
|
+
"""
|
435
|
+
public_key = self._address_to_pk(address)
|
436
|
+
return self._get_eth_address(pk=public_key)
|
437
|
+
|
438
|
+
|
439
|
+
|
440
|
+
def eth_hash_message(self, types, values, as_hex=False):
|
441
|
+
"""
|
442
|
+
Hashes a message using the keccak256 algorithm.
|
443
|
+
|
444
|
+
Parameters
|
445
|
+
----------
|
446
|
+
types : list
|
447
|
+
The types of the values.
|
448
|
+
|
449
|
+
values : list of any
|
450
|
+
The values to hash.
|
451
|
+
|
452
|
+
Returns
|
453
|
+
-------
|
454
|
+
bytes
|
455
|
+
The hash of the message in hexadecimal format.
|
456
|
+
"""
|
457
|
+
message = Web3.solidity_keccak(types, values)
|
458
|
+
if as_hex:
|
459
|
+
return message.hex()
|
460
|
+
return message
|
461
|
+
|
462
|
+
|
463
|
+
def eth_sign_message(self, types, values):
|
464
|
+
"""
|
465
|
+
Signs a message using the private key.
|
466
|
+
|
467
|
+
Parameters
|
468
|
+
----------
|
469
|
+
types : list
|
470
|
+
The types of the values.
|
471
|
+
|
472
|
+
values : list of any
|
473
|
+
The values to sign.
|
474
|
+
|
475
|
+
Returns
|
476
|
+
-------
|
477
|
+
str
|
478
|
+
The signature of the message.
|
479
|
+
"""
|
480
|
+
message_hash = self.eth_hash_message(types, values, as_hex=False)
|
481
|
+
signable_message = encode_defunct(primitive=message_hash)
|
482
|
+
signed_message = Account.sign_message(signable_message, private_key=self.eth_account.key)
|
483
|
+
if hasattr(signed_message, "message_hash"): # backward compatibility
|
484
|
+
signed_message_hash = signed_message.message_hash
|
485
|
+
else:
|
486
|
+
signed_message_hash = signed_message.messageHash
|
487
|
+
return {
|
488
|
+
"message_hash": message_hash.hex(),
|
489
|
+
"r": hex(signed_message.r),
|
490
|
+
"s": hex(signed_message.s),
|
491
|
+
"v": signed_message.v,
|
492
|
+
"signature": signed_message.signature.hex(),
|
493
|
+
"signed_message": signed_message_hash.hex(),
|
494
|
+
"sender" : self.eth_address,
|
495
|
+
}
|
496
|
+
|
497
|
+
def eth_sign_node_epochs(self, node, epochs, epochs_vals, signature_only=True):
|
498
|
+
"""
|
499
|
+
Signs the node availability
|
500
|
+
|
501
|
+
Parameters
|
502
|
+
----------
|
503
|
+
node : str
|
504
|
+
The node address.
|
505
|
+
|
506
|
+
epochs : list of int
|
507
|
+
The epochs to sign.
|
508
|
+
|
509
|
+
epochs_vals : list of int
|
510
|
+
The values for each epoch.
|
511
|
+
|
512
|
+
signature_only : bool, optional
|
513
|
+
Whether to return only the signature. The default is True.
|
514
|
+
|
515
|
+
Returns
|
516
|
+
-------
|
517
|
+
str
|
518
|
+
The signature of the message.
|
519
|
+
"""
|
520
|
+
types = ["string", "uint256[]", "uint256[]"]
|
521
|
+
values = [node, epochs, epochs_vals]
|
522
|
+
result = self.eth_sign_message(types, values)
|
523
|
+
if signature_only:
|
524
|
+
return result["signature"]
|
525
|
+
return result
|
526
|
+
|
527
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import argparse
|
2
|
+
|
3
|
+
from naeural_client.utils.config import maybe_init_config, log_with_color
|
4
|
+
from naeural_client.cli.cli_commands import CLI_COMMANDS
|
5
|
+
|
6
|
+
from naeural_client import version
|
7
|
+
|
8
|
+
def build_parser():
|
9
|
+
"""
|
10
|
+
Dynamically builds the argument parser based on CLI_COMMANDS.
|
11
|
+
|
12
|
+
Returns
|
13
|
+
-------
|
14
|
+
argparse.ArgumentParser
|
15
|
+
Configured argument parser.
|
16
|
+
"""
|
17
|
+
descr = f"nepctl v{version} - CLI for Naeural Edge Protocol SDK package"
|
18
|
+
|
19
|
+
|
20
|
+
parser = argparse.ArgumentParser(description=descr)
|
21
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
22
|
+
|
23
|
+
# Iterate over top-level commands
|
24
|
+
for command, subcommands in CLI_COMMANDS.items():
|
25
|
+
command_parser = subparsers.add_parser(command, help=f"{command} commands")
|
26
|
+
if isinstance(subcommands, dict): # Nested subcommands
|
27
|
+
command_subparsers = command_parser.add_subparsers(dest="subcommand")
|
28
|
+
for subcommand, func in subcommands.items():
|
29
|
+
subcommand_parser = command_subparsers.add_parser(
|
30
|
+
subcommand, help=f"{subcommand} command"
|
31
|
+
)
|
32
|
+
subcommand_parser.set_defaults(func=func)
|
33
|
+
else:
|
34
|
+
command_parser.set_defaults(func=subcommands)
|
35
|
+
|
36
|
+
return parser
|
37
|
+
|
38
|
+
def main():
|
39
|
+
maybe_init_config()
|
40
|
+
parser = build_parser()
|
41
|
+
args = parser.parse_args()
|
42
|
+
if hasattr(args, "func"):
|
43
|
+
args.func() # Call the dynamically loaded function
|
44
|
+
else:
|
45
|
+
parser.print_help()
|
46
|
+
|
47
|
+
if __name__ == "__main__":
|
48
|
+
main()
|
@@ -0,0 +1,15 @@
|
|
1
|
+
from naeural_client.cli.nodes import get_nodes, get_supervisors
|
2
|
+
from naeural_client.utils.config import show_config, reset_config
|
3
|
+
|
4
|
+
|
5
|
+
# Define the available commands
|
6
|
+
CLI_COMMANDS = {
|
7
|
+
"get": {
|
8
|
+
"nodes": get_nodes,
|
9
|
+
"supervisors": get_supervisors,
|
10
|
+
},
|
11
|
+
"config": {
|
12
|
+
"show": show_config,
|
13
|
+
"reset": reset_config,
|
14
|
+
},
|
15
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
from naeural_client.utils.config import log_with_color
|
2
|
+
|
3
|
+
|
4
|
+
def get_nodes():
|
5
|
+
"""
|
6
|
+
This function is used to get the information about the nodes and it will perform the following:
|
7
|
+
|
8
|
+
1. Create a Session object.
|
9
|
+
2. Wait for the first net mon message via Session and show progress.
|
10
|
+
3. Wait for the second net mon message via Session and show progress.
|
11
|
+
4. Get the active nodes union via Session and display the nodes marking those peered vs non-peered.
|
12
|
+
"""
|
13
|
+
log_with_color("Getting nodes information", color="b")
|
14
|
+
return
|
15
|
+
|
16
|
+
|
17
|
+
def get_supervisors():
|
18
|
+
"""
|
19
|
+
This function is used to get the information about the supervisors.
|
20
|
+
"""
|
21
|
+
log_with_color("Getting supervisors information", color='b')
|
22
|
+
return
|