digitalhub 0.8.0b0__py3-none-any.whl → 0.8.0b2__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 (159) hide show
  1. digitalhub/__init__.py +62 -94
  2. digitalhub/client/__init__.py +0 -0
  3. digitalhub/client/builder.py +105 -0
  4. digitalhub/client/objects/__init__.py +0 -0
  5. digitalhub/client/objects/base.py +56 -0
  6. digitalhub/client/objects/dhcore.py +681 -0
  7. digitalhub/client/objects/local.py +533 -0
  8. digitalhub/context/__init__.py +0 -0
  9. digitalhub/context/builder.py +178 -0
  10. digitalhub/context/context.py +136 -0
  11. digitalhub/datastores/__init__.py +0 -0
  12. digitalhub/datastores/builder.py +134 -0
  13. digitalhub/datastores/objects/__init__.py +0 -0
  14. digitalhub/datastores/objects/base.py +85 -0
  15. digitalhub/datastores/objects/local.py +42 -0
  16. digitalhub/datastores/objects/remote.py +23 -0
  17. digitalhub/datastores/objects/s3.py +38 -0
  18. digitalhub/datastores/objects/sql.py +60 -0
  19. digitalhub/entities/__init__.py +0 -0
  20. digitalhub/entities/_base/__init__.py +0 -0
  21. digitalhub/entities/_base/api.py +346 -0
  22. digitalhub/entities/_base/base.py +82 -0
  23. digitalhub/entities/_base/crud.py +610 -0
  24. digitalhub/entities/_base/entity/__init__.py +0 -0
  25. digitalhub/entities/_base/entity/base.py +132 -0
  26. digitalhub/entities/_base/entity/context.py +118 -0
  27. digitalhub/entities/_base/entity/executable.py +380 -0
  28. digitalhub/entities/_base/entity/material.py +214 -0
  29. digitalhub/entities/_base/entity/unversioned.py +87 -0
  30. digitalhub/entities/_base/entity/versioned.py +94 -0
  31. digitalhub/entities/_base/metadata.py +59 -0
  32. digitalhub/entities/_base/spec/__init__.py +0 -0
  33. digitalhub/entities/_base/spec/base.py +58 -0
  34. digitalhub/entities/_base/spec/material.py +22 -0
  35. digitalhub/entities/_base/state.py +31 -0
  36. digitalhub/entities/_base/status/__init__.py +0 -0
  37. digitalhub/entities/_base/status/base.py +32 -0
  38. digitalhub/entities/_base/status/material.py +49 -0
  39. digitalhub/entities/_builders/__init__.py +0 -0
  40. digitalhub/entities/_builders/metadata.py +60 -0
  41. digitalhub/entities/_builders/name.py +31 -0
  42. digitalhub/entities/_builders/spec.py +43 -0
  43. digitalhub/entities/_builders/status.py +62 -0
  44. digitalhub/entities/_builders/uuid.py +33 -0
  45. digitalhub/entities/artifact/__init__.py +0 -0
  46. digitalhub/entities/artifact/builder.py +133 -0
  47. digitalhub/entities/artifact/crud.py +358 -0
  48. digitalhub/entities/artifact/entity/__init__.py +0 -0
  49. digitalhub/entities/artifact/entity/_base.py +39 -0
  50. digitalhub/entities/artifact/entity/artifact.py +9 -0
  51. digitalhub/entities/artifact/spec.py +39 -0
  52. digitalhub/entities/artifact/status.py +15 -0
  53. digitalhub/entities/dataitem/__init__.py +0 -0
  54. digitalhub/entities/dataitem/builder.py +144 -0
  55. digitalhub/entities/dataitem/crud.py +395 -0
  56. digitalhub/entities/dataitem/entity/__init__.py +0 -0
  57. digitalhub/entities/dataitem/entity/_base.py +75 -0
  58. digitalhub/entities/dataitem/entity/dataitem.py +9 -0
  59. digitalhub/entities/dataitem/entity/iceberg.py +7 -0
  60. digitalhub/entities/dataitem/entity/table.py +125 -0
  61. digitalhub/entities/dataitem/models.py +62 -0
  62. digitalhub/entities/dataitem/spec.py +61 -0
  63. digitalhub/entities/dataitem/status.py +38 -0
  64. digitalhub/entities/entity_types.py +19 -0
  65. digitalhub/entities/function/__init__.py +0 -0
  66. digitalhub/entities/function/builder.py +86 -0
  67. digitalhub/entities/function/crud.py +305 -0
  68. digitalhub/entities/function/entity.py +101 -0
  69. digitalhub/entities/function/models.py +118 -0
  70. digitalhub/entities/function/spec.py +81 -0
  71. digitalhub/entities/function/status.py +9 -0
  72. digitalhub/entities/model/__init__.py +0 -0
  73. digitalhub/entities/model/builder.py +152 -0
  74. digitalhub/entities/model/crud.py +358 -0
  75. digitalhub/entities/model/entity/__init__.py +0 -0
  76. digitalhub/entities/model/entity/_base.py +34 -0
  77. digitalhub/entities/model/entity/huggingface.py +9 -0
  78. digitalhub/entities/model/entity/mlflow.py +90 -0
  79. digitalhub/entities/model/entity/model.py +9 -0
  80. digitalhub/entities/model/entity/sklearn.py +9 -0
  81. digitalhub/entities/model/models.py +26 -0
  82. digitalhub/entities/model/spec.py +146 -0
  83. digitalhub/entities/model/status.py +33 -0
  84. digitalhub/entities/project/__init__.py +0 -0
  85. digitalhub/entities/project/builder.py +82 -0
  86. digitalhub/entities/project/crud.py +350 -0
  87. digitalhub/entities/project/entity.py +2060 -0
  88. digitalhub/entities/project/spec.py +50 -0
  89. digitalhub/entities/project/status.py +9 -0
  90. digitalhub/entities/registries.py +48 -0
  91. digitalhub/entities/run/__init__.py +0 -0
  92. digitalhub/entities/run/builder.py +77 -0
  93. digitalhub/entities/run/crud.py +232 -0
  94. digitalhub/entities/run/entity.py +461 -0
  95. digitalhub/entities/run/spec.py +153 -0
  96. digitalhub/entities/run/status.py +114 -0
  97. digitalhub/entities/secret/__init__.py +0 -0
  98. digitalhub/entities/secret/builder.py +93 -0
  99. digitalhub/entities/secret/crud.py +294 -0
  100. digitalhub/entities/secret/entity.py +73 -0
  101. digitalhub/entities/secret/spec.py +35 -0
  102. digitalhub/entities/secret/status.py +9 -0
  103. digitalhub/entities/task/__init__.py +0 -0
  104. digitalhub/entities/task/builder.py +74 -0
  105. digitalhub/entities/task/crud.py +241 -0
  106. digitalhub/entities/task/entity.py +135 -0
  107. digitalhub/entities/task/models.py +199 -0
  108. digitalhub/entities/task/spec.py +51 -0
  109. digitalhub/entities/task/status.py +9 -0
  110. digitalhub/entities/utils.py +184 -0
  111. digitalhub/entities/workflow/__init__.py +0 -0
  112. digitalhub/entities/workflow/builder.py +91 -0
  113. digitalhub/entities/workflow/crud.py +304 -0
  114. digitalhub/entities/workflow/entity.py +77 -0
  115. digitalhub/entities/workflow/spec.py +15 -0
  116. digitalhub/entities/workflow/status.py +9 -0
  117. digitalhub/readers/__init__.py +0 -0
  118. digitalhub/readers/builder.py +54 -0
  119. digitalhub/readers/objects/__init__.py +0 -0
  120. digitalhub/readers/objects/base.py +70 -0
  121. digitalhub/readers/objects/pandas.py +207 -0
  122. digitalhub/readers/registry.py +15 -0
  123. digitalhub/registry/__init__.py +0 -0
  124. digitalhub/registry/models.py +87 -0
  125. digitalhub/registry/registry.py +74 -0
  126. digitalhub/registry/utils.py +150 -0
  127. digitalhub/runtimes/__init__.py +0 -0
  128. digitalhub/runtimes/base.py +164 -0
  129. digitalhub/runtimes/builder.py +53 -0
  130. digitalhub/runtimes/kind_registry.py +170 -0
  131. digitalhub/stores/__init__.py +0 -0
  132. digitalhub/stores/builder.py +257 -0
  133. digitalhub/stores/objects/__init__.py +0 -0
  134. digitalhub/stores/objects/base.py +189 -0
  135. digitalhub/stores/objects/local.py +230 -0
  136. digitalhub/stores/objects/remote.py +143 -0
  137. digitalhub/stores/objects/s3.py +563 -0
  138. digitalhub/stores/objects/sql.py +328 -0
  139. digitalhub/utils/__init__.py +0 -0
  140. digitalhub/utils/data_utils.py +127 -0
  141. digitalhub/utils/env_utils.py +123 -0
  142. digitalhub/utils/exceptions.py +55 -0
  143. digitalhub/utils/file_utils.py +204 -0
  144. digitalhub/utils/generic_utils.py +207 -0
  145. digitalhub/utils/git_utils.py +148 -0
  146. digitalhub/utils/io_utils.py +79 -0
  147. digitalhub/utils/logger.py +17 -0
  148. digitalhub/utils/uri_utils.py +56 -0
  149. {digitalhub-0.8.0b0.dist-info → digitalhub-0.8.0b2.dist-info}/METADATA +27 -12
  150. digitalhub-0.8.0b2.dist-info/RECORD +161 -0
  151. test/test_crud_artifacts.py +1 -1
  152. test/test_crud_dataitems.py +1 -1
  153. test/test_crud_functions.py +1 -1
  154. test/test_crud_runs.py +1 -1
  155. test/test_crud_tasks.py +1 -1
  156. digitalhub-0.8.0b0.dist-info/RECORD +0 -14
  157. {digitalhub-0.8.0b0.dist-info → digitalhub-0.8.0b2.dist-info}/LICENSE.txt +0 -0
  158. {digitalhub-0.8.0b0.dist-info → digitalhub-0.8.0b2.dist-info}/WHEEL +0 -0
  159. {digitalhub-0.8.0b0.dist-info → digitalhub-0.8.0b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,132 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from abc import ABCMeta, abstractmethod
5
+
6
+ from digitalhub.entities._base.base import ModelObj
7
+
8
+ if typing.TYPE_CHECKING:
9
+ from digitalhub.entities._base.metadata import Metadata
10
+ from digitalhub.entities._base.spec.base import Spec
11
+ from digitalhub.entities._base.status.base import Status
12
+
13
+
14
+ class Entity(ModelObj, metaclass=ABCMeta):
15
+ """
16
+ Abstract class for entities.
17
+
18
+ An entity is a collection of metadata, specification and status
19
+ representing a variety of objects handled by Digitalhub.
20
+ """
21
+
22
+ # Entity type
23
+ # Need to be set in subclasses
24
+ ENTITY_TYPE: str
25
+
26
+ # Attributes to render as dict. Need to be expanded in subclasses.
27
+ _obj_attr = ["kind", "metadata", "spec", "status", "user", "key"]
28
+
29
+ def __init__(
30
+ self,
31
+ kind: str,
32
+ metadata: Metadata,
33
+ spec: Spec,
34
+ status: Status,
35
+ user: str | None = None,
36
+ ) -> None:
37
+ self.kind = kind
38
+ self.metadata = metadata
39
+ self.spec = spec
40
+ self.status = status
41
+ self.user = user
42
+
43
+ # Need to be set in subclasses
44
+ self.key: str
45
+
46
+ @abstractmethod
47
+ def save(self, update: bool = False) -> Entity:
48
+ """
49
+ Abstract save method.
50
+ """
51
+
52
+ @abstractmethod
53
+ def refresh(self) -> Entity:
54
+ """
55
+ Abstract refresh method.
56
+ """
57
+
58
+ def _update_attributes(self, obj: dict) -> None:
59
+ """
60
+ Update attributes.
61
+
62
+ Parameters
63
+ ----------
64
+ obj : dict
65
+ Mapping representation of object.
66
+
67
+ Returns
68
+ -------
69
+ None
70
+ """
71
+ new_obj = self.from_dict(obj)
72
+ self.metadata = new_obj.metadata
73
+ self.spec = new_obj.spec
74
+ self.status = new_obj.status
75
+ self.user = new_obj.user
76
+
77
+ @abstractmethod
78
+ def export(self, filename: str | None = None) -> str:
79
+ """
80
+ Abstract export method.
81
+ """
82
+
83
+ def to_dict(self) -> dict:
84
+ """
85
+ Override default to_dict method to add the possibility to exclude
86
+ some attributes. This requires to set a list of _obj_attr
87
+ attributes in the subclass.
88
+
89
+ Returns
90
+ -------
91
+ dict
92
+ A dictionary containing the attributes of the entity instance.
93
+ """
94
+ return {k: v for k, v in super().to_dict().items() if k in self._obj_attr}
95
+
96
+ @classmethod
97
+ def from_dict(cls, obj: dict, validate: bool = True) -> Entity:
98
+ """
99
+ Create a new object from dictionary.
100
+
101
+ Parameters
102
+ ----------
103
+ obj : dict
104
+ Dictionary to create object from.
105
+ validate : bool
106
+ Flag to indicate if arguments validation against a pydantic schema must be ignored.
107
+
108
+ Returns
109
+ -------
110
+ Self
111
+ Self instance.
112
+ """
113
+ parsed_dict = cls._parse_dict(obj, validate=validate)
114
+ return cls(**parsed_dict)
115
+
116
+ @staticmethod
117
+ @abstractmethod
118
+ def _parse_dict(obj: dict, validate: bool = True) -> dict:
119
+ """
120
+ Abstract method to parse dictionary.
121
+ """
122
+
123
+ def __repr__(self) -> str:
124
+ """
125
+ Return string representation of the entity object.
126
+
127
+ Returns
128
+ -------
129
+ str
130
+ A string representing the entity instance.
131
+ """
132
+ return str(self.to_dict())
@@ -0,0 +1,118 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from digitalhub.context.builder import get_context
6
+ from digitalhub.entities._base.crud import create_entity_api_ctx, read_entity_api_ctx, update_entity_api_ctx
7
+ from digitalhub.entities._base.entity.base import Entity
8
+ from digitalhub.utils.generic_utils import get_timestamp
9
+
10
+ if typing.TYPE_CHECKING:
11
+ from digitalhub.context.context import Context
12
+ from digitalhub.entities._base.metadata import Metadata
13
+ from digitalhub.entities._base.spec.base import Spec
14
+ from digitalhub.entities._base.status.base import Status
15
+
16
+
17
+ class ContextEntity(Entity):
18
+ def __init__(
19
+ self,
20
+ project: str,
21
+ kind: str,
22
+ metadata: Metadata,
23
+ spec: Spec,
24
+ status: Status,
25
+ user: str | None = None,
26
+ ) -> None:
27
+ super().__init__(kind, metadata, spec, status, user)
28
+ self.project = project
29
+ self._obj_attr.extend(["project"])
30
+
31
+ ##############################
32
+ # Save / Refresh / Export
33
+ ##############################
34
+
35
+ def save(self, update: bool = False) -> ContextEntity:
36
+ """
37
+ Save or update the entity into the backend.
38
+
39
+ Parameters
40
+ ----------
41
+ update : bool
42
+ Flag to indicate update.
43
+
44
+ Returns
45
+ -------
46
+ ContextEntity
47
+ Entity saved.
48
+ """
49
+ obj = self.to_dict()
50
+ if not update:
51
+ return self._save(obj)
52
+ return self._update(obj)
53
+
54
+ def _save(self, obj: dict) -> ContextEntity:
55
+ """
56
+ Save entity into backend.
57
+
58
+ Parameters
59
+ ----------
60
+ obj : dict
61
+ Object instance as dictionary.
62
+
63
+ Returns
64
+ -------
65
+ ContextEntity
66
+ Entity saved.
67
+ """
68
+ new_obj = create_entity_api_ctx(self.project, self.ENTITY_TYPE, obj)
69
+ self._update_attributes(new_obj)
70
+ return self
71
+
72
+ def _update(self, obj: dict) -> ContextEntity:
73
+ """
74
+ Update entity in backend.
75
+
76
+ Parameters
77
+ ----------
78
+ obj : dict
79
+ Object instance as dictionary.
80
+
81
+ Returns
82
+ -------
83
+ ContextEntity
84
+ Entity updated.
85
+ """
86
+ if self._context().local:
87
+ self.metadata.updated = obj["metadata"]["updated"] = get_timestamp()
88
+ new_obj = update_entity_api_ctx(self.project, self.ENTITY_TYPE, self.id, obj)
89
+ self._update_attributes(new_obj)
90
+ return self
91
+
92
+ def refresh(self) -> ContextEntity:
93
+ """
94
+ Refresh object from backend.
95
+
96
+ Returns
97
+ -------
98
+ ContextEntity
99
+ Entity refreshed.
100
+ """
101
+ new_obj = read_entity_api_ctx(self.key)
102
+ self._update_attributes(new_obj)
103
+ return self
104
+
105
+ ##############################
106
+ # Context
107
+ ##############################
108
+
109
+ def _context(self) -> Context:
110
+ """
111
+ Get context.
112
+
113
+ Returns
114
+ -------
115
+ Context
116
+ Context object.
117
+ """
118
+ return get_context(self.project)
@@ -0,0 +1,380 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from digitalhub.entities._base.crud import list_entity_api_ctx
6
+ from digitalhub.entities._base.entity.versioned import VersionedEntity
7
+ from digitalhub.entities.entity_types import EntityTypes
8
+ from digitalhub.entities.run.crud import delete_run, get_run, list_runs
9
+ from digitalhub.entities.task.crud import delete_task, task_from_dict, task_from_parameters
10
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError
11
+
12
+ if typing.TYPE_CHECKING:
13
+ from digitalhub.entities._base.metadata import Metadata
14
+ from digitalhub.entities._base.spec.base import Spec
15
+ from digitalhub.entities._base.status.base import Status
16
+ from digitalhub.entities.run.entity import Run
17
+ from digitalhub.entities.task.entity import Task
18
+
19
+
20
+ class ExecutableEntity(VersionedEntity):
21
+ """
22
+ A class representing an entity that can be executed.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ project: str,
28
+ name: str,
29
+ uuid: str,
30
+ kind: str,
31
+ metadata: Metadata,
32
+ spec: Spec,
33
+ status: Status,
34
+ user: str | None = None,
35
+ ) -> None:
36
+ super().__init__(project, name, uuid, kind, metadata, spec, status, user)
37
+
38
+ # Initialize tasks
39
+ self._tasks: dict[str, Task] = {}
40
+
41
+ ##############################
42
+ # Helpers
43
+ ##############################
44
+
45
+ def _get_executable_string(self) -> str:
46
+ """
47
+ Get executable string.
48
+
49
+ Returns
50
+ -------
51
+ str
52
+ Executable string.
53
+ """
54
+ return f"{self.kind}://{self.project}/{self.name}:{self.id}"
55
+
56
+ ##############################
57
+ # Tasks
58
+ ##############################
59
+
60
+ def _get_or_create_task(self, kind: str, **kwargs) -> Task:
61
+ """
62
+ Get or create task.
63
+
64
+ Parameters
65
+ ----------
66
+ kind : str
67
+ Kind the object.
68
+
69
+ Returns
70
+ -------
71
+ Task
72
+ Task.
73
+ """
74
+ if self._tasks.get(kind) is None:
75
+ return self.new_task(kind)
76
+ return self._tasks[kind]
77
+
78
+ def import_tasks(self, tasks: list[dict]) -> None:
79
+ """
80
+ Import tasks from yaml.
81
+
82
+ Parameters
83
+ ----------
84
+ tasks : list[dict]
85
+ List of tasks to import.
86
+
87
+ Returns
88
+ -------
89
+ None
90
+ """
91
+ # Loop over tasks list, in the case where the function
92
+ # is imported from local file.
93
+ for task in tasks:
94
+ # If task is not a dictionary, skip it
95
+ if not isinstance(task, dict):
96
+ continue
97
+
98
+ # Create a new object from dictionary.
99
+ # the form in which tasks are stored in function
100
+ # status
101
+ task_obj = task_from_dict(task)
102
+
103
+ # Try to save it in backend to been able to use
104
+ # it for launching runs. In fact, tasks must be
105
+ # persisted in backend to be able to launch runs.
106
+ # Ignore if task already exists
107
+ try:
108
+ task_obj.save()
109
+ except EntityAlreadyExistsError:
110
+ pass
111
+
112
+ # Set task if function is the same. Overwrite
113
+ # status task dict with the new task object
114
+ if task_obj.spec.function == self._get_executable_string():
115
+ self._tasks[task_obj.kind] = task_obj
116
+
117
+ def new_task(self, task_kind: str, **kwargs) -> Task:
118
+ """
119
+ Create new task. If the task already exists, update it.
120
+
121
+ Parameters
122
+ ----------
123
+ task_kind : str
124
+ Kind the object.
125
+ **kwargs : dict
126
+ Keyword arguments.
127
+
128
+ Returns
129
+ -------
130
+ Task
131
+ New task.
132
+ """
133
+ self._raise_if_exists(task_kind)
134
+
135
+ if kwargs is None:
136
+ kwargs = {}
137
+
138
+ # Override kwargs
139
+ kwargs["project"] = self.project
140
+ kwargs["function"] = self._get_executable_string()
141
+ kwargs["kind"] = task_kind
142
+
143
+ # Create object instance
144
+ task = task_from_parameters(**kwargs)
145
+ task.save()
146
+
147
+ self._tasks[task_kind] = task
148
+ return task
149
+
150
+ def update_task(self, kind: str, **kwargs) -> Task:
151
+ """
152
+ Update task.
153
+
154
+ Parameters
155
+ ----------
156
+ kind : str
157
+ Kind the object.
158
+ **kwargs : dict
159
+ Keyword arguments.
160
+
161
+ Returns
162
+ -------
163
+ Task
164
+ Task.
165
+ """
166
+ self._raise_if_not_exists(kind)
167
+
168
+ if kwargs is None:
169
+ kwargs = {}
170
+
171
+ # Update kwargs
172
+ kwargs["project"] = self.project
173
+ kwargs["kind"] = kind
174
+ kwargs["function"] = self._get_executable_string()
175
+ kwargs["uuid"] = self._tasks[kind].id
176
+
177
+ # Update task
178
+ task = task_from_parameters(**kwargs)
179
+ task.save(update=True)
180
+ self._tasks[kind] = task
181
+ return task
182
+
183
+ def get_task(self, kind: str) -> Task:
184
+ """
185
+ Get task.
186
+
187
+ Parameters
188
+ ----------
189
+ kind : str
190
+ Kind the object.
191
+
192
+ Returns
193
+ -------
194
+ Task
195
+ Task.
196
+
197
+ Raises
198
+ ------
199
+ EntityError
200
+ If task is not created.
201
+ """
202
+ self._raise_if_not_exists(kind)
203
+ return self._tasks[kind]
204
+
205
+ def delete_task(self, kind: str, cascade: bool = True) -> dict:
206
+ """
207
+ Delete task.
208
+
209
+ Parameters
210
+ ----------
211
+ kind : str
212
+ Kind the object.
213
+ cascade : bool
214
+ Flag to determine if cascade deletion must be performed.
215
+
216
+ Returns
217
+ -------
218
+ dict
219
+ Response from backend.
220
+ """
221
+ resp = delete_task(self._tasks[kind].key, cascade=cascade)
222
+ self._tasks.pop(kind, None)
223
+ return resp
224
+
225
+ def _check_task_in_backend(self, kind: str) -> bool:
226
+ """
227
+ Check if task exists in backend.
228
+
229
+ Parameters
230
+ ----------
231
+ kind : str
232
+ Kind the object.
233
+
234
+ Returns
235
+ -------
236
+ bool
237
+ Flag to determine if task exists in backend.
238
+ """
239
+ # List tasks from backend filtered by function and kind
240
+ params = {"function": self._get_executable_string(), "kind": kind}
241
+ resp = list_entity_api_ctx(self.project, EntityTypes.TASK.value, params=params)
242
+ if not resp:
243
+ return False
244
+ return True
245
+
246
+ def _raise_if_exists(self, kind: str) -> None:
247
+ """
248
+ Raise error if task is created.
249
+
250
+ Parameters
251
+ ----------
252
+ kind : str
253
+ Kind the object.
254
+
255
+ Returns
256
+ -------
257
+ None
258
+
259
+ Raises
260
+ ------
261
+ EntityError
262
+ If task already exists.
263
+ """
264
+ if self._check_task_in_backend(kind):
265
+ raise EntityError(f"Task '{kind}' already exists.")
266
+
267
+ def _raise_if_not_exists(self, kind: str) -> None:
268
+ """
269
+ Raise error if task is not created.
270
+
271
+ Parameters
272
+ ----------
273
+ kind : str
274
+ Kind the object.
275
+
276
+ Returns
277
+ -------
278
+ None
279
+
280
+ Raises
281
+ ------
282
+ EntityError
283
+ If task does not exist.
284
+ """
285
+ if self._tasks.get(kind) is None:
286
+ raise EntityError(f"Task '{kind}' does not exist.")
287
+
288
+ ##############################
289
+ # Runs
290
+ ##############################
291
+
292
+ def get_run(
293
+ self,
294
+ identifier: str,
295
+ **kwargs,
296
+ ) -> Run:
297
+ """
298
+ Get object from backend.
299
+
300
+ Parameters
301
+ ----------
302
+ identifier : str
303
+ Entity key (store://...) or entity ID.
304
+ **kwargs : dict
305
+ Parameters to pass to the API call.
306
+
307
+ Returns
308
+ -------
309
+ Run
310
+ Object instance.
311
+
312
+ Examples
313
+ --------
314
+ Using entity key:
315
+ >>> obj = executable.get_run("store://my-secret-key")
316
+
317
+ Using entity ID:
318
+ >>> obj = executable.get_run("123")
319
+ """
320
+ obj = get_run(
321
+ identifier=identifier,
322
+ project=self.project,
323
+ **kwargs,
324
+ )
325
+ self.refresh()
326
+ return obj
327
+
328
+ def list_runs(self, **kwargs) -> list[Run]:
329
+ """
330
+ List all runs from backend.
331
+
332
+ Parameters
333
+ ----------
334
+ **kwargs : dict
335
+ Parameters to pass to the API call.
336
+
337
+ Returns
338
+ -------
339
+ list[Run]
340
+ List of object instances.
341
+
342
+ Examples
343
+ --------
344
+ >>> objs = executable.list_runs()
345
+ """
346
+ if kwargs is None:
347
+ kwargs = {}
348
+ kwargs["params"] = {"function": self._get_executable_string()}
349
+ return list_runs(self.project, **kwargs)
350
+
351
+ def delete_run(
352
+ self,
353
+ identifier: str,
354
+ **kwargs,
355
+ ) -> None:
356
+ """
357
+ Delete run from backend.
358
+
359
+ Parameters
360
+ ----------
361
+ identifier : str
362
+ Entity key (store://...) or entity ID.
363
+ **kwargs : dict
364
+ Parameters to pass to the API call.
365
+
366
+ Returns
367
+ -------
368
+ dict
369
+ Response from backend.
370
+
371
+ Examples
372
+ --------
373
+ >>> executable.delete_run("store://my-run-key")
374
+
375
+ """
376
+ delete_run(
377
+ identifier=identifier,
378
+ project=self.project,
379
+ **kwargs,
380
+ )