ratio1 3.4.36__tar.gz → 3.4.37__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.
- {ratio1-3.4.36 → ratio1-3.4.37}/PKG-INFO +1 -1
- {ratio1-3.4.36 → ratio1-3.4.37}/pyproject.toml +1 -1
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/_ver.py +1 -1
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/generic_session.py +264 -57
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/bc/evm.py +17 -1
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/cli_commands.py +16 -6
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/nodes.py +140 -4
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/oracles.py +35 -14
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/apps.py +1 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/plugins/deeploy_const.py +14 -0
- ratio1-3.4.37/tutorials/ex22_deeploy_custom_code.py +100 -0
- ratio1-3.4.37/xperimental/scripts/monitoring/collect_messages.py +57 -0
- ratio1-3.4.37/xperimental/scripts/monitoring/get_hb_distribution.py +153 -0
- ratio1-3.4.37/xperimental/scripts/monitoring/multithreaded_network_sniffer.py +171 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.devcontainer/Dockerfile +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.devcontainer/devcontainer.json +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.gitattributes +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.github/workflows/python-publish.yml +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.gitignore +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/.vscode/launch.json +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/LICENSE +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/README.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/TODOs.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/r1ctl.MD +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/distributed_custom_code_presets.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/instance.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/payload/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/payload/payload.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/pipeline.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/plugin_template.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/responses.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/transaction.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base/webapp_pipeline.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/base_decentra_object.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/bc/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/bc/base.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/bc/chain.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/bc/ec.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/certs/51.15.142.167.crt +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/certs/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/certs/a0d9818f.ala.eu-central-1.emqxsl.com.crt +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/certs/r9092118.ala.eu-central-1.emqxsl.com.crt +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/certs/s624dbd4.ala.us-east-1.emqxsl.com.crt +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/README.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/cli.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/cli/package_update.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/code_cheker/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/code_cheker/base.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/code_cheker/checker.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/comm/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/comm/amqp_wrapper.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/comm/base_comm_wrapper.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/comm/mqtt_wrapper.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/README.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/base.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/comms.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/environment.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/evm_net.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/formatter.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/heartbeat.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/misc.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/const/payload.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/chain_dist_custom_job_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/custom_webapi_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/generic_http_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/net_mon_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/telegram_basic_bot_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/telegram_conversational_bot_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/instance/view_scene_01_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/default/session/mqtt_session.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/base/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/base/base_formatter.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/default/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/default/a_dummy.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/default/aixp1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/default/default.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/io_formatter/io_formatter_manager.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ifps_keygen +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/ipfs.service +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/launch_service.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/restart.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/run.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/setup.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/show.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/ipfs_setup/write_key.sh +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/ipfs/r1fs.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/base_logger.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/class_instance_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/computer_vision_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/datetime_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/download_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/general_serialization_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/json_serialization_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/machine_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/pickle_serialization_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/process_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/resource_size_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/timers_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/upload_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/logger_mixins/utils_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/small_logger.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/tzlocal/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/tzlocal/unix.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/tzlocal/utils.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/tzlocal/win32.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/logging/tzlocal/windows_tz.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/plugins_manager_mixin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/utils/__init__.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/utils/comm_utils.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/utils/config.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/utils/dotenv.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/ratio1/utils/oracle_sync/oracle_tester.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/requirements.txt +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/template.env +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/.example_env +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/8. custom_code_fastapi_assets/index.html +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/9. code_sandbox_from_scratch_assets/index.html +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/_example_pk_sdk.pem +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/eth2025/deploy_home_safety.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/eth2025/deploy_maintenance_monitoring.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex01_part1_connect.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex01_part2_filter.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex01_part3_adv_filter.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex02_part1_deploy_webapi.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex02_part2_deploy_plugin.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex02_part3_deploy_r1fs_test.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex03_custom_code_on_one_remote__example_1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex04_custom_code_on_one_remote__example_2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex05_custom_code_on_one_remote__example_3.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex06_custom_code_on_multiple_remotes__example_1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex07_custom_code_on_multiple_remotes__example_2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex08_custom_webapi.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex09_code_sandbox_from_scratch.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex10_telegram_echo_bot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex11_telegram_blackjack_bot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex12_telegram_smart_bot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex13_launch_repo_based_webapp.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex14_wallets.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex15_telegram_rogue_style_game.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex16_launch_repo_based_http_server.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex17_launch_repo_based_balanced_webapp.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex18_deploy_container_webapi.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex19_deeploy_container_example.py +0 -0
- /ratio1-3.4.36/tutorials/ex20_deeploy_telegram_bot_example.py → /ratio1-3.4.37/tutorials/ex20_deeploy_telegram_bot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/ex21_telegram_community_bot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/tutorials/video_presentation/1. hello_world.ipynb +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/winrun.bat +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/README.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/_show_config_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/cstore_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/dauth_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/keys_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/node_info_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/ora_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/ora_intervals.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/ora_sign_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/owner_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/payload_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/session_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/w3_auth_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/w3_nodes_licenses.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/w3_oracles_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/whitelist_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/_checks/workload_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/dates/check_date.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/debug/close_pipeline.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/decentralized/chain_dist_example.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/decentralized/chain_dist_example_initiator.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/decentralized/chain_dist_example_worker.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/deeploy/checker.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/deeploy/checker2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/deeploy/create_request.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/enc_dec/enc_dec_test.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/balance.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/eth_sign.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/info.md +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/send.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/send_many.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/eth/sign.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/log.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/logger/run.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/lp/lp_checker.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/multi-enc-dec/multi_test1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/multi-enc-dec/multi_test2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/pipelines/start.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/pipelines/stop.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/sign/simple_payload_checker.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/sign/test_sign1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/sign/test_sign2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/test.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/tokens/get_check.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/utils/get_documentation.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/various/attach_example.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/various/ex1.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/various/hello.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/various/remote_exec.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/various/save_images.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/wl/wl_add.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/xarchive/_tutorials/3. simple_real_time_custom_code.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/xarchive/_tutorials/4. real_time_custom_code_2.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/xarchive/_tutorials/8. chatbot.py +0 -0
- {ratio1-3.4.36 → ratio1-3.4.37}/xperimental/xarchive/test.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ratio1
|
|
3
|
-
Version: 3.4.
|
|
3
|
+
Version: 3.4.37
|
|
4
4
|
Summary: `ratio1` or Ration1 SDK is the Python SDK required for client app development for the Ratio1 ecosystem
|
|
5
5
|
Project-URL: Homepage, https://github.com/Ratio1/ratio1_sdk
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/Ratio1/ratio1_sdk/issues
|
|
@@ -27,7 +27,6 @@ from ..const import (
|
|
|
27
27
|
BLOCKCHAIN_CONFIG, SESSION_CT, NET_CONFIG
|
|
28
28
|
)
|
|
29
29
|
from ..const import comms as comm_ct
|
|
30
|
-
from ..const.evm_net import EVM_NET_DATA, EvmNetData
|
|
31
30
|
from ..const import DEEPLOY_CT
|
|
32
31
|
from ..io_formatter import IOFormatterWrapper
|
|
33
32
|
from ..logging import Logger
|
|
@@ -1548,7 +1547,7 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
1548
1547
|
If no oracles are found for the wallet on the current network
|
|
1549
1548
|
"""
|
|
1550
1549
|
current_network = block_engine.current_evm_network
|
|
1551
|
-
api_base_url =
|
|
1550
|
+
api_base_url = block_engine.get_deeploy_url()
|
|
1552
1551
|
|
|
1553
1552
|
wallet_nodes = block_engine.web3_get_wallet_nodes(block_engine.eth_address)
|
|
1554
1553
|
oracles_on_the_network = block_engine.web3_get_oracles(current_network)
|
|
@@ -1750,6 +1749,13 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
1750
1749
|
dct_aliases = {v: k for k, v in self.__dct_node_address_to_alias.items()}
|
|
1751
1750
|
return dct_aliases
|
|
1752
1751
|
|
|
1752
|
+
def get_node_address(self, node):
|
|
1753
|
+
"""
|
|
1754
|
+
A public wrapper for __get_node_address.
|
|
1755
|
+
"""
|
|
1756
|
+
return self.__get_node_address(node)
|
|
1757
|
+
|
|
1758
|
+
|
|
1753
1759
|
def __get_node_address(self, node):
|
|
1754
1760
|
"""
|
|
1755
1761
|
Get the address of a node. If node is an address, return it. Else, return the address of the node.
|
|
@@ -2317,6 +2323,19 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
2317
2323
|
|
|
2318
2324
|
return active_supervisors
|
|
2319
2325
|
|
|
2326
|
+
def get_last_hb(self):
|
|
2327
|
+
"""
|
|
2328
|
+
Get the last heartbeat of all nodes.
|
|
2329
|
+
|
|
2330
|
+
Returns
|
|
2331
|
+
-------
|
|
2332
|
+
dict
|
|
2333
|
+
A dictionary with the last heartbeat of all nodes.
|
|
2334
|
+
Where the key is the node address and the value is the last heartbeat.
|
|
2335
|
+
"""
|
|
2336
|
+
return self._dct_online_nodes_last_heartbeat
|
|
2337
|
+
|
|
2338
|
+
|
|
2320
2339
|
def attach_to_pipeline(self, *,
|
|
2321
2340
|
node,
|
|
2322
2341
|
name,
|
|
@@ -3307,21 +3326,6 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
3307
3326
|
if target_nodes_count == 0 and len(target_nodes) == 0:
|
|
3308
3327
|
raise ValueError("You must specify at least one target node to deploy the container app.")
|
|
3309
3328
|
|
|
3310
|
-
# Check if PK exists
|
|
3311
|
-
if not os.path.isfile(signer_private_key_path):
|
|
3312
|
-
raise ValueError("Private key path is not valid.")
|
|
3313
|
-
|
|
3314
|
-
# Create a block engine instance with the private key
|
|
3315
|
-
block_engine = DefaultBlockEngine(
|
|
3316
|
-
log=logger,
|
|
3317
|
-
name="deeploy_launch_container_app",
|
|
3318
|
-
config={
|
|
3319
|
-
BCct.K_PEM_FILE: signer_private_key_path,
|
|
3320
|
-
BCct.K_PASSWORD: signer_private_key_password,
|
|
3321
|
-
}
|
|
3322
|
-
)
|
|
3323
|
-
|
|
3324
|
-
current_network, api_base_url = self.__validate_deeploy_network_and_get_api_url(block_engine)
|
|
3325
3329
|
#####################################################
|
|
3326
3330
|
|
|
3327
3331
|
assert callable(message_handler), "The `message_handler` method parameter must be provided."
|
|
@@ -3354,43 +3358,126 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
3354
3358
|
|
|
3355
3359
|
|
|
3356
3360
|
#####################################################
|
|
3357
|
-
|
|
3358
|
-
DEEPLOY_CT.DEEPLOY_KEYS.
|
|
3359
|
-
DEEPLOY_CT.DEEPLOY_KEYS.
|
|
3360
|
-
DEEPLOY_CT.DEEPLOY_KEYS.
|
|
3361
|
-
DEEPLOY_CT.DEEPLOY_KEYS.
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
'TELEGRAM_BOT_TOKEN': telegram_bot_token,
|
|
3366
|
-
'TELEGRAM_BOT_NAME': telegram_bot_name,
|
|
3367
|
-
'MESSAGE_HANDLER': func_base64_code,
|
|
3368
|
-
'MESSAGE_HANDLER_ARGS': func_args, # mandatory message and user
|
|
3369
|
-
'MESSAGE_HANDLER_NAME': func_name, # not mandatory
|
|
3370
|
-
'PROCESSING_HANDLER': proc_func_base64_code, # not mandatory
|
|
3371
|
-
'PROCESSING_HANDLER_ARGS': proc_func_args, # not mandatory
|
|
3361
|
+
app_params = {
|
|
3362
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_TELEGRAM_BOT_TOKEN: telegram_bot_token,
|
|
3363
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_TELEGRAM_BOT_NAME: telegram_bot_name,
|
|
3364
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_MESSAGE_HANDLER: func_base64_code,
|
|
3365
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_MESSAGE_HANDLER_ARGS: func_args, # mandatory message and user
|
|
3366
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_MESSAGE_HANDLER_NAME: func_name, # not mandatory
|
|
3367
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_PROCESSING_HANDLER: proc_func_base64_code, # not mandatory
|
|
3368
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_PROCESSING_HANDLER_ARGS: proc_func_args, # not mandatory
|
|
3372
3369
|
}
|
|
3373
3370
|
|
|
3371
|
+
api_base_url, request_body = self.__generate_deeploy_request(
|
|
3372
|
+
logger=logger,
|
|
3373
|
+
signer_private_key_path=signer_private_key_path,
|
|
3374
|
+
signer_private_key_password=signer_private_key_password,
|
|
3375
|
+
app_alias=name,
|
|
3376
|
+
signature=signature,
|
|
3377
|
+
target_nodes=target_nodes,
|
|
3378
|
+
target_nodes_count=target_nodes_count,
|
|
3379
|
+
app_params=app_params
|
|
3380
|
+
)
|
|
3381
|
+
|
|
3382
|
+
|
|
3374
3383
|
try:
|
|
3375
|
-
#
|
|
3376
|
-
|
|
3377
|
-
|
|
3384
|
+
# Send request
|
|
3385
|
+
response = requests.post(f"{api_base_url}/{DEEPLOY_CT.DEEPLOY_REQUEST_PATHS.CREATE_PIPELINE}", json=request_body)
|
|
3386
|
+
return response.json()
|
|
3387
|
+
except Exception as e:
|
|
3388
|
+
logger.P(f"Error during deeploy_simple_telegram_bot: {e}", color='r', show=True)
|
|
3389
|
+
raise e
|
|
3378
3390
|
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3391
|
+
def deeploy_custom_code(self,
|
|
3392
|
+
signer_private_key_path: str,
|
|
3393
|
+
logger,
|
|
3394
|
+
custom_code=None,
|
|
3395
|
+
target_nodes=[],
|
|
3396
|
+
target_nodes_count=0,
|
|
3397
|
+
signer_private_key_password='',
|
|
3398
|
+
name="deeploy_custom_code",
|
|
3399
|
+
signature=PLUGIN_SIGNATURES.CUSTOM_EXEC_01,
|
|
3400
|
+
config={},
|
|
3401
|
+
):
|
|
3402
|
+
"""
|
|
3403
|
+
Deploy custom Python code on the Ratio1 Edge Protocol network using the Deeploy API.
|
|
3404
|
+
Parameters
|
|
3405
|
+
----------
|
|
3406
|
+
signer_private_key_path : str
|
|
3407
|
+
Path to the PEM file containing the private key used for signing the deployment request
|
|
3408
|
+
|
|
3409
|
+
logger : Logger
|
|
3410
|
+
Logger instance for recording deployment activities and errors
|
|
3411
|
+
|
|
3412
|
+
custom_code : callable
|
|
3413
|
+
Python function to deploy. Must be a callable function that will be serialized and deployed to edge nodes.
|
|
3414
|
+
The function will be validated for syntax errors before deployment.
|
|
3415
|
+
|
|
3416
|
+
target_nodes : list, optional
|
|
3417
|
+
List of specific node addresses to deploy the custom code to.
|
|
3418
|
+
If empty, uses target_nodes_count instead. Defaults to []
|
|
3419
|
+
|
|
3420
|
+
target_nodes_count : int, optional
|
|
3421
|
+
Number of nodes to deploy to when target_nodes is not specified. Defaults to 0
|
|
3422
|
+
|
|
3423
|
+
signer_private_key_password : str, optional
|
|
3424
|
+
Password for the private key file if it's encrypted. Defaults to ''
|
|
3425
|
+
|
|
3426
|
+
name : str, optional
|
|
3427
|
+
Application alias/name for identification. Defaults to "deeploy_custom_code"
|
|
3428
|
+
|
|
3429
|
+
signature : str, optional
|
|
3430
|
+
The signature of the plugin that will be used. Defaults to PLUGIN_SIGNATURES.CUSTOM_EXEC_01
|
|
3431
|
+
|
|
3432
|
+
config : dict, optional
|
|
3433
|
+
Additional configuration parameters to pass to the deployed custom code.
|
|
3434
|
+
These parameters will be available to the custom code at runtime. Defaults to {}
|
|
3435
|
+
|
|
3436
|
+
Returns
|
|
3437
|
+
-------
|
|
3438
|
+
dict
|
|
3439
|
+
JSON response from the Deeploy API containing deployment status and details
|
|
3386
3440
|
|
|
3441
|
+
"""
|
|
3442
|
+
if target_nodes_count == 0 and len(target_nodes) == 0:
|
|
3443
|
+
raise ValueError("You must specify at least one target node to deploy the container app.")
|
|
3444
|
+
|
|
3445
|
+
#####################################################
|
|
3446
|
+
|
|
3447
|
+
assert callable(custom_code), "The `custom_code` method parameter must be provided."
|
|
3448
|
+
|
|
3449
|
+
base_code_checker_inst = BaseCodeChecker()
|
|
3450
|
+
|
|
3451
|
+
plain_code = base_code_checker_inst.get_function_source_code(custom_code)
|
|
3452
|
+
custom_code_base64, error_messages = base_code_checker_inst.code_to_base64(plain_code, return_errors=True)
|
|
3453
|
+
if error_messages:
|
|
3454
|
+
raise ValueError(f"Custom code has errors: {error_messages}")
|
|
3455
|
+
#####################################################
|
|
3456
|
+
app_params = {
|
|
3457
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS_CODE: custom_code_base64,
|
|
3458
|
+
**config
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
api_base_url, request_body = self.__generate_deeploy_request(
|
|
3462
|
+
logger=logger,
|
|
3463
|
+
signer_private_key_path=signer_private_key_path,
|
|
3464
|
+
signer_private_key_password=signer_private_key_password,
|
|
3465
|
+
app_alias=name,
|
|
3466
|
+
signature=signature,
|
|
3467
|
+
target_nodes=target_nodes,
|
|
3468
|
+
target_nodes_count=target_nodes_count,
|
|
3469
|
+
app_params=app_params
|
|
3470
|
+
)
|
|
3471
|
+
|
|
3472
|
+
try:
|
|
3387
3473
|
# Send request
|
|
3388
|
-
response = requests.post(f"{api_base_url}/{DEEPLOY_CT.DEEPLOY_REQUEST_PATHS.CREATE_PIPELINE}", json=
|
|
3474
|
+
response = requests.post(f"{api_base_url}/{DEEPLOY_CT.DEEPLOY_REQUEST_PATHS.CREATE_PIPELINE}", json=request_body)
|
|
3389
3475
|
return response.json()
|
|
3390
3476
|
except Exception as e:
|
|
3391
|
-
logger.P(f"Error during
|
|
3477
|
+
logger.P(f"Error during deeploy_custom_code: {e}", color='r', show=True)
|
|
3392
3478
|
raise e
|
|
3393
3479
|
|
|
3480
|
+
|
|
3394
3481
|
def deeploy_close(self, logger,
|
|
3395
3482
|
signer_private_key_path: str,
|
|
3396
3483
|
app_id: str,
|
|
@@ -3471,37 +3558,157 @@ class GenericSession(BaseDecentrAIObject):
|
|
|
3471
3558
|
--------
|
|
3472
3559
|
deeploy_launch_container_app : Deploy a new containerized application
|
|
3473
3560
|
"""
|
|
3561
|
+
|
|
3562
|
+
|
|
3563
|
+
api_base_url, request_body = self.__generate_deeploy_request(
|
|
3564
|
+
logger=logger,
|
|
3565
|
+
signer_private_key_path=signer_private_key_path,
|
|
3566
|
+
signer_private_key_password=signer_private_key_password,
|
|
3567
|
+
request_params={
|
|
3568
|
+
DEEPLOY_CT.DEEPLOY_KEYS.APP_ID: app_id,
|
|
3569
|
+
DEEPLOY_CT.DEEPLOY_KEYS.TARGET_NODES: target_nodes,
|
|
3570
|
+
}
|
|
3571
|
+
)
|
|
3572
|
+
|
|
3573
|
+
endpoint = DEEPLOY_CT.DEEPLOY_REQUEST_PATHS.DELETE_PIPELINE
|
|
3574
|
+
response = requests.post(f"{api_base_url}/{endpoint}", json=request_body)
|
|
3575
|
+
return response.json()
|
|
3576
|
+
|
|
3577
|
+
def __generate_deeploy_request(self,
|
|
3578
|
+
logger,
|
|
3579
|
+
signer_private_key_path,
|
|
3580
|
+
signer_private_key_password,
|
|
3581
|
+
app_alias=None,
|
|
3582
|
+
signature=None,
|
|
3583
|
+
target_nodes=None,
|
|
3584
|
+
target_nodes_count=0,
|
|
3585
|
+
app_params={},
|
|
3586
|
+
request_params={}):
|
|
3587
|
+
"""
|
|
3588
|
+
Generate a signed Deeploy API request for deploying applications to edge nodes.
|
|
3589
|
+
|
|
3590
|
+
This method creates a properly formatted and cryptographically signed request
|
|
3591
|
+
that can be sent to the Deeploy API for deploying various types of applications
|
|
3592
|
+
(containers, custom code, Telegram bots, etc.) to the Ratio1 Edge Protocol network.
|
|
3593
|
+
|
|
3594
|
+
Parameters
|
|
3595
|
+
----------
|
|
3596
|
+
logger : Logger
|
|
3597
|
+
Logger instance for recording request generation activities and errors
|
|
3598
|
+
|
|
3599
|
+
signer_private_key_path : str
|
|
3600
|
+
Path to the PEM file containing the private key used for signing the request
|
|
3601
|
+
|
|
3602
|
+
signer_private_key_password : str
|
|
3603
|
+
Password for the private key file if it's encrypted
|
|
3604
|
+
|
|
3605
|
+
app_alias : str, optional
|
|
3606
|
+
Application alias/name for identification in the Deeploy system.
|
|
3607
|
+
Required for creation requests, not needed for deletion or query operations.
|
|
3608
|
+
Defaults to None
|
|
3609
|
+
|
|
3610
|
+
signature : str, optional
|
|
3611
|
+
The plugin signature that identifies the type of application to deploy
|
|
3612
|
+
(e.g., CONTAINER_APP_RUNNER, TELEGRAM_BASIC_BOT_01, CUSTOM_EXEC_01).
|
|
3613
|
+
Required for creation requests, not needed for deletion or query operations.
|
|
3614
|
+
Defaults to None
|
|
3615
|
+
|
|
3616
|
+
target_nodes : list, optional
|
|
3617
|
+
List of specific node addresses to deploy the application to.
|
|
3618
|
+
If empty, uses target_nodes_count instead.
|
|
3619
|
+
Required for creation requests, optional for other operations.
|
|
3620
|
+
Defaults to None
|
|
3621
|
+
|
|
3622
|
+
target_nodes_count : int, optional
|
|
3623
|
+
Number of nodes to deploy to when target_nodes is not specified.
|
|
3624
|
+
Used when you want Deeploy to automatically select nodes.
|
|
3625
|
+
Defaults to 0
|
|
3626
|
+
|
|
3627
|
+
app_params : dict, optional
|
|
3628
|
+
Application-specific parameters that will be passed to the deployed application.
|
|
3629
|
+
These parameters vary depending on the application type and signature.
|
|
3630
|
+
Defaults to {}
|
|
3631
|
+
|
|
3632
|
+
request_params : dict, optional
|
|
3633
|
+
Additional parameters to include in the request payload.
|
|
3634
|
+
These are typically metadata or configuration options for the deployment process.
|
|
3635
|
+
Defaults to {}
|
|
3636
|
+
|
|
3637
|
+
Returns
|
|
3638
|
+
-------
|
|
3639
|
+
tuple
|
|
3640
|
+
A tuple containing (api_base_url, request_body) where:
|
|
3641
|
+
- api_base_url (str): The base URL for the Deeploy API endpoint
|
|
3642
|
+
- request_body (dict): The complete signed request payload ready for HTTP transmission
|
|
3643
|
+
|
|
3644
|
+
Examples
|
|
3645
|
+
--------
|
|
3646
|
+
Generate a request for deploying a container application:
|
|
3647
|
+
|
|
3648
|
+
>>> api_url, request = session.__generate_deeploy_request(
|
|
3649
|
+
... logger=my_logger,
|
|
3650
|
+
... signer_private_key_path="/path/to/private_key.pem",
|
|
3651
|
+
... signer_private_key_password="",
|
|
3652
|
+
... app_alias="my_web_app",
|
|
3653
|
+
... signature="CONTAINER_APP_RUNNER",
|
|
3654
|
+
... target_nodes=["node1_address", "node2_address"],
|
|
3655
|
+
... target_nodes_count=0,
|
|
3656
|
+
... app_params={"image": "nginx:latest", "port": 80}
|
|
3657
|
+
... )
|
|
3658
|
+
|
|
3659
|
+
Generate a request for deleting an application (no signature/app_alias needed):
|
|
3660
|
+
|
|
3661
|
+
>>> api_url, request = session.__generate_deeploy_request(
|
|
3662
|
+
... logger=my_logger,
|
|
3663
|
+
... signer_private_key_path="/path/to/private_key.pem",
|
|
3664
|
+
... signer_private_key_password="",
|
|
3665
|
+
... request_params={"app_id": "my_app_12345", "target_nodes": ["node1_address"]}
|
|
3666
|
+
... )
|
|
3667
|
+
"""
|
|
3668
|
+
|
|
3669
|
+
request_body = {DEEPLOY_CT.DEEPLOY_KEYS.REQUEST: {
|
|
3670
|
+
DEEPLOY_CT.DEEPLOY_KEYS.TARGET_NODES_COUNT: target_nodes_count,
|
|
3671
|
+
**request_params
|
|
3672
|
+
}}
|
|
3673
|
+
|
|
3674
|
+
# Add creation-specific fields only if provided
|
|
3675
|
+
if app_alias is not None:
|
|
3676
|
+
request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.APP_ALIAS] = app_alias
|
|
3677
|
+
if signature is not None:
|
|
3678
|
+
request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.PLUGIN_SIGNATURE] = signature
|
|
3679
|
+
if target_nodes is not None:
|
|
3680
|
+
request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.TARGET_NODES] = target_nodes
|
|
3681
|
+
if app_params:
|
|
3682
|
+
request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.APP_PARAMS] = app_params
|
|
3683
|
+
|
|
3684
|
+
# Check if PK exists
|
|
3685
|
+
if not os.path.isfile(signer_private_key_path):
|
|
3686
|
+
raise ValueError("Private key path is not valid.")
|
|
3687
|
+
|
|
3474
3688
|
# Create a block engine instance with the private key
|
|
3475
3689
|
block_engine = DefaultBlockEngine(
|
|
3476
3690
|
log=logger,
|
|
3477
|
-
name="
|
|
3691
|
+
name="deeploy_request_block_engine",
|
|
3478
3692
|
config={
|
|
3479
3693
|
BCct.K_PEM_FILE: signer_private_key_path,
|
|
3480
3694
|
BCct.K_PASSWORD: signer_private_key_password,
|
|
3481
3695
|
}
|
|
3482
3696
|
)
|
|
3483
3697
|
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
endpoint = DEEPLOY_CT.DEEPLOY_REQUEST_PATHS.DELETE_PIPELINE
|
|
3487
|
-
request_data = {DEEPLOY_CT.DEEPLOY_KEYS.REQUEST: {}}
|
|
3488
|
-
request_data[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.APP_ID] = app_id
|
|
3489
|
-
request_data[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.TARGET_NODES] = target_nodes
|
|
3490
|
-
|
|
3698
|
+
# Set the nonce for the request
|
|
3491
3699
|
nonce = f"0x{int(time.time() * 1000):x}"
|
|
3492
|
-
|
|
3700
|
+
request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST][DEEPLOY_CT.DEEPLOY_KEYS.NONCE] = nonce
|
|
3493
3701
|
|
|
3494
3702
|
# Sign the payload using eth_sign_payload
|
|
3495
3703
|
block_engine.eth_sign_payload(
|
|
3496
|
-
payload=
|
|
3704
|
+
payload=request_body[DEEPLOY_CT.DEEPLOY_KEYS.REQUEST],
|
|
3497
3705
|
indent=1,
|
|
3498
3706
|
no_hash=True,
|
|
3499
3707
|
message_prefix="Please sign this message for Deeploy: "
|
|
3500
3708
|
)
|
|
3501
3709
|
|
|
3502
|
-
|
|
3503
|
-
return
|
|
3504
|
-
|
|
3710
|
+
_, api_base_url = self.__validate_deeploy_network_and_get_api_url(block_engine)
|
|
3711
|
+
return api_base_url, request_body
|
|
3505
3712
|
|
|
3506
3713
|
def __is_assets_valid(self, assets, mandatory=True, raise_exception=True, default_field_values=None):
|
|
3507
3714
|
if assets is None:
|
|
@@ -11,6 +11,7 @@ from eth_utils import keccak, to_checksum_address
|
|
|
11
11
|
from eth_account.messages import encode_defunct
|
|
12
12
|
|
|
13
13
|
from ..const.base import EE_VPN_IMPL_ENV_KEY, dAuth, BCctbase, ETHVarTypes, EVM_ABI_DATA
|
|
14
|
+
from ..const.evm_net import EVM_NET_DATA, EvmNetData
|
|
14
15
|
|
|
15
16
|
EE_VPN_IMPL = str(os.environ.get(EE_VPN_IMPL_ENV_KEY, False)).lower() in [
|
|
16
17
|
'true', '1', 'yes', 'y', 't', 'on'
|
|
@@ -1291,4 +1292,19 @@ class _EVMMixin:
|
|
|
1291
1292
|
"r1Balance": float(r1_balance),
|
|
1292
1293
|
}
|
|
1293
1294
|
|
|
1294
|
-
return balances
|
|
1295
|
+
return balances
|
|
1296
|
+
|
|
1297
|
+
|
|
1298
|
+
def get_deeploy_url(self):
|
|
1299
|
+
"""
|
|
1300
|
+
Returns the deeploy URL from the environment or the network data
|
|
1301
|
+
|
|
1302
|
+
Returns
|
|
1303
|
+
-------
|
|
1304
|
+
str
|
|
1305
|
+
the deeploy URL.
|
|
1306
|
+
|
|
1307
|
+
"""
|
|
1308
|
+
current_network = self.current_evm_network
|
|
1309
|
+
deeploy_api_base_url = EVM_NET_DATA[current_network][EvmNetData.EE_DEEPLOY_API_URL_KEY]
|
|
1310
|
+
return deeploy_api_base_url
|
|
@@ -10,9 +10,9 @@ and it is used by cli.py
|
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from ratio1.cli.nodes import (
|
|
13
|
-
get_nodes, get_supervisors,
|
|
13
|
+
get_nodes, get_supervisors,
|
|
14
14
|
restart_node, shutdown_node,
|
|
15
|
-
get_apps
|
|
15
|
+
get_apps, inspect_node
|
|
16
16
|
)
|
|
17
17
|
from ratio1.cli.oracles import get_availability, oracle_rollout
|
|
18
18
|
from ratio1.utils.config import (
|
|
@@ -122,14 +122,16 @@ CLI_COMMANDS = {
|
|
|
122
122
|
"func": restart_node,
|
|
123
123
|
"description": "Restart a node",
|
|
124
124
|
"params": {
|
|
125
|
-
"node": "The node to restart"
|
|
125
|
+
"node": "The node to restart",
|
|
126
|
+
"--ignore-peering": "Ignore peering when running the command (flag)",
|
|
126
127
|
}
|
|
127
128
|
},
|
|
128
129
|
"shutdown": {
|
|
129
130
|
"func": shutdown_node,
|
|
130
131
|
"description": "Shutdown a node",
|
|
131
132
|
"params": {
|
|
132
|
-
"node": "The node to shutdown"
|
|
133
|
+
"node": "The node to shutdown",
|
|
134
|
+
"--ignore-peering": "Ignore peering when running the command (flag)",
|
|
133
135
|
}
|
|
134
136
|
},
|
|
135
137
|
"update": {
|
|
@@ -141,6 +143,14 @@ CLI_COMMANDS = {
|
|
|
141
143
|
},
|
|
142
144
|
"oracle-rollout": {
|
|
143
145
|
"func": oracle_rollout,
|
|
144
|
-
"description": "Rollout update on all nodes in the network. The rollout order is seed nodes -> oracle nodes -> all other edge nodes. This command is needed when defining new environment variables in seed nodes, in order to make it available to all nodes in the network."
|
|
145
|
-
}
|
|
146
|
+
"description": "Rollout update on all nodes in the network. The rollout order is seed nodes -> oracle nodes -> all other edge nodes. This command is needed when defining new environment variables in seed nodes, in order to make it available to all nodes in the network."
|
|
147
|
+
},
|
|
148
|
+
"inspect": {
|
|
149
|
+
"func": inspect_node,
|
|
150
|
+
"description": "Inspect a node by address or alias.",
|
|
151
|
+
"params": {
|
|
152
|
+
"node": "The node address or alias to inspect",
|
|
153
|
+
"--wide": "Display all available information (flag)"
|
|
154
|
+
}
|
|
155
|
+
},
|
|
146
156
|
}
|
|
@@ -211,8 +211,8 @@ def get_apps(args):
|
|
|
211
211
|
def _send_command_to_node(args, command, ignore_not_found=False):
|
|
212
212
|
node = args.node
|
|
213
213
|
silent = not args.verbose
|
|
214
|
+
ignore_peering = args.ignore_peering
|
|
214
215
|
|
|
215
|
-
|
|
216
216
|
t1 = time()
|
|
217
217
|
df, _, _, _, _, sess = _get_netstats(
|
|
218
218
|
silent=silent, online_only=True, return_session=True, all_info=True,
|
|
@@ -233,17 +233,21 @@ def _send_command_to_node(args, command, ignore_not_found=False):
|
|
|
233
233
|
node_addr = df_found.Address.values[0]
|
|
234
234
|
log_with_color(f"{df_found}")
|
|
235
235
|
else:
|
|
236
|
-
log_with_color("Node '{}' <{}> not found in network (
|
|
236
|
+
log_with_color("Node '{}' <{}> not found in network (total {} nodes, {} peered).".format(
|
|
237
237
|
node, node_addr, df.shape[0], df.Peered.sum()), color='r'
|
|
238
238
|
)
|
|
239
239
|
node_addr = node
|
|
240
|
-
|
|
240
|
+
|
|
241
|
+
if not peered and not ignore_peering:
|
|
242
|
+
log_with_color(f"Node '{node}' <{node_addr}> not peered, exiting...", color='r')
|
|
243
|
+
return
|
|
244
|
+
|
|
241
245
|
if not peered:
|
|
242
246
|
if found:
|
|
243
247
|
log_with_color(f"Node '{node}' <{node_addr}> is not peered.", color='r')
|
|
244
248
|
else:
|
|
245
249
|
log_with_color(f"Node '{node}' <{node_addr}> may not accept this command.", color='r')
|
|
246
|
-
|
|
250
|
+
|
|
247
251
|
# TODO: currently this is based on node alias, but we should be based on node address
|
|
248
252
|
# and maybe even node alias
|
|
249
253
|
if (found and peered) or ignore_not_found:
|
|
@@ -271,6 +275,7 @@ def restart_node(args):
|
|
|
271
275
|
Arguments passed to the function.
|
|
272
276
|
"""
|
|
273
277
|
node = args.node
|
|
278
|
+
|
|
274
279
|
log_with_color(f"Attempting to restart node <{node}>", color='b')
|
|
275
280
|
_send_command_to_node(args, COMMANDS.RESTART, ignore_not_found=True)
|
|
276
281
|
return
|
|
@@ -286,7 +291,138 @@ def shutdown_node(args):
|
|
|
286
291
|
Arguments passed to the function.
|
|
287
292
|
"""
|
|
288
293
|
node = args.node
|
|
294
|
+
|
|
289
295
|
log_with_color(f"Attempting to shutdown node <{node}>", color='b')
|
|
290
296
|
_send_command_to_node(args, COMMANDS.STOP, ignore_not_found=True)
|
|
291
297
|
return
|
|
292
298
|
|
|
299
|
+
|
|
300
|
+
def inspect_node(args):
|
|
301
|
+
"""
|
|
302
|
+
This function is used to inspect the node info.
|
|
303
|
+
|
|
304
|
+
Parameters
|
|
305
|
+
----------
|
|
306
|
+
args : argparse.Namespace
|
|
307
|
+
Arguments passed to the function.
|
|
308
|
+
"""
|
|
309
|
+
node = args.node
|
|
310
|
+
wide = args.wide
|
|
311
|
+
silent = not args.verbose
|
|
312
|
+
|
|
313
|
+
if not silent:
|
|
314
|
+
log_with_color(f"Inspecting node <{node}>", color='b')
|
|
315
|
+
|
|
316
|
+
from ratio1 import Session
|
|
317
|
+
session = Session(
|
|
318
|
+
silent=silent
|
|
319
|
+
)
|
|
320
|
+
try:
|
|
321
|
+
node_address = session.get_node_address(node)
|
|
322
|
+
last_hb = session.get_last_hb()
|
|
323
|
+
node_last_hb = last_hb.get(node_address)
|
|
324
|
+
|
|
325
|
+
if not node_last_hb:
|
|
326
|
+
# No last HB was found for specified Address, ETH Address or alias.
|
|
327
|
+
raise ValueError("Could not find a node by provided address/alias.")
|
|
328
|
+
|
|
329
|
+
# Display node stats from HB:
|
|
330
|
+
_display_node_stats_for_hb(node_last_hb, wide)
|
|
331
|
+
|
|
332
|
+
except Exception as e:
|
|
333
|
+
log_with_color(f"An error occurred while trying to get node info: {e}", color='r')
|
|
334
|
+
finally:
|
|
335
|
+
session.close()
|
|
336
|
+
return
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def _display_node_stats_for_hb(node_hb, wide=False):
|
|
340
|
+
"""
|
|
341
|
+
Display main system information from node heartbeat data.
|
|
342
|
+
|
|
343
|
+
Parameters
|
|
344
|
+
----------
|
|
345
|
+
node_hb : dict
|
|
346
|
+
Node heartbeat data containing system information
|
|
347
|
+
wide: bool
|
|
348
|
+
If True, display all plugins.
|
|
349
|
+
"""
|
|
350
|
+
from ratio1 import HEARTBEAT_DATA
|
|
351
|
+
from ratio1.utils.config import log_with_color
|
|
352
|
+
from ratio1.const.base import BCctbase
|
|
353
|
+
from ratio1 import PAYLOAD_DATA
|
|
354
|
+
|
|
355
|
+
# Extract basic node info
|
|
356
|
+
ee_id = node_hb.get(HEARTBEAT_DATA.EE_ID, 'Unknown')
|
|
357
|
+
node_addr = node_hb.get(HEARTBEAT_DATA.EE_ADDR, 'Unknown')
|
|
358
|
+
eth_addr = node_hb.get(BCctbase.ETH_SENDER, 'Unknown')
|
|
359
|
+
ee_version = node_hb.get(PAYLOAD_DATA.EE_VERSION, 'Unknown')
|
|
360
|
+
uptime = node_hb.get(HEARTBEAT_DATA.UPTIME, 0)
|
|
361
|
+
|
|
362
|
+
# Display node header
|
|
363
|
+
log_with_color(f"\n=== Node Information ===", color='b')
|
|
364
|
+
log_with_color(f"Node alias: {ee_id}", color='g')
|
|
365
|
+
log_with_color(f"Address: {node_addr}", color='g')
|
|
366
|
+
log_with_color(f"ETH Address: {eth_addr}", color='g')
|
|
367
|
+
log_with_color(f"Edge Node Version: {ee_version}", color='g')
|
|
368
|
+
log_with_color(f"Uptime: {uptime:.1f} seconds ({uptime/3600:.1f} hours)", color='g')
|
|
369
|
+
|
|
370
|
+
# CPU Information
|
|
371
|
+
cpu_info = node_hb.get(HEARTBEAT_DATA.CPU, 'Unknown')
|
|
372
|
+
cpu_cores = node_hb.get(HEARTBEAT_DATA.CPU_NR_CORES, 0)
|
|
373
|
+
cpu_used = node_hb.get(HEARTBEAT_DATA.CPU_USED, 0)
|
|
374
|
+
|
|
375
|
+
log_with_color(f"\n=== CPU Information ===", color='b')
|
|
376
|
+
log_with_color(f"Processor: {cpu_info}", color='y')
|
|
377
|
+
log_with_color(f"Cores: {cpu_cores}", color='y')
|
|
378
|
+
log_with_color(f"Usage: {cpu_used:.1f}%", color='y')
|
|
379
|
+
|
|
380
|
+
# Memory Information
|
|
381
|
+
total_memory = node_hb.get(HEARTBEAT_DATA.MACHINE_MEMORY, 0)
|
|
382
|
+
available_memory = node_hb.get(HEARTBEAT_DATA.AVAILABLE_MEMORY, 0)
|
|
383
|
+
process_memory = node_hb.get(HEARTBEAT_DATA.PROCESS_MEMORY, 0)
|
|
384
|
+
is_alert_ram = node_hb.get(HEARTBEAT_DATA.IS_ALERT_RAM, False)
|
|
385
|
+
|
|
386
|
+
used_memory = total_memory - available_memory if total_memory and available_memory else 0
|
|
387
|
+
memory_usage_pct = (used_memory / total_memory * 100) if total_memory > 0 else 0
|
|
388
|
+
|
|
389
|
+
log_with_color(f"\n=== Memory Information ===", color='b')
|
|
390
|
+
log_with_color(f"Total Memory: {total_memory:.2f} GB", color='y')
|
|
391
|
+
log_with_color(f"Available Memory: {available_memory:.2f} GB", color='y')
|
|
392
|
+
log_with_color(f"Used Memory: {used_memory:.2f} GB ({memory_usage_pct:.1f}%)", color='y')
|
|
393
|
+
log_with_color(f"Process Memory: {process_memory:.2f} GB", color='y')
|
|
394
|
+
if is_alert_ram:
|
|
395
|
+
log_with_color(f"RAM Alert: True", color='r')
|
|
396
|
+
|
|
397
|
+
# Disk Information
|
|
398
|
+
total_disk = node_hb.get(HEARTBEAT_DATA.TOTAL_DISK, 0)
|
|
399
|
+
available_disk = node_hb.get(HEARTBEAT_DATA.AVAILABLE_DISK, 0)
|
|
400
|
+
|
|
401
|
+
used_disk = total_disk - available_disk if total_disk and available_disk else 0
|
|
402
|
+
disk_usage_pct = (used_disk / total_disk * 100) if total_disk > 0 else 0
|
|
403
|
+
|
|
404
|
+
log_with_color(f"\n=== Disk Information ===", color='b')
|
|
405
|
+
log_with_color(f"Total Disk: {total_disk:.2f} GB", color='y')
|
|
406
|
+
log_with_color(f"Available Disk: {available_disk:.2f} GB", color='y')
|
|
407
|
+
log_with_color(f"Used Disk: {used_disk:.2f} GB ({disk_usage_pct:.1f}%)", color='y')
|
|
408
|
+
|
|
409
|
+
# Active Plugins
|
|
410
|
+
active_plugins = node_hb.get(HEARTBEAT_DATA.ACTIVE_PLUGINS, [])
|
|
411
|
+
log_with_color(f"\n=== Active Plugins ===", color='b')
|
|
412
|
+
log_with_color(f"Number of Active Plugins: {len(active_plugins)}", color='y')
|
|
413
|
+
|
|
414
|
+
if active_plugins:
|
|
415
|
+
plugins_to_display = 99999 if wide else 5
|
|
416
|
+
for i, plugin in enumerate(active_plugins[:plugins_to_display]): # Show first 5 plugins
|
|
417
|
+
stream_id = plugin.get(HEARTBEAT_DATA.ACTIVE_PLUGINS_INFO.STREAM_ID, 'Unknown')
|
|
418
|
+
signature = plugin.get(HEARTBEAT_DATA.ACTIVE_PLUGINS_INFO.SIGNATURE, 'Unknown')
|
|
419
|
+
instance_id = plugin.get(HEARTBEAT_DATA.ACTIVE_PLUGINS_INFO.INSTANCE_ID, 'Unknown')
|
|
420
|
+
total_payload = plugin.get(HEARTBEAT_DATA.ACTIVE_PLUGINS_INFO.TOTAL_PAYLOAD_COUNT, 0)
|
|
421
|
+
log_with_color(f" {i+1}. {stream_id} {signature} ({instance_id}) - {total_payload} payloads", color='w')
|
|
422
|
+
|
|
423
|
+
if len(active_plugins) > plugins_to_display:
|
|
424
|
+
log_with_color(f" ... and {len(active_plugins) - plugins_to_display} more plugins", color='w')
|
|
425
|
+
|
|
426
|
+
log_with_color(f"\n", color='w') # Add final newline for spacing
|
|
427
|
+
|
|
428
|
+
return
|