ratio1 3.4.92__py3-none-any.whl → 3.4.94__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.
ratio1/_ver.py CHANGED
@@ -1,4 +1,4 @@
1
- __VER__ = "3.4.92"
1
+ __VER__ = "3.4.94"
2
2
 
3
3
  if __name__ == "__main__":
4
4
  with open("pyproject.toml", "rt") as fd:
@@ -3130,6 +3130,186 @@ class GenericSession(BaseDecentrAIObject):
3130
3130
  **kwargs
3131
3131
  )
3132
3132
 
3133
+ def create_worker_web_app(
3134
+ self,
3135
+ *,
3136
+ node,
3137
+ name="Ratio1 Worker Web App",
3138
+ tunnel_engine_enabled=True,
3139
+ tunnel_engine="cloudflare",
3140
+ cloudflare_token=None,
3141
+ ngrok_edge_label=None,
3142
+ extra_debug=False,
3143
+ summary="Ratio1 Worker WebApp created via SDK",
3144
+ description=None,
3145
+ # Worker app specific parameters
3146
+ vcs_data=None,
3147
+ image="node:22",
3148
+ build_and_run_commands=None,
3149
+ cr_data=None,
3150
+ env=None,
3151
+ dynamic_env=None,
3152
+ port=None,
3153
+ endpoint_url=None,
3154
+ endpoint_poll_interval=30,
3155
+ container_resources=None,
3156
+ volumes=None,
3157
+ file_volumes=None,
3158
+ restart_policy="always",
3159
+ image_pull_policy="always",
3160
+ image_poll_interval=300,
3161
+ vcs_poll_interval=60,
3162
+ **kwargs
3163
+ ):
3164
+ """
3165
+ Create a new worker web app on a node.
3166
+
3167
+ Parameters
3168
+ ----------
3169
+
3170
+ node : str
3171
+ Address or Name of the ratio1 Edge Protocol edge node that will handle this web app.
3172
+
3173
+ name : str
3174
+ Name of the worker web app.
3175
+
3176
+ tunnel_engine : str, optional
3177
+ The tunnel engine to use for exposing the web app. Defaults to "cloudflare".
3178
+ It can also be "ngrok" for ngrok tunnel.
3179
+
3180
+ tunnel_engine_enabled : bool, optional
3181
+ If True, will use the specified tunnel engine to expose the web app. Defaults to True.
3182
+
3183
+ ngrok_edge_label : str, optional
3184
+ The label of the edge node that will be used to expose the HTTP server. Defaults to None.
3185
+
3186
+ cloudflare_token : str, optional
3187
+ The Cloudflare token to use for exposing the web app. Defaults to None.
3188
+
3189
+ vcs_data : dict, required
3190
+ Version control system data containing:
3191
+ - PROVIDER: "github" (currently only GitHub is supported)
3192
+ - USERNAME: GitHub username for cloning (if private repo)
3193
+ - TOKEN: GitHub personal access token for cloning (if private repo)
3194
+ - REPO_OWNER: GitHub repository owner (user or org)
3195
+ - REPO_NAME: GitHub repository name
3196
+ - BRANCH: branch to monitor for updates (defaults to "main")
3197
+ - POLL_INTERVAL: seconds between Git commit checks (defaults to 60)
3198
+
3199
+ image : str, optional
3200
+ Docker image to use for the container. Defaults to "node:22".
3201
+
3202
+ build_and_run_commands : list, optional
3203
+ List of commands to run in the container for building and running the app.
3204
+ Defaults to ["npm install", "npm run build", "npm start"].
3205
+
3206
+ cr_data : dict, optional
3207
+ Container registry data containing:
3208
+ - SERVER: container registry URL (defaults to 'docker.io')
3209
+ - USERNAME: registry username
3210
+ - PASSWORD: registry password or token
3211
+
3212
+ env : dict, optional
3213
+ Environment variables for the container.
3214
+
3215
+ dynamic_env : dict, optional
3216
+ Dynamic environment variables for the container.
3217
+
3218
+ port : int, optional
3219
+ Internal container port if it's a web app.
3220
+
3221
+ endpoint_url : str, optional
3222
+ Endpoint to poll for health checks, e.g., "/health" or "/edgenode".
3223
+
3224
+ endpoint_poll_interval : int, optional
3225
+ Seconds between endpoint health checks. Defaults to 30.
3226
+
3227
+ container_resources : dict, optional
3228
+ Container resource limits containing:
3229
+ - cpu: CPU limit (e.g., "0.5" for half a CPU, "1.0" for one CPU core)
3230
+ - gpu: GPU limit (defaults to 0)
3231
+ - memory: Memory limit (e.g., "512m" for 512MB)
3232
+ - ports: List of container ports or dict of host_port: container_port mappings
3233
+
3234
+ volumes : dict, optional
3235
+ Dictionary mapping host paths to container paths for directory volumes.
3236
+ Example: {"/host/data": "/container/data"}
3237
+
3238
+ file_volumes : dict, optional
3239
+ Dictionary mapping logical names to file configurations for creating and mounting
3240
+ files with dynamic content. Each entry should contain:
3241
+ - content: String content to write to the file
3242
+ - mounting_point: Full path where file will be mounted in container
3243
+ Example: {"config": {"content": "port=8080", "mounting_point": "/app/config.txt"}}
3244
+
3245
+ restart_policy : str, optional
3246
+ Container restart policy. Defaults to "always".
3247
+
3248
+ image_pull_policy : str, optional
3249
+ Image pull policy. Defaults to "always".
3250
+
3251
+ image_poll_interval : int, optional
3252
+ Seconds between Docker image checks. Defaults to 300.
3253
+
3254
+ vcs_poll_interval : int, optional
3255
+ Seconds between Git commit checks. Defaults to 60.
3256
+
3257
+ """
3258
+ if vcs_data is None:
3259
+ raise ValueError("vcs_data is required for worker web apps. Please provide repository information.")
3260
+
3261
+ # Set default values
3262
+ if build_and_run_commands is None:
3263
+ build_and_run_commands = ["npm install", "npm run build", "npm start"]
3264
+
3265
+ if cr_data is None:
3266
+ cr_data = {"SERVER": "docker.io", "USERNAME": None, "PASSWORD": None}
3267
+
3268
+ if container_resources is None:
3269
+ container_resources = {"cpu": 1, "gpu": 0, "memory": "512m", "ports": []}
3270
+
3271
+ # Prepare worker app specific configuration
3272
+ worker_config = {
3273
+ "VCS_DATA": {**vcs_data, "POLL_INTERVAL": vcs_poll_interval},
3274
+ "IMAGE": image,
3275
+ "BUILD_AND_RUN_COMMANDS": build_and_run_commands,
3276
+ "CR_DATA": cr_data,
3277
+ "ENV": env or {},
3278
+ "DYNAMIC_ENV": dynamic_env or {},
3279
+ "PORT": port,
3280
+ "ENDPOINT_URL": endpoint_url,
3281
+ "ENDPOINT_POLL_INTERVAL": endpoint_poll_interval,
3282
+ "CONTAINER_RESOURCES": container_resources,
3283
+ "VOLUMES": volumes or {},
3284
+ "FILE_VOLUMES": file_volumes or {},
3285
+ "RESTART_POLICY": restart_policy,
3286
+ "IMAGE_PULL_POLICY": image_pull_policy,
3287
+ "IMAGE_POLL_INTERVAL": image_poll_interval,
3288
+ "CAR_VERBOSE": 100,
3289
+ }
3290
+
3291
+ kwargs = self.maybe_clean_kwargs(
3292
+ _kwargs=kwargs,
3293
+ caller_method_name="create_worker_web_app",
3294
+ solver_method_name="create_web_app",
3295
+ parameters_to_remove=["signature"]
3296
+ )
3297
+
3298
+ return self.create_web_app(
3299
+ node=node,
3300
+ name=name,
3301
+ signature=PLUGIN_SIGNATURES.WORKER_APP_RUNNER,
3302
+ tunnel_engine=tunnel_engine,
3303
+ tunnel_engine_enabled=tunnel_engine_enabled,
3304
+ cloudflare_token=cloudflare_token,
3305
+ ngrok_edge_label=ngrok_edge_label,
3306
+ extra_debug=extra_debug,
3307
+ summary=summary,
3308
+ description=description,
3309
+ **worker_config,
3310
+ **kwargs
3311
+ )
3312
+
3133
3313
  def deeploy_launch_container_app(
3134
3314
  self,
3135
3315
  docker_image: str,
ratio1/bc/evm.py CHANGED
@@ -1334,29 +1334,40 @@ class _EVMMixin:
1334
1334
 
1335
1335
  # Call the contract function to get details.
1336
1336
  result_tuple = contract.functions.getJobDetails(job_id).call()
1337
-
1338
- # Unpack the tuple into a dictionary for readability.
1339
- details = {
1340
- "network": network,
1341
- "jobId": result_tuple[0],
1342
- "projectHash": "0x" + result_tuple[1].hex(),
1343
- "requestTimestamp": result_tuple[2],
1344
- "startTimestamp": result_tuple[3],
1345
- "lastNodesChangeTimestamp": result_tuple[4],
1346
- "jobType": result_tuple[5],
1347
- "pricePerEpoch": result_tuple[6],
1348
- "lastExecutionEpoch": result_tuple[7],
1349
- "numberOfNodesRequested": result_tuple[8],
1350
- "balance": result_tuple[9],
1351
- "lastAllocatedEpoch": result_tuple[10],
1352
- "activeNodes": result_tuple[11],
1353
- "escrowAddress": result_tuple[12],
1354
- "escrowOwner": result_tuple[13],
1355
- }
1337
+ details = self._format_job_details(result_tuple, network)
1356
1338
  self.P(f"Job Details:\n{json.dumps(details, indent=2)}", verbosity=2)
1357
-
1358
1339
  return details
1359
1340
 
1341
+ def web3_get_all_active_jobs(
1342
+ self,
1343
+ network: str = None
1344
+ ):
1345
+ """
1346
+ Retrieve all active jobs tracked by the PoAI manager.
1347
+
1348
+ Parameters
1349
+ ----------
1350
+ network : str, optional
1351
+ The network to use. Defaults to the current engine network.
1352
+
1353
+ Returns
1354
+ -------
1355
+ list[dict]
1356
+ A list with the job details for every active job.
1357
+ """
1358
+ w3vars = self._get_web3_vars(network)
1359
+ network = w3vars.network
1360
+ contract = w3vars.w3.eth.contract(
1361
+ address=w3vars.poai_manager_address,
1362
+ abi=EVM_ABI_DATA.POAI_MANAGER_ABI
1363
+ )
1364
+
1365
+ self.P(f"`getAllActiveJobs` on {network} via {w3vars.rpc_url}", verbosity=2)
1366
+ raw_jobs = contract.functions.getAllActiveJobs().call()
1367
+ jobs = [self._format_job_details(job, network) for job in raw_jobs]
1368
+ self.P(f"Active jobs found: {len(jobs)}", verbosity=2)
1369
+ return jobs
1370
+
1360
1371
  def web3_submit_node_update(
1361
1372
  self,
1362
1373
  job_id: int,
@@ -1630,6 +1641,28 @@ class _EVMMixin:
1630
1641
  self.P(f"Last epoch allocated: {result}", verbosity=2)
1631
1642
 
1632
1643
  return result
1644
+
1645
+ def _format_job_details(self, raw_job_details, network: str):
1646
+ """
1647
+ Normalize the job details tuple returned by the PoAI Manager contract.
1648
+ """
1649
+ return {
1650
+ "network": network,
1651
+ "jobId": raw_job_details[0],
1652
+ "projectHash": "0x" + raw_job_details[1].hex(),
1653
+ "requestTimestamp": raw_job_details[2],
1654
+ "startTimestamp": raw_job_details[3],
1655
+ "lastNodesChangeTimestamp": raw_job_details[4],
1656
+ "jobType": raw_job_details[5],
1657
+ "pricePerEpoch": raw_job_details[6],
1658
+ "lastExecutionEpoch": raw_job_details[7],
1659
+ "numberOfNodesRequested": raw_job_details[8],
1660
+ "balance": raw_job_details[9],
1661
+ "lastAllocatedEpoch": raw_job_details[10],
1662
+ "activeNodes": raw_job_details[11],
1663
+ "escrowAddress": raw_job_details[12],
1664
+ "escrowOwner": raw_job_details[13],
1665
+ }
1633
1666
 
1634
1667
  def get_deeploy_url(self):
1635
1668
  """
ratio1/const/apps.py CHANGED
@@ -14,6 +14,7 @@ class PLUGIN_SIGNATURES:
14
14
  TELEGRAM_CONVERSATIONAL_BOT_01 = 'TELEGRAM_CONVERSATIONAL_BOT_01'
15
15
  NET_CONFIG_MONITOR = 'NET_CONFIG_MONITOR'
16
16
  CONTAINER_APP_RUNNER = 'CONTAINER_APP_RUNNER'
17
+ WORKER_APP_RUNNER = 'WORKER_APP_RUNNER'
17
18
  # INSERT_NEW_PLUGIN_HERE
18
19
 
19
20
 
ratio1/const/evm_net.py CHANGED
@@ -430,6 +430,91 @@ _POAI_MANAGER_ABI = [
430
430
  ],
431
431
  "stateMutability": "view",
432
432
  "type": "function"
433
+ },
434
+ {
435
+ "inputs": [],
436
+ "name": "getAllActiveJobs",
437
+ "outputs": [
438
+ {
439
+ "components": [
440
+ {
441
+ "internalType": "uint256",
442
+ "name": "id",
443
+ "type": "uint256"
444
+ },
445
+ {
446
+ "internalType": "bytes32",
447
+ "name": "projectHash",
448
+ "type": "bytes32"
449
+ },
450
+ {
451
+ "internalType": "uint256",
452
+ "name": "requestTimestamp",
453
+ "type": "uint256"
454
+ },
455
+ {
456
+ "internalType": "uint256",
457
+ "name": "startTimestamp",
458
+ "type": "uint256"
459
+ },
460
+ {
461
+ "internalType": "uint256",
462
+ "name": "lastNodesChangeTimestamp",
463
+ "type": "uint256"
464
+ },
465
+ {
466
+ "internalType": "uint256",
467
+ "name": "jobType",
468
+ "type": "uint256"
469
+ },
470
+ {
471
+ "internalType": "uint256",
472
+ "name": "pricePerEpoch",
473
+ "type": "uint256"
474
+ },
475
+ {
476
+ "internalType": "uint256",
477
+ "name": "lastExecutionEpoch",
478
+ "type": "uint256"
479
+ },
480
+ {
481
+ "internalType": "uint256",
482
+ "name": "numberOfNodesRequested",
483
+ "type": "uint256"
484
+ },
485
+ {
486
+ "internalType": "int256",
487
+ "name": "balance",
488
+ "type": "int256"
489
+ },
490
+ {
491
+ "internalType": "uint256",
492
+ "name": "lastAllocatedEpoch",
493
+ "type": "uint256"
494
+ },
495
+ {
496
+ "internalType": "address[]",
497
+ "name": "activeNodes",
498
+ "type": "address[]"
499
+ },
500
+ {
501
+ "internalType": "address",
502
+ "name": "escrowAddress",
503
+ "type": "address"
504
+ },
505
+ {
506
+ "internalType": "address",
507
+ "name": "escrowOwner",
508
+ "type": "address"
509
+ }
510
+ ],
511
+ "internalType": "struct JobWithAllDetails[]",
512
+ "name": "",
513
+ "type": "tuple[]"
514
+ }
515
+ ],
516
+ "stateMutability": "view",
517
+ "type": "function"
433
518
  }
434
519
  ]
435
520
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ratio1
3
- Version: 3.4.92
3
+ Version: 3.4.94
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
@@ -1,10 +1,10 @@
1
1
  ratio1/__init__.py,sha256=YimqgDbjLuywsf8zCWE0EaUXH4MBUrqLxt0TDV558hQ,632
2
- ratio1/_ver.py,sha256=jr82AXwgHwGADT5iLJq0XMsii56EJRQuow9NbIZHlb8,331
2
+ ratio1/_ver.py,sha256=SmMEkehFX9-G0oMXyGGpAX6VXjy25KstgcmRgX66Iy8,331
3
3
  ratio1/base_decentra_object.py,sha256=iXvAAf6wPnGWzeeiRfwLojVoan-m1e_VsyPzjUQuENo,4492
4
4
  ratio1/plugins_manager_mixin.py,sha256=X1JdGLDz0gN1rPnTN_5mJXR8JmqoBFQISJXmPR9yvCo,11106
5
5
  ratio1/base/__init__.py,sha256=hACh83_cIv7-PwYMM3bQm2IBmNqiHw-3PAfDfAEKz9A,259
6
6
  ratio1/base/distributed_custom_code_presets.py,sha256=cvz5R88P6Z5V61Ce1vHVVh8bOkgXd6gve_vdESDNAsg,2544
7
- ratio1/base/generic_session.py,sha256=kTO5VIGQ4ZgGlN6JtZ82TGT9u-l-wX3s6JM__VtCwbU,188158
7
+ ratio1/base/generic_session.py,sha256=Gbygyd_5rX_JoD05pdbp1Ji_77BLSiAZ-vxXeOJ2Jt0,194670
8
8
  ratio1/base/instance.py,sha256=oQvwzzRvir7851wyhDx_BwN6y_VgsNWwYo53vN33QI4,21914
9
9
  ratio1/base/pipeline.py,sha256=szoHrk1qBdY6NKPUk3tUTsJx3XzYp5C2GTOlzRiQi48,62489
10
10
  ratio1/base/plugin_template.py,sha256=Gs438cSkhvxPujE4CRH_32pcuZaVwI9kia8E4VDRpSU,138794
@@ -17,7 +17,7 @@ ratio1/bc/__init__.py,sha256=BI5pcqHdhwnMdbWTYDLW1cVP_844VtLra-lz7xprgsk,171
17
17
  ratio1/bc/base.py,sha256=g7tARNgi_0N1p9HpvqRDWDVYxuqU7W6S0q3ARC6oxKk,45870
18
18
  ratio1/bc/chain.py,sha256=HCTQGnmuKqTvUo95OKdg8rL2jhKfSMwrich2e_7Nyms,2336
19
19
  ratio1/bc/ec.py,sha256=FwlkWmJvQ9aHuf_BZX1CWSUAxw6OZ9jBparLIWcs_e4,18933
20
- ratio1/bc/evm.py,sha256=E_W6mjmk1-rBrRaCaYE5mM0LItHwkCTpjAEWR9JgmAM,52511
20
+ ratio1/bc/evm.py,sha256=OP68eZ3Zr62gljVtyLmvDnJZvdUCdWUc7FS-xNzm_PU,53631
21
21
  ratio1/certs/51.15.142.167.crt,sha256=rLxkwDIQm-u6Kw570NmdSFgjSChcdSJvXPxr4Mj-EU8,1167
22
22
  ratio1/certs/72.60.187.24.crt,sha256=R_7KRS9zLONRxk6FpB72674Z45rKG5prKOd5MZGKk1E,1164
23
23
  ratio1/certs/72.60.81.67.crt,sha256=1Lw19spbXnswqKoQVih78xuZe5NxP5z9HS6bh3-0U_g,1159
@@ -40,11 +40,11 @@ ratio1/comm/base_comm_wrapper.py,sha256=oJwMtQYGumxZz1lKvDEgFwLhC1LzZFsGTP9hxBH7
40
40
  ratio1/comm/mqtt_wrapper.py,sha256=tOlKD8NUOUdMZ-FK7XZonxQydKmD0sHrugqb8YsRBaI,14397
41
41
  ratio1/const/README.md,sha256=6OHesr-f5NBuuJGryEoi_TCu2XdlhfQYlDKx_IJoXeg,177
42
42
  ratio1/const/__init__.py,sha256=mcSaDgSYV2xbOS8Api72dDPO6kPBRjnYjBPAh9cAgaU,558
43
- ratio1/const/apps.py,sha256=0NiuoAPak0HjEULF3fs3xaUH8IRSZ0i4fZw7T2fEd_g,785
43
+ ratio1/const/apps.py,sha256=MD4SRTNId663D3SX78_GJa40BI_H1mdcNbL2gy_Hio0,827
44
44
  ratio1/const/base.py,sha256=QIeRH6X-u8DbezQCGipI3isL1LGComBQC5hLedO1jrQ,6042
45
45
  ratio1/const/comms.py,sha256=qEYX4ciYg8SYWSDZZTUYxzpR1--2a7UusrWzAq0hxo8,2259
46
46
  ratio1/const/environment.py,sha256=632L5GrcNqF3-JhvrC6kXzXwLMcihRgMlOkLurnOwGY,1031
47
- ratio1/const/evm_net.py,sha256=v53s5Cm_0iZqHdBjkR-3FLYKElB2_PKikHltqZz_H3s,17013
47
+ ratio1/const/evm_net.py,sha256=55R7nr4PgAZ8ae22SgyP7wExP91G_XbTVJ8U3-DPB3s,19141
48
48
  ratio1/const/formatter.py,sha256=AW3bWlqf39uaqV4BBUuW95qKYfF2OkkU4f9hy3kSVhM,200
49
49
  ratio1/const/heartbeat.py,sha256=Z_n87yI-L4vlBmlHZhkruysEJV5JVbXLQlGI26R42C4,3197
50
50
  ratio1/const/misc.py,sha256=VDCwwpf5bl9ltx9rzT2WPVP8B3mZFRufU1tSS5MO240,413
@@ -105,8 +105,8 @@ ratio1/utils/comm_utils.py,sha256=4cS9llRr_pK_3rNgDcRMCQwYPO0kcNU7AdWy_LtMyCY,10
105
105
  ratio1/utils/config.py,sha256=Elfkl7W4aDMvB5WZLiYlPXrecBncgTxb4hcKhQedMzI,10111
106
106
  ratio1/utils/dotenv.py,sha256=_AgSo35n7EnQv5yDyu7C7i0kHragLJoCGydHjvOkrYY,2008
107
107
  ratio1/utils/oracle_sync/oracle_tester.py,sha256=aJOPcZhtbw1XPqsFG4qYpfv2Taj5-qRXbwJzrPyeXDE,27465
108
- ratio1-3.4.92.dist-info/METADATA,sha256=LBq9it3rOtn9ztF0CeGxauX8HCght4h4k_2oR0t7NhI,12255
109
- ratio1-3.4.92.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
110
- ratio1-3.4.92.dist-info/entry_points.txt,sha256=DR_olREzU1egwmgek3s4GfQslBi-KR7lXsd4ap0TFxE,46
111
- ratio1-3.4.92.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
112
- ratio1-3.4.92.dist-info/RECORD,,
108
+ ratio1-3.4.94.dist-info/METADATA,sha256=R1XSSnC0u0dcGfdr097tXmG7vOJuSolXVcwliaCPMHQ,12255
109
+ ratio1-3.4.94.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
110
+ ratio1-3.4.94.dist-info/entry_points.txt,sha256=DR_olREzU1egwmgek3s4GfQslBi-KR7lXsd4ap0TFxE,46
111
+ ratio1-3.4.94.dist-info/licenses/LICENSE,sha256=cvOsJVslde4oIaTCadabXnPqZmzcBO2f2zwXZRmJEbE,11311
112
+ ratio1-3.4.94.dist-info/RECORD,,