digitalhub 0.8.1__py3-none-any.whl → 0.9.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.

Potentially problematic release.


This version of digitalhub might be problematic. Click here for more details.

Files changed (134) hide show
  1. digitalhub/__init__.py +19 -2
  2. digitalhub/client/_base/api_builder.py +16 -0
  3. digitalhub/client/_base/client.py +67 -0
  4. digitalhub/client/_base/key_builder.py +52 -0
  5. digitalhub/client/api.py +2 -38
  6. digitalhub/client/dhcore/api_builder.py +100 -0
  7. digitalhub/client/dhcore/client.py +81 -25
  8. digitalhub/client/dhcore/enums.py +27 -0
  9. digitalhub/client/dhcore/env.py +2 -2
  10. digitalhub/client/dhcore/key_builder.py +58 -0
  11. digitalhub/client/dhcore/utils.py +17 -17
  12. digitalhub/client/local/api_builder.py +100 -0
  13. digitalhub/client/local/client.py +22 -0
  14. digitalhub/client/local/key_builder.py +58 -0
  15. digitalhub/context/api.py +3 -38
  16. digitalhub/context/builder.py +10 -23
  17. digitalhub/context/context.py +20 -92
  18. digitalhub/entities/_base/context/entity.py +30 -22
  19. digitalhub/entities/_base/entity/_constructors/metadata.py +12 -1
  20. digitalhub/entities/_base/entity/_constructors/name.py +1 -1
  21. digitalhub/entities/_base/entity/_constructors/spec.py +1 -1
  22. digitalhub/entities/_base/entity/_constructors/status.py +3 -2
  23. digitalhub/entities/_base/entity/builder.py +6 -1
  24. digitalhub/entities/_base/entity/entity.py +32 -10
  25. digitalhub/entities/_base/entity/metadata.py +22 -0
  26. digitalhub/entities/_base/entity/spec.py +7 -2
  27. digitalhub/entities/_base/executable/entity.py +8 -8
  28. digitalhub/entities/_base/material/entity.py +49 -17
  29. digitalhub/entities/_base/material/status.py +0 -31
  30. digitalhub/entities/_base/material/utils.py +106 -0
  31. digitalhub/entities/_base/project/entity.py +341 -0
  32. digitalhub/entities/_base/unversioned/entity.py +3 -24
  33. digitalhub/entities/_base/versioned/entity.py +2 -26
  34. digitalhub/entities/_commons/enums.py +103 -0
  35. digitalhub/entities/_commons/utils.py +83 -0
  36. digitalhub/entities/_operations/processor.py +1873 -0
  37. digitalhub/entities/artifact/_base/builder.py +1 -1
  38. digitalhub/entities/artifact/_base/entity.py +1 -1
  39. digitalhub/entities/artifact/artifact/builder.py +2 -1
  40. digitalhub/entities/artifact/crud.py +46 -29
  41. digitalhub/entities/artifact/utils.py +62 -0
  42. digitalhub/entities/dataitem/_base/builder.py +1 -1
  43. digitalhub/entities/dataitem/_base/entity.py +6 -6
  44. digitalhub/entities/dataitem/crud.py +50 -66
  45. digitalhub/entities/dataitem/dataitem/builder.py +2 -1
  46. digitalhub/entities/dataitem/iceberg/builder.py +2 -1
  47. digitalhub/entities/dataitem/table/builder.py +2 -1
  48. digitalhub/entities/dataitem/table/entity.py +5 -10
  49. digitalhub/entities/dataitem/table/models.py +4 -5
  50. digitalhub/entities/dataitem/utils.py +137 -0
  51. digitalhub/entities/function/_base/builder.py +1 -1
  52. digitalhub/entities/function/_base/entity.py +6 -2
  53. digitalhub/entities/function/crud.py +36 -17
  54. digitalhub/entities/model/_base/builder.py +1 -1
  55. digitalhub/entities/model/_base/entity.py +1 -1
  56. digitalhub/entities/model/crud.py +46 -29
  57. digitalhub/entities/model/huggingface/builder.py +2 -1
  58. digitalhub/entities/model/huggingface/spec.py +4 -2
  59. digitalhub/entities/model/mlflow/builder.py +2 -1
  60. digitalhub/entities/model/mlflow/models.py +17 -9
  61. digitalhub/entities/model/mlflow/spec.py +6 -1
  62. digitalhub/entities/model/mlflow/utils.py +4 -2
  63. digitalhub/entities/model/model/builder.py +2 -1
  64. digitalhub/entities/model/sklearn/builder.py +2 -1
  65. digitalhub/entities/model/utils.py +62 -0
  66. digitalhub/entities/project/_base/builder.py +2 -2
  67. digitalhub/entities/project/_base/entity.py +82 -272
  68. digitalhub/entities/project/crud.py +110 -91
  69. digitalhub/entities/project/utils.py +35 -0
  70. digitalhub/entities/run/_base/builder.py +3 -1
  71. digitalhub/entities/run/_base/entity.py +52 -54
  72. digitalhub/entities/run/_base/spec.py +15 -7
  73. digitalhub/entities/run/crud.py +35 -17
  74. digitalhub/entities/secret/_base/builder.py +2 -2
  75. digitalhub/entities/secret/_base/entity.py +4 -10
  76. digitalhub/entities/secret/crud.py +36 -21
  77. digitalhub/entities/task/_base/builder.py +14 -14
  78. digitalhub/entities/task/_base/entity.py +21 -14
  79. digitalhub/entities/task/_base/models.py +35 -6
  80. digitalhub/entities/task/_base/spec.py +50 -13
  81. digitalhub/entities/task/_base/utils.py +18 -0
  82. digitalhub/entities/task/crud.py +35 -15
  83. digitalhub/entities/workflow/_base/builder.py +1 -1
  84. digitalhub/entities/workflow/_base/entity.py +22 -6
  85. digitalhub/entities/workflow/crud.py +36 -17
  86. digitalhub/factory/utils.py +1 -1
  87. digitalhub/readers/_base/reader.py +2 -2
  88. digitalhub/readers/_commons/enums.py +13 -0
  89. digitalhub/readers/api.py +3 -2
  90. digitalhub/readers/factory.py +12 -6
  91. digitalhub/readers/pandas/reader.py +20 -8
  92. digitalhub/runtimes/_base.py +0 -7
  93. digitalhub/runtimes/enums.py +12 -0
  94. digitalhub/stores/_base/store.py +59 -11
  95. digitalhub/stores/builder.py +5 -5
  96. digitalhub/stores/local/store.py +43 -4
  97. digitalhub/stores/remote/store.py +31 -5
  98. digitalhub/stores/s3/store.py +129 -48
  99. digitalhub/stores/sql/store.py +122 -47
  100. digitalhub/utils/exceptions.py +6 -0
  101. digitalhub/utils/file_utils.py +60 -2
  102. digitalhub/utils/generic_utils.py +45 -4
  103. digitalhub/utils/io_utils.py +18 -0
  104. digitalhub/utils/s3_utils.py +17 -0
  105. digitalhub/utils/uri_utils.py +153 -15
  106. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/LICENSE.txt +1 -1
  107. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/METADATA +3 -3
  108. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/RECORD +116 -114
  109. test/local/instances/test_validate.py +55 -0
  110. test/testkfp.py +4 -1
  111. digitalhub/datastores/_base/datastore.py +0 -85
  112. digitalhub/datastores/api.py +0 -37
  113. digitalhub/datastores/builder.py +0 -110
  114. digitalhub/datastores/local/datastore.py +0 -50
  115. digitalhub/datastores/remote/__init__.py +0 -0
  116. digitalhub/datastores/remote/datastore.py +0 -31
  117. digitalhub/datastores/s3/__init__.py +0 -0
  118. digitalhub/datastores/s3/datastore.py +0 -46
  119. digitalhub/datastores/sql/__init__.py +0 -0
  120. digitalhub/datastores/sql/datastore.py +0 -68
  121. digitalhub/entities/_base/api_utils.py +0 -620
  122. digitalhub/entities/_base/crud.py +0 -468
  123. digitalhub/entities/function/_base/models.py +0 -118
  124. digitalhub/entities/utils/__init__.py +0 -0
  125. digitalhub/entities/utils/api.py +0 -346
  126. digitalhub/entities/utils/entity_types.py +0 -19
  127. digitalhub/entities/utils/state.py +0 -31
  128. digitalhub/entities/utils/utils.py +0 -202
  129. /digitalhub/{context → entities/_base/project}/__init__.py +0 -0
  130. /digitalhub/{datastores → entities/_commons}/__init__.py +0 -0
  131. /digitalhub/{datastores/_base → entities/_operations}/__init__.py +0 -0
  132. /digitalhub/{datastores/local → readers/_commons}/__init__.py +0 -0
  133. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/WHEEL +0 -0
  134. {digitalhub-0.8.1.dist-info → digitalhub-0.9.0.dist-info}/top_level.txt +0 -0
