runnable 0.28.8__py3-none-any.whl → 0.30.0__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.
runnable/nodes.py CHANGED
@@ -37,6 +37,7 @@ class BaseNode(ABC, BaseModel):
37
37
  internal_name: str = Field(exclude=True)
38
38
  internal_branch_name: str = Field(default="", exclude=True)
39
39
  is_composite: bool = Field(default=False, exclude=True)
40
+ is_distributed: bool = Field(default=False, exclude=True)
40
41
 
41
42
  @property
42
43
  def _context(self):
@@ -280,7 +281,6 @@ class BaseNode(ABC, BaseModel):
280
281
  mock=False,
281
282
  map_variable: TypeMapVariable = None,
282
283
  attempt_number: int = 1,
283
- **kwargs,
284
284
  ) -> StepLog:
285
285
  """
286
286
  The actual function that does the execution of the command in the config.
@@ -299,7 +299,7 @@ class BaseNode(ABC, BaseModel):
299
299
  """
300
300
 
301
301
  @abstractmethod
302
- def execute_as_graph(self, map_variable: TypeMapVariable = None, **kwargs):
302
+ def execute_as_graph(self, map_variable: TypeMapVariable = None):
303
303
  """
304
304
  This function would be called to set up the execution of the individual
305
305
  branches of a composite node.
@@ -314,7 +314,7 @@ class BaseNode(ABC, BaseModel):
314
314
  """
315
315
 
316
316
  @abstractmethod
317
- def fan_out(self, map_variable: TypeMapVariable = None, **kwargs):
317
+ def fan_out(self, map_variable: TypeMapVariable = None):
318
318
  """
319
319
  This function would be called to set up the execution of the individual
320
320
  branches of a composite node.
@@ -330,7 +330,7 @@ class BaseNode(ABC, BaseModel):
330
330
  """
331
331
 
332
332
  @abstractmethod
333
- def fan_in(self, map_variable: TypeMapVariable = None, **kwargs):
333
+ def fan_in(self, map_variable: TypeMapVariable = None):
334
334
  """
335
335
  This function would be called to tear down the execution of the individual
336
336
  branches of a composite node.
@@ -439,33 +439,25 @@ class ExecutableNode(TraversalNode):
439
439
  "This is an executable node and does not have branches"
440
440
  )
441
441
 
442
- def execute_as_graph(self, map_variable: TypeMapVariable = None, **kwargs):
442
+ def execute_as_graph(self, map_variable: TypeMapVariable = None):
443
443
  raise exceptions.NodeMethodCallError(
444
444
  "This is an executable node and does not have a graph"
445
445
  )
446
446
 
447
- def fan_in(self, map_variable: TypeMapVariable = None, **kwargs):
447
+ def fan_in(self, map_variable: TypeMapVariable = None):
448
448
  raise exceptions.NodeMethodCallError(
449
449
  "This is an executable node and does not have a fan in"
450
450
  )
451
451
 
452
- def fan_out(self, map_variable: TypeMapVariable = None, **kwargs):
452
+ def fan_out(self, map_variable: TypeMapVariable = None):
453
453
  raise exceptions.NodeMethodCallError(
454
454
  "This is an executable node and does not have a fan out"
455
455
  )
456
456
 
457
- def prepare_for_job_execution(self):
458
- raise exceptions.NodeMethodCallError(
459
- "This is an executable node and does not have a prepare_for_job_execution"
460
- )
461
-
462
- def tear_down_after_job_execution(self):
463
- raise exceptions.NodeMethodCallError(
464
- "This is an executable node and does not have a tear_down_after_job_execution",
465
- )
466
-
467
457
 
468
458
  class CompositeNode(TraversalNode):
459
+ is_composite: bool = True
460
+
469
461
  def _get_catalog_settings(self) -> Dict[str, Any]:
470
462
  """
471
463
  If the node defines a catalog settings, return it or None
@@ -485,20 +477,44 @@ class CompositeNode(TraversalNode):
485
477
  mock=False,
486
478
  map_variable: TypeMapVariable = None,
487
479
  attempt_number: int = 1,
488
- **kwargs,
489
480
  ) -> StepLog:
490
481
  raise exceptions.NodeMethodCallError(
491
482
  "This is a composite node and does not have an execute function"
492
483
  )
493
484
 
494
- def prepare_for_job_execution(self):
485
+
486
+ class DistributedNode(TraversalNode):
487
+ """
488
+ Use this node for distributed execution of tasks.
489
+ eg: torch distributed, horovod, etc.
490
+ """
491
+
492
+ is_distributed: bool = True
493
+ catalog: Optional[CatalogStructure] = Field(default=None)
494
+ max_attempts: int = Field(default=1, ge=1)
495
+
496
+ def _get_catalog_settings(self) -> Dict[str, Any]:
497
+ """
498
+ If the node defines a catalog settings, return it or None
499
+
500
+ Returns:
501
+ dict: catalog settings defined as per the node or None
502
+ """
503
+ if self.catalog:
504
+ return self.catalog.model_dump()
505
+ return {}
506
+
507
+ def _get_max_attempts(self) -> int:
508
+ return self.max_attempts
509
+
510
+ def _get_branch_by_name(self, branch_name: str):
495
511
  raise exceptions.NodeMethodCallError(
496
- "This is an executable node and does not have a prepare_for_job_execution"
512
+ "This is an distributed node and does not have branches"
497
513
  )
498
514
 
499
- def tear_down_after_job_execution(self):
515
+ def execute_as_graph(self, map_variable: TypeMapVariable = None):
500
516
  raise exceptions.NodeMethodCallError(
501
- "This is an executable node and does not have a tear_down_after_job_execution"
517
+ "This is an executable node and does not have a graph"
502
518
  )
503
519
 
504
520
 
@@ -524,13 +540,16 @@ class TerminalNode(BaseNode):
524
540
  def _get_max_attempts(self) -> int:
525
541
  return 1
526
542
 
527
- def execute_as_graph(self, map_variable: TypeMapVariable = None, **kwargs):
543
+ def execute_as_graph(self, map_variable: TypeMapVariable = None):
528
544
  raise exceptions.TerminalNodeError()
529
545
 
530
- def fan_in(self, map_variable: TypeMapVariable = None, **kwargs):
546
+ def fan_in(self, map_variable: TypeMapVariable = None):
531
547
  raise exceptions.TerminalNodeError()
532
548
 
533
- def fan_out(self, map_variable: TypeMapVariable = None, **kwargs):
549
+ def fan_out(
550
+ self,
551
+ map_variable: TypeMapVariable = None,
552
+ ):
534
553
  raise exceptions.TerminalNodeError()
535
554
 
536
555
  @classmethod
runnable/sdk.py CHANGED
@@ -5,7 +5,7 @@ import os
5
5
  import re
6
6
  from abc import ABC, abstractmethod
7
7
  from pathlib import Path
8
- from typing import Any, Callable, Dict, List, Optional, Union
8
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
9
9
 