@@ -1,18 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import importlib.util as imputil
4
3
  import typing
5
- from pathlib import Path
6
4
 
7
- from digitalhub.client.api import build_client, get_client
8
- from digitalhub.context.api import delete_context
9
- from digitalhub.entities._base.api_utils import delete_entity_api_base, read_entity_api_base, update_entity_api_base
10
- from digitalhub.entities.utils.entity_types import EntityTypes
11
- from digitalhub.factory.api import build_entity_from_dict, build_entity_from_params
12
- from digitalhub.utils.exceptions import BackendError, EntityAlreadyExistsError, EntityError
13
- from digitalhub.utils.io_utils import read_yaml
5
+ from digitalhub.entities._commons.enums import EntityTypes
6
+ from digitalhub.entities._operations.processor import processor
7
+ from digitalhub.entities.project.utils import setup_project
8
+ from digitalhub.utils.exceptions import BackendError
14
9
 
15
10
  if typing.TYPE_CHECKING:
11
+ from digitalhub.entities._base.context.entity import ContextEntity
16
12
  from digitalhub.entities.project._base.entity import Project
17
13
 
18
14
 
@@ -60,20 +56,19 @@ def new_project(
60
56
  --------
61
57
  >>> obj = new_project("my-project")
62
58
  """
63
- build_client(local, config)
64
59
  if context is None:
65
- context = name
66
- obj = build_entity_from_params(
60
+ context = "./"
61
+ obj = processor.create_project_entity(
67
62
  name=name,
68
63
  kind="project",
69
64
  description=description,
70
65
  labels=labels,
71
66
  local=local,
67
+ config=config,
72
68
  context=context,
73
69
  **kwargs,
74
70
  )
75
- obj.save()
76
- return _setup_project(obj, setup_kwargs)
71
+ return setup_project(obj, setup_kwargs)
77
72
 
78
73
 
79
74
  def get_project(
@@ -108,12 +103,14 @@ def get_project(
108
103
  --------
109
104
  >>> obj = get_project("my-project")
110
105
  """
111
- build_client(local, config)
112
- client = get_client(local)
113
- obj = read_entity_api_base(client, ENTITY_TYPE, name, **kwargs)
114
- obj["local"] = local
115
- project = build_entity_from_dict(obj)
116
- return _setup_project(project, setup_kwargs)
106
+ obj = processor.read_project_entity(
107
+ entity_type=ENTITY_TYPE,
108
+ entity_name=name,
109
+ local=local,
110
+ config=config,
111
+ **kwargs,
112
+ )
113
+ return setup_project(obj, setup_kwargs)
117
114
 
118
115
 
119
116
  def import_project(
@@ -123,7 +120,7 @@ def import_project(
123
120
  setup_kwargs: dict | None = None,
124
121
  ) -> Project:
125
122
  """
126
- Import object from a YAML file.
123
+ Import object from a YAML file and create a new object into the backend.
127
124
 
128
125
  Parameters
129
126
  ----------
@@ -145,42 +142,22 @@ def import_project(
145
142
  --------
146
143
  >>> obj = import_project("my-project.yaml")
147
144
  """
148
- build_client(local, config)
149
- dict_obj: dict = read_yaml(file)
150
- dict_obj["local"] = local
151
- obj = build_entity_from_dict(dict_obj)
152
- obj = _setup_project(obj, setup_kwargs)
153
-
154
- try:
155
- obj.save()
156
- except EntityAlreadyExistsError:
157
- pass
158
-
159
- # Import related entities
160
- obj._import_entities(dict_obj)
161
-
162
- obj.refresh()
163
-
164
- return obj
145
+ obj = processor.import_project_entity(file=file, local=local, config=config)
146
+ return setup_project(obj, setup_kwargs)
165
147
 
166
148
 
167
149
  def load_project(
168
- name: str | None = None,
169
- filename: str | None = None,
150
+ file: str,
170
151
  local: bool = False,
171
152
  config: dict | None = None,
172
153
  setup_kwargs: dict | None = None,
173
- **kwargs,
174
154
  ) -> Project:
175
155
  """
176
- Load project and context from backend or file. Name or
177
- filename must be provided. Name takes precedence over filename.
156
+ Load object from a YAML file and update an existing object into the backend.
178
157
 
179
158
  Parameters
180
159
  ----------
181
- name : str
182
- Project name.
183
- filename : str
160
+ file : str
184
161
  Path to YAML file.
185
162
  local : bool
186
163
  Flag to determine if backend is local.
@@ -188,8 +165,6 @@ def load_project(
188
165
  DHCore environment configuration.
189
166
  setup_kwargs : dict
190
167
  Setup keyword arguments passed to setup_project() function.
191
- **kwargs : dict
192
- Keyword arguments.
193
168
 
194
169
  Returns
195
170
  -------
@@ -198,17 +173,29 @@ def load_project(
198
173
 
199
174
  Examples
200
175
  --------
201
- If name is provided, load project from backend.
202
- >>> obj = load_project(name="my-project")
176
+ >>> obj = load_project("my-project.yaml")
177
+ """
178
+ obj = processor.load_project_entity(file=file, local=local, config=config)
179
+ return setup_project(obj, setup_kwargs)
180
+
203
181
 
204
- If filename is provided, load project from file.
205
- >>> obj = load_project(filename="my-project.yaml")
182
+ def list_projects(local: bool = False, **kwargs) -> list[Project]:
206
183
  """
207
- if name is not None:
208
- return get_project(name=name, local=local, config=config, setup_kwargs=setup_kwargs, **kwargs)
209
- if filename is not None:
210
- return import_project(filename, local=local, config=config, setup_kwargs=setup_kwargs)
211
- raise EntityError("Either name or filename must be provided.")
184
+ List projects in backend.
185
+
186
+ Parameters
187
+ ----------
188
+ local : bool
189
+ Flag to determine if backend is local.
190
+ **kwargs : dict
191
+ Parameters to pass to the API call.
192
+
193
+ Returns
194
+ -------
195
+ list
196
+ List of objects.
197
+ """
198
+ return processor.list_project_entities(local=local, **kwargs)
212
199
 
213
200
 
214
201
  def get_or_create_project(
@@ -261,7 +248,7 @@ def get_or_create_project(
261
248
  )
262
249
 
263
250
 
264
- def update_project(entity: Project, local: bool = False, **kwargs) -> Project:
251
+ def update_project(entity: Project, **kwargs) -> Project:
265
252
  """
266
253
  Update object. Note that object spec are immutable.
267
254
 
@@ -269,8 +256,6 @@ def update_project(entity: Project, local: bool = False, **kwargs) -> Project:
269
256
  ----------
270
257
  entity : Project
271
258
  Object to update.
272
- local : bool
273
- Flag to determine if backend is local.
274
259
  **kwargs : dict
275
260
  Parameters to pass to the API call.
276
261
 
@@ -283,9 +268,13 @@ def update_project(entity: Project, local: bool = False, **kwargs) -> Project:
283
268
  --------
284
269
  >>> obj = update_project(obj)
285
270
  """
286
- client = get_client(local)
287
- obj = update_entity_api_base(client, ENTITY_TYPE, entity.name, entity.to_dict(), **kwargs)
288
- return build_entity_from_dict(obj)
271
+ return processor.update_project_entity(
272
+ entity_type=entity.ENTITY_TYPE,
273
+ entity_name=entity.name,
274
+ entity_dict=entity.to_dict(),
275
+ local=entity.local,
276
+ **kwargs,
277
+ )
289
278
 
290
279
 
291
280
  def delete_project(
@@ -305,8 +294,7 @@ def delete_project(
305
294
  cascade : bool
306
295
  Flag to determine if delete is cascading.
307
296
  clean_context : bool
308
- Flag to determine if context will be deleted. If a context is deleted,
309
- all its objects are unreacheable.
297
+ Flag to determine if context will be deleted.
310
298
  local : bool
311
299
  Flag to determine if backend is local.
312
300
  **kwargs : dict
@@ -321,37 +309,68 @@ def delete_project(
321
309
  --------
322
310
  >>> delete_project("my-project")
323
311
  """
324
- client = get_client(local)
325
- obj = delete_entity_api_base(client, ENTITY_TYPE, name, cascade=cascade, **kwargs)
326
- if clean_context:
327
- delete_context(name)
328
- return obj
312
+ return processor.delete_project_entity(
313
+ entity_type=ENTITY_TYPE,
314
+ entity_name=name,
315
+ local=local,
316
+ cascade=cascade,
317
+ clean_context=clean_context,
318
+ **kwargs,
319
+ )
329
320
 
330
321
 
331
- def _setup_project(project: Project, setup_kwargs: dict | None = None) -> Project:
322
+ def search_entity(
323
+ project_name: str,
324
+ query: str | None = None,
325
+ entity_types: list[str] | None = None,
326
+ name: str | None = None,
327
+ kind: str | None = None,
328
+ created: str | None = None,
329
+ updated: str | None = None,
330
+ description: str | None = None,
331
+ labels: list[str] | None = None,
332
+ **kwargs,
333
+ ) -> list[ContextEntity]:
332
334
  """
333
- Search for setup_project.py file and launch setup hanlder as project hook.
335
+ Search objects from backend.
334
336
 
335
337
  Parameters
336
338
  ----------
337
- project : Project
338
- The project to scafold.
339
- setup_kwargs : dict
340
- Arguments to pass to setup handler.
339
+ project_name : str
340
+ Project name.
341
+ query : str
342
+ Search query.
343
+ entity_types : list[str]
344
+ Entity types.
345
+ name : str
346
+ Entity name.
347
+ kind : str
348
+ Entity kind.
349
+ created : str
350
+ Entity creation date.
351
+ updated : str
352
+ Entity update date.
353
+ description : str
354
+ Entity description.
355
+ labels : list[str]
356
+ Entity labels.
357
+ **kwargs : dict
358
+ Parameters to pass to the API call.
341
359
 
342
- Returns
343
- -------
344
- Project
345
- Set up project.
360
+ Returns
361
+ -------
362
+ list[ContextEntity]
363
+ List of object instances.
346
364
  """
347
- setup_kwargs = setup_kwargs if setup_kwargs is not None else {}
348
- check_pth = Path(project.spec.context, ".CHECK")
349
- setup_pth = Path(project.spec.context, "setup_project.py")
350
- if setup_pth.exists() and not check_pth.exists():
351
- spec = imputil.spec_from_file_location("setup_project", setup_pth)
352
- mod = imputil.module_from_spec(spec)
353
- spec.loader.exec_module(mod)
354
- handler = getattr(mod, "setup")
355
- project = handler(project, **setup_kwargs)
356
- check_pth.touch()
357
- return project
365
+ return processor.search_entity(
366
+ project_name,
367
+ query=query,
368
+ entity_types=entity_types,
369
+ name=name,
370
+ kind=kind,
371
+ created=created,
372
+ updated=updated,
373
+ description=description,
374
+ labels=labels,
375
+ **kwargs,
376
+ )
@@ -0,0 +1,35 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from pathlib import Path
5
+
6
+ from digitalhub.utils.generic_utils import import_function
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from digitalhub.entities.project._base.entity import Project
10
+
11
+
12
+ def setup_project(project: Project, setup_kwargs: dict | None = None) -> Project:
13
+ """
14
+ Search for setup_project.py file and launch setup hanlder as project hook.
15
+
16
+ Parameters
17
+ ----------
18
+ project : Project
19
+ The project to scafold.
20
+ setup_kwargs : dict
21
+ Arguments to pass to setup handler.
22
+
23
+ Returns
24
+ -------
25
+ Project
26
+ Set up project.
27
+ """
28
+ setup_kwargs = setup_kwargs if setup_kwargs is not None else {}
29
+ check_pth = Path(project.spec.context, ".CHECK")
30
+ setup_pth = Path(project.spec.context, "setup_project.py")
31
+ if setup_pth.exists() and not check_pth.exists():
32
+ setup_fnc = import_function(setup_pth, "setup")
33
+ project = setup_fnc(project, **setup_kwargs)
34
+ check_pth.touch()
35
+ return project
@@ -4,7 +4,7 @@ import typing
4
4
 
5
5
  from digitalhub.entities._base.runtime_entity.builder import EntityError, RuntimeEntityBuilder
6
6
  from digitalhub.entities._base.unversioned.builder import UnversionedBuilder
7
- from digitalhub.entities.utils.entity_types import EntityTypes
7
+ from digitalhub.entities._commons.enums import EntityTypes
8
8
 
9
9
  if typing.TYPE_CHECKING:
10
10
  from digitalhub.entities.run._base.entity import Run
@@ -52,9 +52,11 @@ class RunBuilder(UnversionedBuilder, RuntimeEntityBuilder):
52
52
  Run
53
53
  Object instance.
54
54
  """
55
+ # Check task validity
55
56
  if task is None:
56
57
  raise EntityError("Missing task in run spec")
57
58
  self._check_kind_validity(task)
59
+
58
60
  uuid = self.build_uuid(uuid)
59
61
  metadata = self.build_metadata(
60
62
  project=project,
@@ -3,17 +3,9 @@ from __future__ import annotations
3
3
  import time
4
4
  import typing
5
5
 
6
- from digitalhub.entities._base.api_utils import (
7
- list_entity_api_base,
8
- list_entity_api_ctx,
9
- logs_api,
10
- read_entity_api_ctx,
11
- resume_api,
12
- stop_api,
13
- )
14
6
  from digitalhub.entities._base.unversioned.entity import UnversionedEntity
15
- from digitalhub.entities.utils.entity_types import EntityTypes
16
- from digitalhub.entities.utils.state import State
7
+ from digitalhub.entities._commons.enums import EntityTypes, State
8
+ from digitalhub.entities._operations.processor import processor
17
9
  from digitalhub.factory.api import (
18
10
  build_runtime,
19
11
  build_spec,
@@ -68,12 +60,9 @@ class Run(UnversionedEntity):
68
60
  executable = self._get_executable()
69
61
  task = self._get_task()
70
62
  new_spec = self._get_runtime().build(executable, task, self.to_dict())
71
- self.spec = build_spec(
72
- self.kind,
73
- **new_spec,
74
- )
63
+ self.spec = build_spec(self.kind, **new_spec)
75
64
  self._set_state(State.BUILT.value)
76
- self.save()
65
+ self.save(update=True)
77
66
 
78
67
  def run(self) -> Run:
79
68
  """
@@ -85,12 +74,8 @@ class Run(UnversionedEntity):
85
74
  Run object.
86
75
  """
87
76
  self.refresh()
88
- if self.spec.local_execution:
89
- if not self._is_ready_to_run():
90
- raise EntityError("Run is not in a state to run.")
91
- self._set_state(State.RUNNING.value)
92
- self.save(update=True)
93
77
 
78
+ self._start_execution()
94
79
  self._setup_execution()
95
80
 
96
81
  try:
@@ -102,6 +87,8 @@ class Run(UnversionedEntity):
102
87
  self._set_message(str(e))
103
88
  self.save(update=True)
104
89
  raise e
90
+ finally:
91
+ self._finish_execution()
105
92
 
106
93
  self.refresh()
107
94
  if not self.spec.local_execution:
@@ -143,17 +130,14 @@ class Run(UnversionedEntity):
143
130
 
144
131
  def logs(self) -> dict:
145
132
  """
146
- Get object from backend.
147
- Returns empty dictionary if context is local.
133
+ Get run logs.
148
134
 
149
135
  Returns
150
136
  -------
151
137
  dict
152
- Logs from backend.
138
+ Run logs.
153
139
  """
154
- if self._context().local:
155
- return {}
156
- return logs_api(self.project, self.ENTITY_TYPE, self.id)
140
+ return processor.read_run_logs(self.project, self.ENTITY_TYPE, self.id)
157
141
 
158
142
  def stop(self) -> None:
159
143
  """
@@ -163,8 +147,8 @@ class Run(UnversionedEntity):
163
147
  -------
164
148
  None
165
149
  """
166
- if not self._context().local and not self.spec.local_execution:
167
- return stop_api(self.project, self.ENTITY_TYPE, self.id)
150
+ if not self.spec.local_execution:
151
+ return processor.stop_run(self.project, self.ENTITY_TYPE, self.id)
168
152
 
169
153
  def resume(self) -> None:
170
154
  """
@@ -174,9 +158,8 @@ class Run(UnversionedEntity):
174
158
  -------
175
159
  None
176
160
  """
177
- if not self._context().local and not self.spec.local_execution:
178
- return resume_api(self.project, self.ENTITY_TYPE, self.id)
179
- self.run()
161
+ if not self.spec.local_execution:
162
+ return processor.resume_run(self.project, self.ENTITY_TYPE, self.id)
180
163
 
181
164
  ##############################
182
165
  # Helpers
@@ -184,13 +167,38 @@ class Run(UnversionedEntity):
184
167
 
185
168
  def _setup_execution(self) -> None:
186
169
  """
187
- Setup run execution. In base class, nothing to do.
170
+ Setup run execution.
188
171
 
189
172
  Returns
190
173
  -------
191
174
  None
192
175
  """
193
176
 
177
+ def _start_execution(self) -> None:
178
+ """
179
+ Start run execution.
180
+
181
+ Returns
182
+ -------
183
+ None
184
+ """
185
+ self._context().set_run(f"{self.key}:{self.id}")
186
+ if self.spec.local_execution:
187
+ if not self._is_ready_to_run():
188
+ raise EntityError("Run is not in a state to run.")
189
+ self._set_state(State.RUNNING.value)
190
+ self.save(update=True)
191
+
192
+ def _finish_execution(self) -> None:
193
+ """
194
+ Finish run execution.
195
+
196
+ Returns
197
+ -------
198
+ None
199
+ """
200
+ self._context().unset_run()
201
+
194
202
  def _is_ready_to_run(self) -> bool:
195
203
  """
196
204
  Check if run is in a state ready for running (BUILT or STOPPED).
@@ -269,16 +277,15 @@ class Run(UnversionedEntity):
269
277
  Executable (function or workflow) from backend.
270
278
  """
271
279
  exec_kind = get_executable_kind(self.kind)
272
- entity_type = get_entity_type_from_kind(exec_kind)
273
- splitted = self.spec.task.split("/")
274
- exec_name = splitted[-1].split(":")[0]
275
- exec_id = splitted[-1].split(":")[1]
276
- return read_entity_api_ctx(
280
+ exec_type = get_entity_type_from_kind(exec_kind)
281
+ string_to_split = getattr(self.spec, exec_type)
282
+ exec_name, exec_id = string_to_split.split("://")[-1].split("/")[-1].split(":")
283
+ return processor.read_context_entity(
277
284
  exec_name,
278
- entity_type=entity_type,
285
+ entity_type=exec_type,
279
286
  project=self.project,
280
287
  entity_id=exec_id,
281
- )
288
+ ).to_dict()
282
289
 
283
290
  def _get_task(self) -> dict:
284
291
  """
@@ -290,18 +297,9 @@ class Run(UnversionedEntity):
290
297
  dict
291
298
  Task from backend.
292
299
  """
293
- executable_kind = get_executable_kind(self.kind)
294
- exec_string = f"{executable_kind}://{self.spec.task.split('://')[1]}"
295
-
296
- # Local backend
297
- if self._context().local:
298
- tasks = list_entity_api_base(self._context().client, EntityTypes.TASK.value)
299
- for i in tasks:
300
- if i.get("spec").get("function") == exec_string:
301
- return i
302
- raise EntityError("Task not found.")
303
-
304
- # Remote backend
305
- task_kind = self.spec.task.split("://")[0]
306
- params = {"function": exec_string, "kind": task_kind}
307
- return list_entity_api_ctx(self.project, EntityTypes.TASK.value, params=params)[0]
300
+ task_id = self.spec.task.split("://")[-1].split("/")[-1]
301
+ return processor.read_unversioned_entity(
302
+ task_id,
303
+ entity_type=EntityTypes.TASK.value,
304
+ project=self.project,
305
+ ).to_dict()
@@ -12,19 +12,23 @@ class RunSpec(Spec):
12
12
  task: str,
13
13
  local_execution: bool = False,
14
14
  function: str | None = None,
15
- node_selector: dict | None = None,
16
- volumes: list | None = None,
15
+ workflow: str | None = None,
16
+ node_selector: list[dict] | None = None,
17
+ volumes: list[dict] | None = None,
17
18
  resources: dict | None = None,
18
19
  affinity: dict | None = None,
19
- tolerations: list | None = None,
20
- envs: list | None = None,
21
- secrets: list | None = None,
20
+ tolerations: list[dict] | None = None,
21
+ envs: list[dict] | None = None,
22
+ secrets: list[str] | None = None,
22
23
  profile: str | None = None,
24
+ runtime_class: str | None = None,
25
+ priority_class: str | None = None,
23
26
  **kwargs,
24
27
  ) -> None:
25
28
  self.task = task
26
29
  self.local_execution = local_execution
27
30
  self.function = function
31
+ self.workflow = workflow
28
32
  self.node_selector = node_selector
29
33
  self.volumes = volumes
30
34
  self.resources = resources
@@ -33,6 +37,8 @@ class RunSpec(Spec):
33
37
  self.envs = envs
34
38
  self.secrets = secrets
35
39
  self.profile = profile
40
+ self.runtime_class = runtime_class
41
+ self.priority_class = priority_class
36
42
 
37
43
 
38
44
  class RunValidator(SpecValidator, K8s):
@@ -40,10 +46,12 @@ class RunValidator(SpecValidator, K8s):
40
46
  RunValidator validator.
41
47
  """
42
48
 
49
+ # Task parameters
43
50
  function: str = None
44
- """The function associated with the run."""
51
+ workflow: str = None
45
52
 
46
- task: str = None
53
+ # Run parameters
54
+ task: str
47
55
  """The task string associated with the run."""
48
56
 
49
57
  local_execution: bool = False