10
10
  from pydantic import (
11
11
  BaseModel,
@@ -34,17 +34,20 @@ from extensions.nodes.nodes import (
34
34
  SuccessNode,
35
35
  TaskNode,
36
36
  )
37
+ from extensions.nodes.torch_config import TorchConfig
37
38
  from runnable import console, defaults, entrypoints, exceptions, graph, utils
38
39
  from runnable.executor import BaseJobExecutor, BasePipelineExecutor
39
40
  from runnable.nodes import TraversalNode
40
41
  from runnable.tasks import BaseTaskType as RunnableTask
41
42
  from runnable.tasks import TaskReturns
42
43
 
43
- # TODO: This might have to be an extension
44
-
45
44
  logger = logging.getLogger(defaults.LOGGER_NAME)
46
45
 
47
- StepType = Union["Stub", "PythonTask", "NotebookTask", "ShellTask", "Parallel", "Map"]
46
+ StepType = Union[
47
+ "Stub", "PythonTask", "NotebookTask", "ShellTask", "Parallel", "Map", "Torch"
48
+ ]
49
+ if TYPE_CHECKING:
50
+ from extensions.nodes.torch import TorchNode
48
51
 
49
52
 
50
53
  def pickled(name: str) -> TaskReturns:
@@ -322,7 +325,7 @@ class NotebookTask(BaseTask):
322
325
  catalog Optional[Catalog]: The files sync data from/to, refer to Catalog.
323
326
 
324
327
  secrets List[str]: List of secrets to pass to the task. They are exposed as environment variables
325
- and removed after execution.
328
+ and removed after execution.
326
329
 
327
330
  overrides (Dict[str, Any]): Any overrides to the command.
328
331
  Individual tasks can override the global configuration config by referring to the
@@ -388,7 +391,7 @@ class ShellTask(BaseTask):
388
391
  catalog Optional[Catalog]: The files sync data from/to, refer to Catalog.
389
392
 
390
393
  secrets List[str]: List of secrets to pass to the task. They are exposed as environment variables
391
- and removed after execution.
394
+ and removed after execution.
392
395
 
393
396
  overrides (Dict[str, Any]): Any overrides to the command.
394
397
  Individual tasks can override the global configuration config by referring to the
@@ -456,6 +459,43 @@ class Stub(BaseTraversal):
456
459
  return StubNode.parse_from_config(self.model_dump(exclude_none=True))
457
460
 
458
461
 
462
+ class Torch(BaseTraversal, TorchConfig):
463
+ function: Callable = Field(exclude=True)
464
+ catalog: Optional[Catalog] = Field(default=None, alias="catalog")
465
+ overrides: Dict[str, Any] = Field(default_factory=dict, alias="overrides")
466
+ returns: List[Union[str, TaskReturns]] = Field(
467
+ default_factory=list, alias="returns"
468
+ )
469
+ secrets: List[str] = Field(default_factory=list)
470
+
471
+ @computed_field
472
+ def command_type(self) -> str:
473
+ return "python"
474
+
475
+ @computed_field
476
+ def command(self) -> str:
477
+ module = self.function.__module__
478
+ name = self.function.__name__
479
+
480
+ return f"{module}.{name}"
481
+
482
+ def create_node(self) -> TorchNode:
483
+ if not self.next_node:
484
+ if not (self.terminate_with_failure or self.terminate_with_success):
485
+ raise AssertionError(
486
+ "A node not being terminated must have a user defined next node"
487
+ )
488
+
489
+ if self.on_failure:
490
+ self.on_failure = self.on_failure.steps[0].name # type: ignore
491
+
492
+ from extensions.nodes.torch import TorchNode
493
+
494
+ return TorchNode.parse_from_config(
495
+ self.model_dump(exclude_none=True, by_alias=True)
496
+ )
497
+
498
+
459
499
  class Parallel(BaseTraversal):
460
500
  """
461
501
  A node that executes multiple branches in parallel.
runnable/secrets.py CHANGED
@@ -29,7 +29,7 @@ class BaseSecrets(ABC, BaseModel):
29
29
  return context.run_context
30
30
 
31
31
  @abstractmethod
32
- def get(self, name: str, **kwargs) -> str:
32
+ def get(self, name: str) -> str:
33
33
  """
34
34
  Return the secret by name.
35
35
 
@@ -53,7 +53,7 @@ class DoNothingSecretManager(BaseSecrets):
53
53
 
54
54
  service_name: str = "do-nothing"
55
55
 
56
- def get(self, name: str, **kwargs) -> str:
56
+ def get(self, name: str) -> str:
57
57
  """
58
58
  If a name is provided, return None else return empty dict.
59
59
 
@@ -76,7 +76,7 @@ class EnvSecretsManager(BaseSecrets):
76
76
 
77
77
  service_name: str = "env-secrets"
78
78
 
79
- def get(self, name: str, **kwargs) -> str:
79
+ def get(self, name: str) -> str:
80
80
  """
81
81
  If a name is provided, return None else return empty dict.
82
82
 
runnable/tasks.py CHANGED
@@ -93,7 +93,6 @@ class BaseTaskType(BaseModel):
93
93
  def execute_command(
94
94
  self,
95
95
  map_variable: TypeMapVariable = None,
96
- **kwargs,
97
96
  ) -> StepAttempt:
98
97
  """The function to execute the command.
99
98
 
@@ -271,7 +270,6 @@ class PythonTaskType(BaseTaskType): # pylint: disable=too-few-public-methods
271
270
  def execute_command(
272
271
  self,
273
272
  map_variable: TypeMapVariable = None,
274
- **kwargs,
275
273
  ) -> StepAttempt:
276
274
  """Execute the notebook as defined by the command."""
277
275
  attempt_log = StepAttempt(status=defaults.FAIL, start_time=str(datetime.now()))
@@ -441,7 +439,6 @@ class NotebookTaskType(BaseTaskType):
441
439
  def execute_command(
442
440
  self,
443
441
  map_variable: TypeMapVariable = None,
444
- **kwargs,
445
442
  ) -> StepAttempt:
446
443
  """Execute the python notebook as defined by the command.
447
444
 
@@ -620,7 +617,6 @@ class ShellTaskType(BaseTaskType):
620
617
  def execute_command(
621
618
  self,
622
619
  map_variable: TypeMapVariable = None,
623
- **kwargs,
624
620
  ) -> StepAttempt:
625
621
  # Using shell=True as we want to have chained commands to be executed in the same shell.
626
622
  """Execute the shell command as defined by the command.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: runnable
3
- Version: 0.28.8
3
+ Version: 0.30.0
4
4
  Summary: Add your description here
5
5
  Author-email: "Vammi, Vijay" <vijay.vammi@astrazeneca.com>
6
6
  License-File: LICENSE
@@ -26,6 +26,8 @@ Provides-Extra: notebook
26
26
  Requires-Dist: ploomber-engine>=0.0.33; extra == 'notebook'
27
27
  Provides-Extra: s3
28
28
  Requires-Dist: cloudpathlib[s3]; extra == 's3'
29
+ Provides-Extra: torch
30
+ Requires-Dist: torch>=2.6.0; extra == 'torch'
29
31
  Description-Content-Type: text/markdown
30
32
 
31
33
 
@@ -8,37 +8,39 @@ extensions/catalog/pyproject.toml,sha256=lLNxY6v04c8I5QK_zKw_E6sJTArSJRA_V-79kta
8
8
  extensions/catalog/s3.py,sha256=Sw5t8_kVRprn3uGGJCiHn7M9zw1CLaCOFj6YErtfG0o,287
9
9
  extensions/job_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  extensions/job_executor/__init__.py,sha256=E2R6GV5cZTlZdqA5SVJ6ajZFh4oruM0k8AKHkpOZ3W8,5772
11
- extensions/job_executor/k8s.py,sha256=Mlmuqm1D70gfj471KKZrQF1PeDSCpOiW1bd4vD0pQ-w,16243
11
+ extensions/job_executor/k8s.py,sha256=erzw4UOsOf2JSOiQio5stgW_rMryAsIQSBd8wiL6nBY,16214
12
12
  extensions/job_executor/k8s_job_spec.yaml,sha256=7aFpxHdO_p6Hkc3YxusUOuAQTD1Myu0yTPX9DrhxbOg,1158
13
- extensions/job_executor/local.py,sha256=FvxTk0vyxdrbLOAyNkLyjvmmowypabWOSITQBK_ffVE,1907
14
- extensions/job_executor/local_container.py,sha256=hyFnpicCp3_87mZsW64P6KSVbz7XMLjwJUWVjeCJ0_I,6627
13
+ extensions/job_executor/local.py,sha256=3v6F8SOaPbCfPVVmU07RFr1wgs8iC8WoSn6Evfi8o3M,2033
14
+ extensions/job_executor/local_container.py,sha256=8-dLhzY34pOVjJ_x0VmeTwVvYkESXBnp4j-XLsSsgBk,6688
15
15
  extensions/job_executor/pyproject.toml,sha256=UIEgiCYHTXcRWSByNMFuKJFKgxTBpQqTqyUecIsb_Vc,286
16
16
  extensions/nodes/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- extensions/nodes/nodes.py,sha256=WdOmep4uxmY2mTOtsuVZ5QhYl96jqJprkG6jkIg7BVg,34774
17
+ extensions/nodes/nodes.py,sha256=s9ub1dqy4qHjRQG6YElCdL7rCOTYNs9RUIrStZ6tEB4,28256
18
18
  extensions/nodes/pyproject.toml,sha256=YTu-ETN3JNFSkMzzWeOwn4m-O2nbRH-PmiPBALDCUw4,278
19
+ extensions/nodes/torch.py,sha256=kB4a72YMcrxDDzbR5LffODtrdA7vUo9dRJlaVr8KEEM,5570
20
+ extensions/nodes/torch_config.py,sha256=yDvDADpnLhQsNtfH8qIztLHQ2LhYiOJEWljxpH9GZzs,1222
19
21
  extensions/pipeline_executor/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- extensions/pipeline_executor/__init__.py,sha256=lk_QmbfzXNrgpF_KvMPuPpzxp0B8SJobDHWrK_0Q5FE,24359
21
- extensions/pipeline_executor/argo.py,sha256=nnlR_D6arQMUSgAevnW1RXeN48SoB1wVcEfQ4TBireY,34543
22
- extensions/pipeline_executor/local.py,sha256=H8s6AdML_9_f-vdGG_6k0y9FbLqAqvA1S_7xMNyARzY,1946
23
- extensions/pipeline_executor/local_container.py,sha256=HOT9I-cPDCvgy6_bzNEtl4jPhTyeYSn1GK7lplH3vDA,12515
24
- extensions/pipeline_executor/mocked.py,sha256=SuObJ6Myt7p8duW8sylIp1cYIAnFutsJW1avWaOUY3c,5798
22
+ extensions/pipeline_executor/__init__.py,sha256=9ZMHcieSYdTiYyjSkc8eT8yhOlKEUFnrbrdbqdOgvP0,24195
23
+ extensions/pipeline_executor/argo.py,sha256=svnje6l1mYfLhrHZf54pE_ljwxvH8Gt0ZXSLWLDs4aQ,37869
24
+ extensions/pipeline_executor/local.py,sha256=6oWUJ6b6NvIkpeQJBoCT1hbfX4_6WCB4HzMgHZ4ik1A,1887
25
+ extensions/pipeline_executor/local_container.py,sha256=3kZ2QCsrq_YjH9dcAz8v05knKShQ_JtbIU-IA_-G538,12724
26
+ extensions/pipeline_executor/mocked.py,sha256=0sMmypuvstBIv9uQg-WAcPrF3oOFpeEXNi6N8Nzdnl0,5680
25
27
  extensions/pipeline_executor/pyproject.toml,sha256=ykTX7srR10PBYb8LsIwEj8vIPPIEZQ5V_R7VYbZ-ido,291
26
- extensions/pipeline_executor/retry.py,sha256=KGenhWrLLmOQgzMvqloXHDRJyoNs91t05rRW8aLW6FA,6969
28
+ extensions/pipeline_executor/retry.py,sha256=6ClFXJYtr0M6nWIZiI-mbUGshobOtVH_KADN8JCfvH0,6881
27
29
  extensions/run_log_store/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
30
  extensions/run_log_store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
31
  extensions/run_log_store/any_path.py,sha256=0nN_LHbm2W6AHkerQmsVHq3EoybFQF8lxpCicacHo8Y,2861
30
32
  extensions/run_log_store/chunked_fs.py,sha256=wHMKcAx6uFI4OOTp7QWCdGq9WvEFesbLp9VxHZU28l0,3341
31
33
  extensions/run_log_store/chunked_minio.py,sha256=Itfkw4Ycf0uLCqxH3Uk_itmVgT7ipJp05yKfD22WBiY,4007
32
34
  extensions/run_log_store/file_system.py,sha256=hhrbhSnuzv8yzBr6DAu45NT8-sawPP86WA2-LY70vjw,2781
33
- extensions/run_log_store/generic_chunked.py,sha256=bsGgChTDZN3dSbLmLJ9SIpcvArzVmzhTVAOYZytAUNc,20483
35
+ extensions/run_log_store/generic_chunked.py,sha256=EnhRxlqm1jG-Tdxul4sY8OeCX5fK9FY2v8DZanX9-5o,20455
34
36
  extensions/run_log_store/minio.py,sha256=omrKDSdRzmnVBg9xXkkdQb-icBIgBDRdpmwGRlMyCGk,3453
35
37
  extensions/run_log_store/pyproject.toml,sha256=YnmXsFvFG9uv_c0spLYBsNI_1sbktqxtHsOuClyvZ3g,288
36
38
  extensions/run_log_store/db/implementation_FF.py,sha256=euTnh0xzNF0e_DyfHQ4W-kG1AwTr8u7OuO3_cZkR5bM,5237
37
39
  extensions/run_log_store/db/integration_FF.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
40
  extensions/secrets/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- extensions/secrets/dotenv.py,sha256=FbYYd_pVuJuVuIDIvXbzKuSSQ9GPq7xJXTDbJMTQbhM,1583
41
+ extensions/secrets/dotenv.py,sha256=nADHXI6KJ_LUYOIe5EbtYH-21OBebSNVr0Pjb1GlZ7w,1573
40
42
  extensions/secrets/pyproject.toml,sha256=mLJNImNcBlbLKHh-0ugVWT9V83R4RibyyYDtBCSqVF4,282
41
- runnable/__init__.py,sha256=n14AnTUUEYxXlTJ6-YLT0tMmeFb7Co_3kNldV6pgKSs,662
43
+ runnable/__init__.py,sha256=swvqdCjeddn40o4zjsluyahdVcU0r1arSRrxmRsvFEQ,673
42
44
  runnable/catalog.py,sha256=W_erYbLZ-ffuA9RQuWVqz1DUJOuWayf32ne32IDbAbc,4358
43
45
  runnable/cli.py,sha256=3BiKSj95h2Drn__YlchMPZ5rBMafuRb2OGIsVpbsO5Y,8788
44
46
  runnable/context.py,sha256=by5uepmuCP0dmM9BmsliXihSes5QEFejwAsmekcqylE,1388
@@ -46,18 +48,18 @@ runnable/datastore.py,sha256=ZobM1aVkgeUJ2fZYt63IFDsoNzObwc93hdByegS5YKQ,32396
46
48
  runnable/defaults.py,sha256=3o9IVGryyCE6PoQTOoaIaHHTbJGEzmdXMcwzOhwAYoI,3518
47
49
  runnable/entrypoints.py,sha256=cDbhtmLUWdBh9K6hNusfQpSd5NadcX8V1K2JEDf_YAg,18984
48
50
  runnable/exceptions.py,sha256=LFbp0-Qxg2PAMLEVt7w2whhBxSG-5pzUEv5qN-Rc4_c,3003
49
- runnable/executor.py,sha256=UCBBtyD0khl9QjT4SRTFMQDHDLWfJUC2U4_b3KQzaBE,15127
51
+ runnable/executor.py,sha256=J8-Ri9nBZCb-ao6okePb9FUVlhAaPc0ojQ2l48-FUqc,15031
50
52
  runnable/graph.py,sha256=poQz5zcvq89ju_u5sYlunQLPbHnXTaUmjcvstPwvT4U,16536
51
53
  runnable/names.py,sha256=vn92Kv9ANROYSZX6Z4z1v_WA3WiEdIYmG6KEStBFZug,8134
52
- runnable/nodes.py,sha256=YU9u7r1ESzui1uVtJ1dgwdv1ozyJnF2k-MCFieT8CLI,17519
54
+ runnable/nodes.py,sha256=d1eLttMAcV7CTwTEqOuNwZqItANoLUkXJ73Xp-srlyI,17811
53
55
  runnable/parameters.py,sha256=sT3DNGczivP9z7r4Cp_brbudg1z4J-zjmvrq3ppIrVs,5089
54
56
  runnable/pickler.py,sha256=ydJ_eti_U1F4l-YacFp7BWm6g5vTn04UXye25S1HVok,2684
55
- runnable/sdk.py,sha256=y3fbK4KAP6FiTF37ickVF9gqaZXrJIgSnHGOSG5ZWpI,33803
56
- runnable/secrets.py,sha256=PXcEJw-4WPzeWRLfsatcPPyr1zkqgHzdRWRcS9vvpvM,2354
57
- runnable/tasks.py,sha256=X6xijut7ffwpfYDcXoN6y0AcRVd7fWHs676DJ00Kma4,29134
57
+ runnable/sdk.py,sha256=NZVQGaL4Zm2hwloRmqEgp8UPbBg9hY1abQGYnOgniPI,35128
58
+ runnable/secrets.py,sha256=4L_dBFxTgr8r_hHUD6RlZEtqaOHDRsFG5PXO5wlvMI0,2324
59
+ runnable/tasks.py,sha256=Qb1IhVxHv68E7vf3M3YCf7MGRHyjmsEEYBpEpiZ4mRI,29062
58
60
  runnable/utils.py,sha256=hBr7oGwGL2VgfITlQCTz-a1iwvvf7Mfl-HY8UdENZac,19929
59
- runnable-0.28.8.dist-info/METADATA,sha256=zA7aiT_kZ5NikkA0SRFmCC-83ZcjN883gHIQqVJXntw,10047
60
- runnable-0.28.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
61
- runnable-0.28.8.dist-info/entry_points.txt,sha256=ioMbWojILtdibYVgh1jXJ00SpK-tX3gy7oVGDq61cSk,1839
62
- runnable-0.28.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
63
- runnable-0.28.8.dist-info/RECORD,,
61
+ runnable-0.30.0.dist-info/METADATA,sha256=mFY61nh2mT8DGjewQKOJIlNVxcZisIWsLZ6FlcvHvZU,10115
62
+ runnable-0.30.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
63
+ runnable-0.30.0.dist-info/entry_points.txt,sha256=PrjKrlfXPZaV_7hz8orGu4FDnatLqnhPOXljyllszdw,1880
64
+ runnable-0.30.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
65
+ runnable-0.30.0.dist-info/RECORD,,
@@ -21,6 +21,7 @@ parallel = extensions.nodes.nodes:ParallelNode
21
21
  stub = extensions.nodes.nodes:StubNode
22
22
  success = extensions.nodes.nodes:SuccessNode
23
23
  task = extensions.nodes.nodes:TaskNode
24
+ torch = extensions.nodes.torch:TorchNode
24
25
 
25
26
  [pickler]
26
27
  pickle = runnable.pickler:NativePickler