digitalhub 0.7.0b2__py3-none-any.whl → 0.8.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 (232) hide show
  1. digitalhub/__init__.py +63 -93
  2. digitalhub/client/__init__.py +0 -0
  3. digitalhub/client/_base/__init__.py +0 -0
  4. digitalhub/client/_base/client.py +56 -0
  5. digitalhub/client/api.py +63 -0
  6. digitalhub/client/builder.py +50 -0
  7. digitalhub/client/dhcore/__init__.py +0 -0
  8. digitalhub/client/dhcore/client.py +669 -0
  9. digitalhub/client/dhcore/env.py +21 -0
  10. digitalhub/client/dhcore/models.py +46 -0
  11. digitalhub/client/dhcore/utils.py +111 -0
  12. digitalhub/client/local/__init__.py +0 -0
  13. digitalhub/client/local/client.py +533 -0
  14. digitalhub/context/__init__.py +0 -0
  15. digitalhub/context/api.py +93 -0
  16. digitalhub/context/builder.py +94 -0
  17. digitalhub/context/context.py +136 -0
  18. digitalhub/datastores/__init__.py +0 -0
  19. digitalhub/datastores/_base/__init__.py +0 -0
  20. digitalhub/datastores/_base/datastore.py +85 -0
  21. digitalhub/datastores/api.py +37 -0
  22. digitalhub/datastores/builder.py +110 -0
  23. digitalhub/datastores/local/__init__.py +0 -0
  24. digitalhub/datastores/local/datastore.py +50 -0
  25. digitalhub/datastores/remote/__init__.py +0 -0
  26. digitalhub/datastores/remote/datastore.py +31 -0
  27. digitalhub/datastores/s3/__init__.py +0 -0
  28. digitalhub/datastores/s3/datastore.py +46 -0
  29. digitalhub/datastores/sql/__init__.py +0 -0
  30. digitalhub/datastores/sql/datastore.py +68 -0
  31. digitalhub/entities/__init__.py +0 -0
  32. digitalhub/entities/_base/__init__.py +0 -0
  33. digitalhub/entities/_base/_base/__init__.py +0 -0
  34. digitalhub/entities/_base/_base/entity.py +82 -0
  35. digitalhub/entities/_base/api_utils.py +620 -0
  36. digitalhub/entities/_base/context/__init__.py +0 -0
  37. digitalhub/entities/_base/context/entity.py +118 -0
  38. digitalhub/entities/_base/crud.py +468 -0
  39. digitalhub/entities/_base/entity/__init__.py +0 -0
  40. digitalhub/entities/_base/entity/_constructors/__init__.py +0 -0
  41. digitalhub/entities/_base/entity/_constructors/metadata.py +44 -0
  42. digitalhub/entities/_base/entity/_constructors/name.py +31 -0
  43. digitalhub/entities/_base/entity/_constructors/spec.py +33 -0
  44. digitalhub/entities/_base/entity/_constructors/status.py +52 -0
  45. digitalhub/entities/_base/entity/_constructors/uuid.py +26 -0
  46. digitalhub/entities/_base/entity/builder.py +175 -0
  47. digitalhub/entities/_base/entity/entity.py +106 -0
  48. digitalhub/entities/_base/entity/metadata.py +59 -0
  49. digitalhub/entities/_base/entity/spec.py +58 -0
  50. digitalhub/entities/_base/entity/status.py +43 -0
  51. digitalhub/entities/_base/executable/__init__.py +0 -0
  52. digitalhub/entities/_base/executable/entity.py +405 -0
  53. digitalhub/entities/_base/material/__init__.py +0 -0
  54. digitalhub/entities/_base/material/entity.py +214 -0
  55. digitalhub/entities/_base/material/spec.py +22 -0
  56. digitalhub/entities/_base/material/status.py +49 -0
  57. digitalhub/entities/_base/runtime_entity/__init__.py +0 -0
  58. digitalhub/entities/_base/runtime_entity/builder.py +106 -0
  59. digitalhub/entities/_base/unversioned/__init__.py +0 -0
  60. digitalhub/entities/_base/unversioned/builder.py +66 -0
  61. digitalhub/entities/_base/unversioned/entity.py +49 -0
  62. digitalhub/entities/_base/versioned/__init__.py +0 -0
  63. digitalhub/entities/_base/versioned/builder.py +68 -0
  64. digitalhub/entities/_base/versioned/entity.py +53 -0
  65. digitalhub/entities/artifact/__init__.py +0 -0
  66. digitalhub/entities/artifact/_base/__init__.py +0 -0
  67. digitalhub/entities/artifact/_base/builder.py +86 -0
  68. digitalhub/entities/artifact/_base/entity.py +39 -0
  69. digitalhub/entities/artifact/_base/spec.py +15 -0
  70. digitalhub/entities/artifact/_base/status.py +9 -0
  71. digitalhub/entities/artifact/artifact/__init__.py +0 -0
  72. digitalhub/entities/artifact/artifact/builder.py +18 -0
  73. digitalhub/entities/artifact/artifact/entity.py +32 -0
  74. digitalhub/entities/artifact/artifact/spec.py +27 -0
  75. digitalhub/entities/artifact/artifact/status.py +15 -0
  76. digitalhub/entities/artifact/crud.py +332 -0
  77. digitalhub/entities/builders.py +63 -0
  78. digitalhub/entities/dataitem/__init__.py +0 -0
  79. digitalhub/entities/dataitem/_base/__init__.py +0 -0
  80. digitalhub/entities/dataitem/_base/builder.py +86 -0
  81. digitalhub/entities/dataitem/_base/entity.py +75 -0
  82. digitalhub/entities/dataitem/_base/spec.py +15 -0
  83. digitalhub/entities/dataitem/_base/status.py +20 -0
  84. digitalhub/entities/dataitem/crud.py +372 -0
  85. digitalhub/entities/dataitem/dataitem/__init__.py +0 -0
  86. digitalhub/entities/dataitem/dataitem/builder.py +18 -0
  87. digitalhub/entities/dataitem/dataitem/entity.py +32 -0
  88. digitalhub/entities/dataitem/dataitem/spec.py +15 -0
  89. digitalhub/entities/dataitem/dataitem/status.py +9 -0
  90. digitalhub/entities/dataitem/iceberg/__init__.py +0 -0
  91. digitalhub/entities/dataitem/iceberg/builder.py +18 -0
  92. digitalhub/entities/dataitem/iceberg/entity.py +32 -0
  93. digitalhub/entities/dataitem/iceberg/spec.py +15 -0
  94. digitalhub/entities/dataitem/iceberg/status.py +9 -0
  95. digitalhub/entities/dataitem/table/__init__.py +0 -0
  96. digitalhub/entities/dataitem/table/builder.py +18 -0
  97. digitalhub/entities/dataitem/table/entity.py +146 -0
  98. digitalhub/entities/dataitem/table/models.py +62 -0
  99. digitalhub/entities/dataitem/table/spec.py +25 -0
  100. digitalhub/entities/dataitem/table/status.py +9 -0
  101. digitalhub/entities/function/__init__.py +0 -0
  102. digitalhub/entities/function/_base/__init__.py +0 -0
  103. digitalhub/entities/function/_base/builder.py +79 -0
  104. digitalhub/entities/function/_base/entity.py +98 -0
  105. digitalhub/entities/function/_base/models.py +118 -0
  106. digitalhub/entities/function/_base/spec.py +15 -0
  107. digitalhub/entities/function/_base/status.py +9 -0
  108. digitalhub/entities/function/crud.py +279 -0
  109. digitalhub/entities/model/__init__.py +0 -0
  110. digitalhub/entities/model/_base/__init__.py +0 -0
  111. digitalhub/entities/model/_base/builder.py +86 -0
  112. digitalhub/entities/model/_base/entity.py +34 -0
  113. digitalhub/entities/model/_base/spec.py +49 -0
  114. digitalhub/entities/model/_base/status.py +9 -0
  115. digitalhub/entities/model/crud.py +331 -0
  116. digitalhub/entities/model/huggingface/__init__.py +0 -0
  117. digitalhub/entities/model/huggingface/builder.py +18 -0
  118. digitalhub/entities/model/huggingface/entity.py +32 -0
  119. digitalhub/entities/model/huggingface/spec.py +36 -0
  120. digitalhub/entities/model/huggingface/status.py +9 -0
  121. digitalhub/entities/model/mlflow/__init__.py +0 -0
  122. digitalhub/entities/model/mlflow/builder.py +18 -0
  123. digitalhub/entities/model/mlflow/entity.py +32 -0
  124. digitalhub/entities/model/mlflow/models.py +26 -0
  125. digitalhub/entities/model/mlflow/spec.py +44 -0
  126. digitalhub/entities/model/mlflow/status.py +9 -0
  127. digitalhub/entities/model/mlflow/utils.py +81 -0
  128. digitalhub/entities/model/model/__init__.py +0 -0
  129. digitalhub/entities/model/model/builder.py +18 -0
  130. digitalhub/entities/model/model/entity.py +32 -0
  131. digitalhub/entities/model/model/spec.py +15 -0
  132. digitalhub/entities/model/model/status.py +9 -0
  133. digitalhub/entities/model/sklearn/__init__.py +0 -0
  134. digitalhub/entities/model/sklearn/builder.py +18 -0
  135. digitalhub/entities/model/sklearn/entity.py +32 -0
  136. digitalhub/entities/model/sklearn/spec.py +15 -0
  137. digitalhub/entities/model/sklearn/status.py +9 -0
  138. digitalhub/entities/project/__init__.py +0 -0
  139. digitalhub/entities/project/_base/__init__.py +0 -0
  140. digitalhub/entities/project/_base/builder.py +128 -0
  141. digitalhub/entities/project/_base/entity.py +2078 -0
  142. digitalhub/entities/project/_base/spec.py +50 -0
  143. digitalhub/entities/project/_base/status.py +9 -0
  144. digitalhub/entities/project/crud.py +357 -0
  145. digitalhub/entities/run/__init__.py +0 -0
  146. digitalhub/entities/run/_base/__init__.py +0 -0
  147. digitalhub/entities/run/_base/builder.py +94 -0
  148. digitalhub/entities/run/_base/entity.py +307 -0
  149. digitalhub/entities/run/_base/spec.py +50 -0
  150. digitalhub/entities/run/_base/status.py +9 -0
  151. digitalhub/entities/run/crud.py +219 -0
  152. digitalhub/entities/secret/__init__.py +0 -0
  153. digitalhub/entities/secret/_base/__init__.py +0 -0
  154. digitalhub/entities/secret/_base/builder.py +81 -0
  155. digitalhub/entities/secret/_base/entity.py +74 -0
  156. digitalhub/entities/secret/_base/spec.py +35 -0
  157. digitalhub/entities/secret/_base/status.py +9 -0
  158. digitalhub/entities/secret/crud.py +290 -0
  159. digitalhub/entities/task/__init__.py +0 -0
  160. digitalhub/entities/task/_base/__init__.py +0 -0
  161. digitalhub/entities/task/_base/builder.py +91 -0
  162. digitalhub/entities/task/_base/entity.py +136 -0
  163. digitalhub/entities/task/_base/models.py +208 -0
  164. digitalhub/entities/task/_base/spec.py +53 -0
  165. digitalhub/entities/task/_base/status.py +9 -0
  166. digitalhub/entities/task/crud.py +228 -0
  167. digitalhub/entities/utils/__init__.py +0 -0
  168. digitalhub/entities/utils/api.py +346 -0
  169. digitalhub/entities/utils/entity_types.py +19 -0
  170. digitalhub/entities/utils/state.py +31 -0
  171. digitalhub/entities/utils/utils.py +202 -0
  172. digitalhub/entities/workflow/__init__.py +0 -0
  173. digitalhub/entities/workflow/_base/__init__.py +0 -0
  174. digitalhub/entities/workflow/_base/builder.py +79 -0
  175. digitalhub/entities/workflow/_base/entity.py +74 -0
  176. digitalhub/entities/workflow/_base/spec.py +15 -0
  177. digitalhub/entities/workflow/_base/status.py +9 -0
  178. digitalhub/entities/workflow/crud.py +278 -0
  179. digitalhub/factory/__init__.py +0 -0
  180. digitalhub/factory/api.py +277 -0
  181. digitalhub/factory/factory.py +268 -0
  182. digitalhub/factory/utils.py +90 -0
  183. digitalhub/readers/__init__.py +0 -0
  184. digitalhub/readers/_base/__init__.py +0 -0
  185. digitalhub/readers/_base/builder.py +26 -0
  186. digitalhub/readers/_base/reader.py +70 -0
  187. digitalhub/readers/api.py +80 -0
  188. digitalhub/readers/factory.py +133 -0
  189. digitalhub/readers/pandas/__init__.py +0 -0
  190. digitalhub/readers/pandas/builder.py +29 -0
  191. digitalhub/readers/pandas/reader.py +207 -0
  192. digitalhub/runtimes/__init__.py +0 -0
  193. digitalhub/runtimes/_base.py +102 -0
  194. digitalhub/runtimes/builder.py +32 -0
  195. digitalhub/stores/__init__.py +0 -0
  196. digitalhub/stores/_base/__init__.py +0 -0
  197. digitalhub/stores/_base/store.py +189 -0
  198. digitalhub/stores/api.py +54 -0
  199. digitalhub/stores/builder.py +211 -0
  200. digitalhub/stores/local/__init__.py +0 -0
  201. digitalhub/stores/local/store.py +230 -0
  202. digitalhub/stores/remote/__init__.py +0 -0
  203. digitalhub/stores/remote/store.py +143 -0
  204. digitalhub/stores/s3/__init__.py +0 -0
  205. digitalhub/stores/s3/store.py +563 -0
  206. digitalhub/stores/sql/__init__.py +0 -0
  207. digitalhub/stores/sql/store.py +328 -0
  208. digitalhub/utils/__init__.py +0 -0
  209. digitalhub/utils/data_utils.py +127 -0
  210. digitalhub/utils/exceptions.py +67 -0
  211. digitalhub/utils/file_utils.py +204 -0
  212. digitalhub/utils/generic_utils.py +183 -0
  213. digitalhub/utils/git_utils.py +148 -0
  214. digitalhub/utils/io_utils.py +116 -0
  215. digitalhub/utils/logger.py +17 -0
  216. digitalhub/utils/s3_utils.py +58 -0
  217. digitalhub/utils/uri_utils.py +56 -0
  218. {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/METADATA +30 -13
  219. digitalhub-0.8.0.dist-info/RECORD +231 -0
  220. {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/WHEEL +1 -1
  221. test/local/CRUD/test_artifacts.py +96 -0
  222. test/local/CRUD/test_dataitems.py +96 -0
  223. test/local/CRUD/test_models.py +95 -0
  224. test/test_crud_functions.py +1 -1
  225. test/test_crud_runs.py +1 -1
  226. test/test_crud_tasks.py +1 -1
  227. digitalhub-0.7.0b2.dist-info/RECORD +0 -14
  228. test/test_crud_artifacts.py +0 -96
  229. test/test_crud_dataitems.py +0 -96
  230. {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/LICENSE.txt +0 -0
  231. {digitalhub-0.7.0b2.dist-info → digitalhub-0.8.0.dist-info}/top_level.txt +0 -0
  232. /test/{test_imports.py → local/imports/test_imports.py} +0 -0
@@ -0,0 +1,2078 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+ from digitalhub.client.api import get_client
8
+ from digitalhub.context.api import set_context
9
+ from digitalhub.entities._base.api_utils import (
10
+ create_entity_api_base,
11
+ read_entity_api_base,
12
+ read_entity_api_ctx,
13
+ update_entity_api_base,
14
+ )
15
+ from digitalhub.entities._base.crud import import_context_entity, import_executable_entity
16
+ from digitalhub.entities._base.entity.entity import Entity
17
+ from digitalhub.entities.artifact.crud import (
18
+ delete_artifact,
19
+ get_artifact,
20
+ get_artifact_versions,
21
+ import_artifact,
22
+ list_artifacts,
23
+ log_artifact,
24
+ new_artifact,
25
+ update_artifact,
26
+ )
27
+ from digitalhub.entities.dataitem.crud import (
28
+ delete_dataitem,
29
+ get_dataitem,
30
+ get_dataitem_versions,
31
+ import_dataitem,
32
+ list_dataitems,
33
+ log_dataitem,
34
+ new_dataitem,
35
+ update_dataitem,
36
+ )
37
+ from digitalhub.entities.function.crud import (
38
+ delete_function,
39
+ get_function,
40
+ get_function_versions,
41
+ import_function,
42
+ list_functions,
43
+ new_function,
44
+ update_function,
45
+ )
46
+ from digitalhub.entities.model.crud import (
47
+ delete_model,
48
+ get_model,
49
+ get_model_versions,
50
+ import_model,
51
+ list_models,
52
+ log_model,
53
+ new_model,
54
+ update_model,
55
+ )
56
+ from digitalhub.entities.run.crud import delete_run, get_run, list_runs
57
+ from digitalhub.entities.secret.crud import (
58
+ delete_secret,
59
+ get_secret,
60
+ get_secret_versions,
61
+ import_secret,
62
+ list_secrets,
63
+ new_secret,
64
+ update_secret,
65
+ )
66
+ from digitalhub.entities.utils.entity_types import EntityTypes
67
+ from digitalhub.entities.workflow.crud import (
68
+ delete_workflow,
69
+ get_workflow,
70
+ get_workflow_versions,
71
+ import_workflow,
72
+ list_workflows,
73
+ new_workflow,
74
+ update_workflow,
75
+ )
76
+ from digitalhub.factory.api import build_entity_from_dict
77
+ from digitalhub.utils.exceptions import BackendError, EntityAlreadyExistsError, EntityError
78
+ from digitalhub.utils.generic_utils import get_timestamp
79
+ from digitalhub.utils.io_utils import write_yaml
80
+ from digitalhub.utils.uri_utils import map_uri_scheme
81
+
82
+ if typing.TYPE_CHECKING:
83
+ from digitalhub.entities._base.entity.metadata import Metadata
84
+ from digitalhub.entities.artifact._base.entity import Artifact
85
+ from digitalhub.entities.dataitem._base.entity import Dataitem
86
+ from digitalhub.entities.function._base.entity import Function
87
+ from digitalhub.entities.model._base.entity import Model
88
+ from digitalhub.entities.project._base.spec import ProjectSpec
89
+ from digitalhub.entities.project._base.status import ProjectStatus
90
+ from digitalhub.entities.run._base.entity import Run
91
+ from digitalhub.entities.secret._base.entity import Secret
92
+ from digitalhub.entities.workflow._base.entity import Workflow
93
+
94
+
95
+ class Project(Entity):
96
+ """
97
+ A class representing a project.
98
+ """
99
+
100
+ ENTITY_TYPE = EntityTypes.PROJECT.value
101
+
102
+ def __init__(
103
+ self,
104
+ name: str,
105
+ kind: str,
106
+ metadata: Metadata,
107
+ spec: ProjectSpec,
108
+ status: ProjectStatus,
109
+ user: str | None = None,
110
+ local: bool = False,
111
+ ) -> None:
112
+ super().__init__(kind, metadata, spec, status, user)
113
+ self.id = name
114
+ self.name = name
115
+ self.key = f"store://{name}"
116
+ self.spec: ProjectSpec
117
+ self.status: ProjectStatus
118
+
119
+ # Add attributes to be used in the to_dict method
120
+ self._obj_attr.extend(["id", "name"])
121
+
122
+ # Set client
123
+ self._client = get_client(local)
124
+
125
+ # Set context
126
+ set_context(self)
127
+
128
+ ##############################
129
+ # Save / Refresh / Export
130
+ ##############################
131
+
132
+ def save(self, update: bool = False) -> Project:
133
+ """
134
+ Save entity into backend.
135
+
136
+ Parameters
137
+ ----------
138
+ update : bool
139
+ If True, the object will be updated.
140
+
141
+ Returns
142
+ -------
143
+ Project
144
+ Entity saved.
145
+ """
146
+ obj = self._refresh_to_dict()
147
+
148
+ if not update:
149
+ new_obj = create_entity_api_base(self._client, self.ENTITY_TYPE, obj)
150
+ new_obj["local"] = self._client.is_local()
151
+ self._update_attributes(new_obj)
152
+ return self
153
+
154
+ self.metadata.updated = obj["metadata"]["updated"] = get_timestamp()
155
+ new_obj = update_entity_api_base(self._client, self.ENTITY_TYPE, obj)
156
+ new_obj["local"] = self._client.is_local()
157
+ self._update_attributes(new_obj)
158
+ return self
159
+
160
+ def refresh(self) -> Project:
161
+ """
162
+ Refresh object from backend.
163
+
164
+ Returns
165
+ -------
166
+ Project
167
+ Project object.
168
+ """
169
+ new_obj = read_entity_api_base(self._client, self.ENTITY_TYPE, self.name)
170
+ new_obj["local"] = self._client.is_local()
171
+ self._update_attributes(new_obj)
172
+ return self
173
+
174
+ def export(self, filename: str | None = None) -> str:
175
+ """
176
+ Export object as a YAML file. If the objects are not embedded, the objects are
177
+ exported as a YAML file.
178
+
179
+ Parameters
180
+ ----------
181
+ filename : str
182
+ Name of the export YAML file. If not specified, the default value is used.
183
+
184
+ Returns
185
+ -------
186
+ str
187
+ Exported file.
188
+ """
189
+ obj = self._refresh_to_dict()
190
+
191
+ if filename is None:
192
+ filename = f"{self.kind}_{self.name}.yml"
193
+ pth = Path(self.spec.context) / filename
194
+ pth.parent.mkdir(parents=True, exist_ok=True)
195
+
196
+ obj = self._export_not_embedded(obj)
197
+ write_yaml(pth, obj)
198
+ return str(pth)
199
+
200
+ def _refresh_to_dict(self) -> dict:
201
+ """
202
+ Try to refresh object to collect entities related to project.
203
+
204
+ Returns
205
+ -------
206
+ dict
207
+ Entity object in dictionary format.
208
+ """
209
+ try:
210
+ return self.refresh().to_dict()
211
+ except BackendError:
212
+ return self.to_dict()
213
+
214
+ def _export_not_embedded(self, obj: dict) -> dict:
215
+ """
216
+ Export project objects if not embedded.
217
+
218
+ Parameters
219
+ ----------
220
+ obj : dict
221
+ Project object in dictionary format.
222
+
223
+ Returns
224
+ -------
225
+ dict
226
+ Updatated project object in dictionary format with referenced entities.
227
+ """
228
+ # Cycle over entity types
229
+ for entity_type in self._get_entity_types():
230
+ # Entity types are stored as a list of entities
231
+ for idx, entity in enumerate(obj.get("spec", {}).get(entity_type, [])):
232
+ # Export entity if not embedded is in metadata, else do nothing
233
+ if not self._is_embedded(entity):
234
+ # Get entity object from backend
235
+ obj_dict: dict = read_entity_api_ctx(entity["key"])
236
+
237
+ # Create from dict (not need to new method, we do not save to backend)
238
+ ent = build_entity_from_dict(obj_dict)
239
+
240
+ # Export and stor ref in object metadata inside project
241
+ pth = ent.export()
242
+ obj["spec"][entity_type][idx]["metadata"]["ref"] = pth
243
+
244
+ # Return updated object
245
+ return obj
246
+
247
+ def _import_entities(self, obj: dict) -> None:
248
+ """
249
+ Import project entities.
250
+
251
+ Parameters
252
+ ----------
253
+ obj : dict
254
+ Project object in dictionary format.
255
+
256
+ Returns
257
+ -------
258
+ None
259
+ """
260
+ entity_types = self._get_entity_types()
261
+
262
+ # Cycle over entity types
263
+ for entity_type in entity_types:
264
+ # Entity types are stored as a list of entities
265
+ for entity in obj.get("spec", {}).get(entity_type, []):
266
+ embedded = self._is_embedded(entity)
267
+ ref = entity["metadata"].get("ref")
268
+
269
+ # Import entity if not embedded and there is a ref
270
+ if not embedded and ref is not None:
271
+ # Import entity from local ref
272
+ if map_uri_scheme(ref) == "local":
273
+ try:
274
+ # Artifacts, Dataitems and Models
275
+ if entity_type in entity_types[:3]:
276
+ import_context_entity(ref)
277
+
278
+ # Functions and Workflows
279
+ elif entity_type in entity_types[3:]:
280
+ import_executable_entity(ref)
281
+
282
+ except FileNotFoundError:
283
+ msg = f"File not found: {ref}."
284
+ raise EntityError(msg)
285
+
286
+ # If entity is embedded, create it and try to save
287
+ elif embedded:
288
+ # It's possible that embedded field in metadata is not shown
289
+ if entity["metadata"].get("embedded") is None:
290
+ entity["metadata"]["embedded"] = True
291
+
292
+ try:
293
+ build_entity_from_dict(entity).save()
294
+ except EntityAlreadyExistsError:
295
+ pass
296
+
297
+ def _is_embedded(self, entity: dict) -> bool:
298
+ """
299
+ Check if entity is embedded.
300
+
301
+ Parameters
302
+ ----------
303
+ entity : dict
304
+ Entity in dictionary format.
305
+
306
+ Returns
307
+ -------
308
+ bool
309
+ True if entity is embedded.
310
+ """
311
+ metadata_embedded = entity["metadata"].get("embedded", False)
312
+ no_status = entity.get("status", None) is None
313
+ no_spec = entity.get("spec", None) is None
314
+ return metadata_embedded or not (no_status and no_spec)
315
+
316
+ def _get_entity_types(self) -> list[str]:
317
+ """
318
+ Get entity types.
319
+
320
+ Returns
321
+ -------
322
+ list
323
+ Entity types.
324
+ """
325
+ return [
326
+ f"{EntityTypes.ARTIFACT.value}s",
327
+ f"{EntityTypes.DATAITEM.value}s",
328
+ f"{EntityTypes.MODEL.value}s",
329
+ f"{EntityTypes.FUNCTION.value}s",
330
+ f"{EntityTypes.WORKFLOW.value}s",
331
+ ]
332
+
333
+ def run(self, workflow: str | None = None, **kwargs) -> Run:
334
+ """
335
+ Run workflow project.
336
+
337
+ Parameters
338
+ ----------
339
+ workflow : str
340
+ Workflow name.
341
+ **kwargs : dict
342
+ Keyword arguments passed to workflow.run().
343
+
344
+ Returns
345
+ -------
346
+ Run
347
+ Run instance.
348
+ """
349
+ self.refresh()
350
+
351
+ workflow = workflow if workflow is not None else "main"
352
+
353
+ for i in self.spec.workflows:
354
+ if workflow in [i["name"], i["key"]]:
355
+ entity = self.get_workflow(i["key"])
356
+ break
357
+ else:
358
+ msg = f"Workflow {workflow} not found."
359
+ raise EntityError(msg)
360
+
361
+ return entity.run(**kwargs)
362
+
363
+ ##############################
364
+ # Artifacts
365
+ ##############################
366
+
367
+ def new_artifact(
368
+ self,
369
+ name: str,
370
+ kind: str,
371
+ uuid: str | None = None,
372
+ description: str | None = None,
373
+ labels: list[str] | None = None,
374
+ embedded: bool = False,
375
+ path: str | None = None,
376
+ **kwargs,
377
+ ) -> Artifact:
378
+ """
379
+ Create a new object.
380
+
381
+ Parameters
382
+ ----------
383
+ name : str
384
+ Object name.
385
+ kind : str
386
+ Kind the object.
387
+ uuid : str
388
+ ID of the object.
389
+ description : str
390
+ Description of the object (human readable).
391
+ labels : list[str]
392
+ List of labels.
393
+ embedded : bool
394
+ Flag to determine if object spec must be embedded in project spec.
395
+ path : str
396
+ Object path on local file system or remote storage. It is also the destination path of upload() method.
397
+ **kwargs : dict
398
+ Spec keyword arguments.
399
+
400
+ Returns
401
+ -------
402
+ Artifact
403
+ Object instance.
404
+
405
+ Examples
406
+ --------
407
+ >>> obj = project.new_artifact(name="my-artifact",
408
+ >>> kind="artifact",
409
+ >>> path="s3://my-bucket/my-key")
410
+ """
411
+ obj = new_artifact(
412
+ project=self.name,
413
+ name=name,
414
+ kind=kind,
415
+ uuid=uuid,
416
+ description=description,
417
+ labels=labels,
418
+ embedded=embedded,
419
+ path=path,
420
+ **kwargs,
421
+ )
422
+ self.refresh()
423
+ return obj
424
+
425
+ def log_artifact(
426
+ self,
427
+ name: str,
428
+ kind: str,
429
+ source: str,
430
+ path: str | None = None,
431
+ **kwargs,
432
+ ) -> Artifact:
433
+ """
434
+ Create and upload an object.
435
+
436
+ Parameters
437
+ ----------
438
+ name : str
439
+ Object name.
440
+ kind : str
441
+ Kind the object.
442
+ source : str
443
+ Artifact location on local path.
444
+ path : str
445
+ Destination path of the artifact. If not provided, it's generated.
446
+ **kwargs : dict
447
+ New artifact spec parameters.
448
+
449
+ Returns
450
+ -------
451
+ Artifact
452
+ Object instance.
453
+
454
+ Examples
455
+ --------
456
+ >>> obj = project.log_artifact(name="my-artifact",
457
+ >>> kind="artifact",
458
+ >>> source="./local-path")
459
+ """
460
+ obj = log_artifact(
461
+ project=self.name,
462
+ name=name,
463
+ kind=kind,
464
+ source=source,
465
+ path=path,
466
+ **kwargs,
467
+ )
468
+ self.refresh()
469
+ return obj
470
+
471
+ def get_artifact(
472
+ self,
473
+ identifier: str,
474
+ entity_id: str | None = None,
475
+ **kwargs,
476
+ ) -> Artifact:
477
+ """
478
+ Get object from backend.
479
+
480
+ Parameters
481
+ ----------
482
+ identifier : str
483
+ Entity key (store://...) or entity name.
484
+ entity_id : str
485
+ Entity ID.
486
+ **kwargs : dict
487
+ Parameters to pass to the API call.
488
+
489
+ Returns
490
+ -------
491
+ Artifact
492
+ Object instance.
493
+
494
+ Examples
495
+ --------
496
+ Using entity key:
497
+ >>> obj = project.get_artifact("store://my-artifact-key")
498
+
499
+ Using entity name:
500
+ >>> obj = project.get_artifact("my-artifact-name"
501
+ >>> entity_id="my-artifact-id")
502
+ """
503
+ obj = get_artifact(
504
+ identifier=identifier,
505
+ project=self.name,
506
+ entity_id=entity_id,
507
+ **kwargs,
508
+ )
509
+ self.refresh()
510
+ return obj
511
+
512
+ def get_artifact_versions(
513
+ self,
514
+ identifier: str,
515
+ **kwargs,
516
+ ) -> list[Artifact]:
517
+ """
518
+ Get object versions from backend.
519
+
520
+ Parameters
521
+ ----------
522
+ identifier : str
523
+ Entity key (store://...) or entity name.
524
+ **kwargs : dict
525
+ Parameters to pass to the API call.
526
+
527
+ Returns
528
+ -------
529
+ list[Artifact]
530
+ List of object instances.
531
+
532
+ Examples
533
+ --------
534
+ Using entity key:
535
+ >>> obj = project.get_artifact_versions("store://my-artifact-key")
536
+
537
+ Using entity name:
538
+ >>> obj = project.get_artifact_versions("my-artifact-name")
539
+ """
540
+ return get_artifact_versions(identifier, project=self.name, **kwargs)
541
+
542
+ def list_artifacts(self, **kwargs) -> list[Artifact]:
543
+ """
544
+ List all latest version objects from backend.
545
+
546
+ Parameters
547
+ ----------
548
+ **kwargs : dict
549
+ Parameters to pass to the API call.
550
+
551
+ Returns
552
+ -------
553
+ list[Artifact]
554
+ List of object instances.
555
+
556
+ Examples
557
+ --------
558
+ >>> objs = project.list_artifacts()
559
+ """
560
+ return list_artifacts(self.name, **kwargs)
561
+
562
+ def import_artifact(
563
+ self,
564
+ file: str,
565
+ **kwargs,
566
+ ) -> Artifact:
567
+ """
568
+ Import object from a YAML file.
569
+
570
+ Parameters
571
+ ----------
572
+ file : str
573
+ Path to YAML file.
574
+ **kwargs : dict
575
+ Parameters to pass to the API call.
576
+
577
+ Returns
578
+ -------
579
+ Artifact
580
+ Object instance.
581
+
582
+ Examples
583
+ --------
584
+ >>> obj = project.import_artifact("my-artifact.yaml")
585
+ """
586
+ return import_artifact(file, **kwargs)
587
+
588
+ def update_artifact(self, entity: Artifact) -> Artifact:
589
+ """
590
+ Update object. Note that object spec are immutable.
591
+
592
+ Parameters
593
+ ----------
594
+ entity : Artifact
595
+ Object to update.
596
+
597
+ Returns
598
+ -------
599
+ Artifact
600
+ Entity updated.
601
+
602
+ Examples
603
+ --------
604
+ >>> obj = project.update_artifact(obj)
605
+ """
606
+ if entity.project != self.name:
607
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
608
+ return update_artifact(entity)
609
+
610
+ def delete_artifact(
611
+ self,
612
+ identifier: str,
613
+ entity_id: str | None = None,
614
+ delete_all_versions: bool = False,
615
+ **kwargs,
616
+ ) -> None:
617
+ """
618
+ Delete object from backend.
619
+
620
+ Parameters
621
+ ----------
622
+ identifier : str
623
+ Entity key (store://...) or entity name.
624
+ entity_id : str
625
+ Entity ID.
626
+ delete_all_versions : bool
627
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
628
+ **kwargs : dict
629
+ Parameters to pass to the API call.
630
+
631
+ Returns
632
+ -------
633
+ dict
634
+ Response from backend.
635
+
636
+ Examples
637
+ --------
638
+ If delete_all_versions is False:
639
+ >>> project.delete_artifact("store://my-artifact-key")
640
+
641
+ Otherwise:
642
+ >>> project.delete_artifact("my-artifact-name",
643
+ >>> delete_all_versions=True)
644
+ """
645
+ delete_artifact(
646
+ identifier=identifier,
647
+ project=self.name,
648
+ entity_id=entity_id,
649
+ delete_all_versions=delete_all_versions,
650
+ **kwargs,
651
+ )
652
+ self.refresh()
653
+
654
+ ##############################
655
+ # Dataitems
656
+ ##############################
657
+
658
+ def new_dataitem(
659
+ self,
660
+ name: str,
661
+ kind: str,
662
+ uuid: str | None = None,
663
+ description: str | None = None,
664
+ labels: list[str] | None = None,
665
+ embedded: bool = False,
666
+ path: str | None = None,
667
+ **kwargs,
668
+ ) -> Dataitem:
669
+ """
670
+ Create a new object.
671
+
672
+ Parameters
673
+ ----------
674
+ name : str
675
+ Object name.
676
+ kind : str
677
+ Kind the object.
678
+ uuid : str
679
+ ID of the object.
680
+ description : str
681
+ Description of the object (human readable).
682
+ labels : list[str]
683
+ List of labels.
684
+ embedded : bool
685
+ Flag to determine if object spec must be embedded in project spec.
686
+ path : str
687
+ Object path on local file system or remote storage. It is also the destination path of upload() method.
688
+ **kwargs : dict
689
+ Spec keyword arguments.
690
+
691
+ Returns
692
+ -------
693
+ Dataitem
694
+ Object instance.
695
+
696
+ Examples
697
+ --------
698
+ >>> obj = project.new_dataitem(name="my-dataitem",
699
+ >>> kind="dataitem",
700
+ >>> path="s3://my-bucket/my-key")
701
+ """
702
+ obj = new_dataitem(
703
+ project=self.name,
704
+ name=name,
705
+ kind=kind,
706
+ uuid=uuid,
707
+ description=description,
708
+ labels=labels,
709
+ embedded=embedded,
710
+ path=path,
711
+ **kwargs,
712
+ )
713
+ self.refresh()
714
+ return obj
715
+
716
+ def log_dataitem(
717
+ self,
718
+ name: str,
719
+ kind: str,
720
+ source: str | None = None,
721
+ data: Any | None = None,
722
+ extension: str | None = None,
723
+ path: str | None = None,
724
+ **kwargs,
725
+ ) -> Dataitem:
726
+ """
727
+ Create and upload an object.
728
+
729
+ Parameters
730
+ ----------
731
+ name : str
732
+ Object name.
733
+ kind : str
734
+ Kind the object.
735
+ data : Any
736
+ Dataframe to log.
737
+ extension : str
738
+ Extension of the dataitem.
739
+ source : str
740
+ Dataitem location on local path.
741
+ data : Any
742
+ Dataframe to log. Alternative to source.
743
+ extension : str
744
+ Extension of the output dataframe.
745
+ path : str
746
+ Destination path of the dataitem. If not provided, it's generated.
747
+ **kwargs : dict
748
+ New dataitem spec parameters.
749
+
750
+ Returns
751
+ -------
752
+ Dataitem
753
+ Object instance.
754
+
755
+ Examples
756
+ --------
757
+ >>> obj = project.log_dataitem(name="my-dataitem",
758
+ >>> kind="table",
759
+ >>> data=df)
760
+ """
761
+ obj = log_dataitem(
762
+ project=self.name,
763
+ name=name,
764
+ kind=kind,
765
+ path=path,
766
+ source=source,
767
+ data=data,
768
+ extension=extension,
769
+ **kwargs,
770
+ )
771
+ self.refresh()
772
+ return obj
773
+
774
+ def get_dataitem(
775
+ self,
776
+ identifier: str,
777
+ entity_id: str | None = None,
778
+ **kwargs,
779
+ ) -> Dataitem:
780
+ """
781
+ Get object from backend.
782
+
783
+ Parameters
784
+ ----------
785
+ identifier : str
786
+ Entity key (store://...) or entity name.
787
+ entity_id : str
788
+ Entity ID.
789
+ **kwargs : dict
790
+ Parameters to pass to the API call.
791
+
792
+ Returns
793
+ -------
794
+ Dataitem
795
+ Object instance.
796
+
797
+ Examples
798
+ --------
799
+ Using entity key:
800
+ >>> obj = project.get_dataitem("store://my-dataitem-key")
801
+
802
+ Using entity name:
803
+ >>> obj = project.get_dataitem("my-dataitem-name"
804
+ >>> entity_id="my-dataitem-id")
805
+ """
806
+ obj = get_dataitem(
807
+ identifier=identifier,
808
+ project=self.name,
809
+ entity_id=entity_id,
810
+ **kwargs,
811
+ )
812
+ self.refresh()
813
+ return obj
814
+
815
+ def get_dataitem_versions(
816
+ self,
817
+ identifier: str,
818
+ **kwargs,
819
+ ) -> list[Dataitem]:
820
+ """
821
+ Get object versions from backend.
822
+
823
+ Parameters
824
+ ----------
825
+ identifier : str
826
+ Entity key (store://...) or entity name.
827
+ **kwargs : dict
828
+ Parameters to pass to the API call.
829
+
830
+ Returns
831
+ -------
832
+ list[Dataitem]
833
+ List of object instances.
834
+
835
+ Examples
836
+ --------
837
+ Using entity key:
838
+ >>> obj = project.get_dataitem_versions("store://my-dataitem-key")
839
+
840
+ Using entity name:
841
+ >>> obj = project.get_dataitem_versions("my-dataitem-name")
842
+ """
843
+ return get_dataitem_versions(identifier, project=self.name, **kwargs)
844
+
845
+ def list_dataitems(self, **kwargs) -> list[Dataitem]:
846
+ """
847
+ List all latest version objects from backend.
848
+
849
+ Parameters
850
+ ----------
851
+ **kwargs : dict
852
+ Parameters to pass to the API call.
853
+
854
+ Returns
855
+ -------
856
+ list[Dataitem]
857
+ List of object instances.
858
+
859
+ Examples
860
+ --------
861
+ >>> objs = project.list_dataitems()
862
+ """
863
+ return list_dataitems(self.name, **kwargs)
864
+
865
+ def import_dataitem(
866
+ self,
867
+ file: str,
868
+ **kwargs,
869
+ ) -> Dataitem:
870
+ """
871
+ Import object from a YAML file.
872
+
873
+ Parameters
874
+ ----------
875
+ file : str
876
+ Path to YAML file.
877
+ **kwargs : dict
878
+ Parameters to pass to the API call.
879
+
880
+ Returns
881
+ -------
882
+ Dataitem
883
+ Object instance.
884
+
885
+ Examples
886
+ --------
887
+ >>> obj = project.import_dataitem("my-dataitem.yaml")
888
+ """
889
+ return import_dataitem(file, **kwargs)
890
+
891
+ def update_dataitem(self, entity: Dataitem) -> Dataitem:
892
+ """
893
+ Update object. Note that object spec are immutable.
894
+
895
+ Parameters
896
+ ----------
897
+ entity : Dataitem
898
+ Object to update.
899
+
900
+ Returns
901
+ -------
902
+ Dataitem
903
+ Entity updated.
904
+
905
+ Examples
906
+ --------
907
+ >>> obj = project.update_dataitem(obj)
908
+ """
909
+ if entity.project != self.name:
910
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
911
+ return update_dataitem(entity)
912
+
913
+ def delete_dataitem(
914
+ self,
915
+ identifier: str,
916
+ entity_id: str | None = None,
917
+ delete_all_versions: bool = False,
918
+ **kwargs,
919
+ ) -> None:
920
+ """
921
+ Delete object from backend.
922
+
923
+ Parameters
924
+ ----------
925
+ identifier : str
926
+ Entity key (store://...) or entity name.
927
+ entity_id : str
928
+ Entity ID.
929
+ delete_all_versions : bool
930
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
931
+ **kwargs : dict
932
+ Parameters to pass to the API call.
933
+
934
+ Returns
935
+ -------
936
+ dict
937
+ Response from backend.
938
+
939
+ Examples
940
+ --------
941
+ If delete_all_versions is False:
942
+ >>> project.delete_dataitem("store://my-dataitem-key")
943
+
944
+ Otherwise:
945
+ >>> project.delete_dataitem("my-dataitem-name",
946
+ >>> project="my-project",
947
+ >>> delete_all_versions=True)
948
+ """
949
+ delete_dataitem(
950
+ identifier=identifier,
951
+ project=self.name,
952
+ entity_id=entity_id,
953
+ delete_all_versions=delete_all_versions,
954
+ **kwargs,
955
+ )
956
+ self.refresh()
957
+
958
+ ##############################
959
+ # Models
960
+ ##############################
961
+
962
+ def new_model(
963
+ self,
964
+ name: str,
965
+ kind: str,
966
+ uuid: str | None = None,
967
+ description: str | None = None,
968
+ labels: list[str] | None = None,
969
+ embedded: bool = False,
970
+ path: str | None = None,
971
+ **kwargs,
972
+ ) -> Model:
973
+ """
974
+ Create a new object.
975
+
976
+ Parameters
977
+ ----------
978
+ name : str
979
+ Object name.
980
+ kind : str
981
+ Kind the object.
982
+ uuid : str
983
+ ID of the object.
984
+ description : str
985
+ Description of the object (human readable).
986
+ labels : list[str]
987
+ List of labels.
988
+ embedded : bool
989
+ Flag to determine if object spec must be embedded in project spec.
990
+ path : str
991
+ Object path on local file system or remote storage. It is also the destination path of upload() method.
992
+ **kwargs : dict
993
+ Spec keyword arguments.
994
+
995
+ Returns
996
+ -------
997
+ Model
998
+ Object instance.
999
+
1000
+ Examples
1001
+ --------
1002
+ >>> obj = project.new_model(name="my-model",
1003
+ >>> kind="model",
1004
+ >>> path="s3://my-bucket/my-key")
1005
+ """
1006
+ obj = new_model(
1007
+ project=self.name,
1008
+ name=name,
1009
+ kind=kind,
1010
+ uuid=uuid,
1011
+ description=description,
1012
+ labels=labels,
1013
+ embedded=embedded,
1014
+ path=path,
1015
+ **kwargs,
1016
+ )
1017
+ self.refresh()
1018
+ return obj
1019
+
1020
+ def log_model(
1021
+ self,
1022
+ name: str,
1023
+ kind: str,
1024
+ source: str,
1025
+ path: str | None = None,
1026
+ **kwargs,
1027
+ ) -> Model:
1028
+ """
1029
+ Create and upload an object.
1030
+
1031
+ Parameters
1032
+ ----------
1033
+ name : str
1034
+ Object name.
1035
+ kind : str
1036
+ Kind the object.
1037
+ source : str
1038
+ Model location on local path.
1039
+ path : str
1040
+ Destination path of the model. If not provided, it's generated.
1041
+ **kwargs : dict
1042
+ New model spec parameters.
1043
+
1044
+ Returns
1045
+ -------
1046
+ Model
1047
+ Object instance.
1048
+
1049
+ Examples
1050
+ --------
1051
+ >>> obj = project.log_model(name="my-model",
1052
+ >>> kind="model",
1053
+ >>> source="./local-path")
1054
+ """
1055
+ obj = log_model(
1056
+ project=self.name,
1057
+ name=name,
1058
+ kind=kind,
1059
+ source=source,
1060
+ path=path,
1061
+ **kwargs,
1062
+ )
1063
+ self.refresh()
1064
+ return obj
1065
+
1066
+ def get_model(
1067
+ self,
1068
+ identifier: str,
1069
+ entity_id: str | None = None,
1070
+ **kwargs,
1071
+ ) -> Model:
1072
+ """
1073
+ Get object from backend.
1074
+
1075
+ Parameters
1076
+ ----------
1077
+ identifier : str
1078
+ Entity key (store://...) or entity name.
1079
+ entity_id : str
1080
+ Entity ID.
1081
+ **kwargs : dict
1082
+ Parameters to pass to the API call.
1083
+
1084
+ Returns
1085
+ -------
1086
+ Model
1087
+ Object instance.
1088
+
1089
+ Examples
1090
+ --------
1091
+ Using entity key:
1092
+ >>> obj = project.get_model("store://my-model-key")
1093
+
1094
+ Using entity name:
1095
+ >>> obj = project.get_model("my-model-name"
1096
+ >>> entity_id="my-model-id")
1097
+ """
1098
+ obj = get_model(
1099
+ identifier=identifier,
1100
+ project=self.name,
1101
+ entity_id=entity_id,
1102
+ **kwargs,
1103
+ )
1104
+ self.refresh()
1105
+ return obj
1106
+
1107
+ def get_model_versions(
1108
+ self,
1109
+ identifier: str,
1110
+ **kwargs,
1111
+ ) -> list[Model]:
1112
+ """
1113
+ Get object versions from backend.
1114
+
1115
+ Parameters
1116
+ ----------
1117
+ identifier : str
1118
+ Entity key (store://...) or entity name.
1119
+ **kwargs : dict
1120
+ Parameters to pass to the API call.
1121
+
1122
+ Returns
1123
+ -------
1124
+ list[Model]
1125
+ List of object instances.
1126
+
1127
+ Examples
1128
+ --------
1129
+ Using entity key:
1130
+ >>> obj = project.get_model_versions("store://my-model-key")
1131
+
1132
+ Using entity name:
1133
+ >>> obj = project.get_model_versions("my-model-name")
1134
+ """
1135
+ return get_model_versions(identifier, project=self.name, **kwargs)
1136
+
1137
+ def list_models(self, **kwargs) -> list[Model]:
1138
+ """
1139
+ List all latest version objects from backend.
1140
+
1141
+ Parameters
1142
+ ----------
1143
+ **kwargs : dict
1144
+ Parameters to pass to the API call.
1145
+
1146
+ Returns
1147
+ -------
1148
+ list[Model]
1149
+ List of object instances.
1150
+
1151
+ Examples
1152
+ --------
1153
+ >>> objs = project.list_models()
1154
+ """
1155
+ return list_models(self.name, **kwargs)
1156
+
1157
+ def import_model(
1158
+ self,
1159
+ file: str,
1160
+ **kwargs,
1161
+ ) -> Model:
1162
+ """
1163
+ Import object from a YAML file.
1164
+
1165
+ Parameters
1166
+ ----------
1167
+ file : str
1168
+ Path to YAML file.
1169
+ **kwargs : dict
1170
+ Parameters to pass to the API call.
1171
+
1172
+ Returns
1173
+ -------
1174
+ Model
1175
+ Object instance.
1176
+
1177
+ Examples
1178
+ --------
1179
+ >>> obj = project.import_model("my-model.yaml")
1180
+ """
1181
+ return import_model(file, **kwargs)
1182
+
1183
+ def update_model(self, entity: Model) -> Model:
1184
+ """
1185
+ Update object. Note that object spec are immutable.
1186
+
1187
+ Parameters
1188
+ ----------
1189
+ entity : Model
1190
+ Object to update.
1191
+
1192
+ Returns
1193
+ -------
1194
+ Model
1195
+ Entity updated.
1196
+
1197
+ Examples
1198
+ --------
1199
+ >>> obj = project.update_model(obj)
1200
+ """
1201
+ if entity.project != self.name:
1202
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
1203
+ return update_model(entity)
1204
+
1205
+ def delete_model(
1206
+ self,
1207
+ identifier: str,
1208
+ entity_id: str | None = None,
1209
+ delete_all_versions: bool = False,
1210
+ **kwargs,
1211
+ ) -> None:
1212
+ """
1213
+ Delete object from backend.
1214
+
1215
+ Parameters
1216
+ ----------
1217
+ identifier : str
1218
+ Entity key (store://...) or entity name.
1219
+ entity_id : str
1220
+ Entity ID.
1221
+ delete_all_versions : bool
1222
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
1223
+ **kwargs : dict
1224
+ Parameters to pass to the API call.
1225
+
1226
+ Returns
1227
+ -------
1228
+ dict
1229
+ Response from backend.
1230
+
1231
+ Examples
1232
+ --------
1233
+ If delete_all_versions is False:
1234
+ >>> project.delete_model("store://my-model-key")
1235
+
1236
+ Otherwise:
1237
+ >>> project.delete_model("my-model-name",
1238
+ >>> project="my-project",
1239
+ >>> delete_all_versions=True)
1240
+ """
1241
+ delete_model(
1242
+ identifier=identifier,
1243
+ project=self.name,
1244
+ entity_id=entity_id,
1245
+ delete_all_versions=delete_all_versions,
1246
+ **kwargs,
1247
+ )
1248
+ self.refresh()
1249
+
1250
+ ##############################
1251
+ # Functions
1252
+ ##############################
1253
+
1254
+ def new_function(
1255
+ self,
1256
+ name: str,
1257
+ kind: str,
1258
+ uuid: str | None = None,
1259
+ description: str | None = None,
1260
+ labels: list[str] | None = None,
1261
+ embedded: bool = False,
1262
+ **kwargs,
1263
+ ) -> Function:
1264
+ """
1265
+ Create a new object.
1266
+
1267
+ Parameters
1268
+ ----------
1269
+ name : str
1270
+ Object name.
1271
+ kind : str
1272
+ Kind the object.
1273
+ uuid : str
1274
+ ID of the object.
1275
+ description : str
1276
+ Description of the object (human readable).
1277
+ labels : list[str]
1278
+ List of labels.
1279
+ embedded : bool
1280
+ Flag to determine if object spec must be embedded in project spec.
1281
+ **kwargs : dict
1282
+ Spec keyword arguments.
1283
+
1284
+ Returns
1285
+ -------
1286
+ Function
1287
+ Object instance.
1288
+
1289
+ Examples
1290
+ --------
1291
+ >>> obj = project.new_function(name="my-function",
1292
+ >>> kind="python",
1293
+ >>> code_src="function.py",
1294
+ >>> handler="function-handler")
1295
+ """
1296
+ obj = new_function(
1297
+ project=self.name,
1298
+ name=name,
1299
+ kind=kind,
1300
+ uuid=uuid,
1301
+ description=description,
1302
+ labels=labels,
1303
+ embedded=embedded,
1304
+ **kwargs,
1305
+ )
1306
+ self.refresh()
1307
+ return obj
1308
+
1309
+ def get_function(
1310
+ self,
1311
+ identifier: str,
1312
+ entity_id: str | None = None,
1313
+ **kwargs,
1314
+ ) -> Function:
1315
+ """
1316
+ Get object from backend.
1317
+
1318
+ Parameters
1319
+ ----------
1320
+ identifier : str
1321
+ Entity key (store://...) or entity name.
1322
+ entity_id : str
1323
+ Entity ID.
1324
+ **kwargs : dict
1325
+ Parameters to pass to the API call.
1326
+
1327
+ Returns
1328
+ -------
1329
+ Function
1330
+ Object instance.
1331
+
1332
+ Examples
1333
+ --------
1334
+ Using entity key:
1335
+ >>> obj = project.get_function("store://my-function-key")
1336
+
1337
+ Using entity name:
1338
+ >>> obj = project.get_function("my-function-name"
1339
+ >>> entity_id="my-function-id")
1340
+ """
1341
+ obj = get_function(
1342
+ identifier=identifier,
1343
+ project=self.name,
1344
+ entity_id=entity_id,
1345
+ **kwargs,
1346
+ )
1347
+ self.refresh()
1348
+ return obj
1349
+
1350
+ def get_function_versions(
1351
+ self,
1352
+ identifier: str,
1353
+ **kwargs,
1354
+ ) -> list[Function]:
1355
+ """
1356
+ Get object versions from backend.
1357
+
1358
+ Parameters
1359
+ ----------
1360
+ identifier : str
1361
+ Entity key (store://...) or entity name.
1362
+ **kwargs : dict
1363
+ Parameters to pass to the API call.
1364
+
1365
+ Returns
1366
+ -------
1367
+ list[Function]
1368
+ List of object instances.
1369
+
1370
+ Examples
1371
+ --------
1372
+ Using entity key:
1373
+ >>> obj = project.get_function_versions("store://my-function-key")
1374
+
1375
+ Using entity name:
1376
+ >>> obj = project.get_function_versions("my-function-name")
1377
+ """
1378
+ return get_function_versions(identifier, project=self.name, **kwargs)
1379
+
1380
+ def list_functions(self, **kwargs) -> list[Function]:
1381
+ """
1382
+ List all latest version objects from backend.
1383
+
1384
+ Parameters
1385
+ ----------
1386
+ **kwargs : dict
1387
+ Parameters to pass to the API call.
1388
+
1389
+ Returns
1390
+ -------
1391
+ list[Function]
1392
+ List of object instances.
1393
+
1394
+ Examples
1395
+ --------
1396
+ >>> objs = project.list_functions()
1397
+ """
1398
+ return list_functions(self.name, **kwargs)
1399
+
1400
+ def import_function(
1401
+ self,
1402
+ file: str,
1403
+ **kwargs,
1404
+ ) -> Function:
1405
+ """
1406
+ Import object from a YAML file.
1407
+
1408
+ Parameters
1409
+ ----------
1410
+ file : str
1411
+ Path to YAML file.
1412
+ **kwargs : dict
1413
+ Parameters to pass to the API call.
1414
+
1415
+ Returns
1416
+ -------
1417
+ Function
1418
+ Object instance.
1419
+
1420
+ Examples
1421
+ --------
1422
+ >>> obj = project.import_function("my-function.yaml")
1423
+ """
1424
+ return import_function(file, **kwargs)
1425
+
1426
+ def update_function(self, entity: Function) -> Function:
1427
+ """
1428
+ Update object. Note that object spec are immutable.
1429
+
1430
+ Parameters
1431
+ ----------
1432
+ entity : Function
1433
+ Object to update.
1434
+
1435
+ Returns
1436
+ -------
1437
+ Function
1438
+ Entity updated.
1439
+
1440
+ Examples
1441
+ --------
1442
+ >>> obj = project.update_function(obj)
1443
+ """
1444
+ if entity.project != self.name:
1445
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
1446
+ return update_function(entity)
1447
+
1448
+ def delete_function(
1449
+ self,
1450
+ identifier: str,
1451
+ entity_id: str | None = None,
1452
+ delete_all_versions: bool = False,
1453
+ cascade: bool = True,
1454
+ **kwargs,
1455
+ ) -> None:
1456
+ """
1457
+ Delete object from backend.
1458
+
1459
+ Parameters
1460
+ ----------
1461
+ identifier : str
1462
+ Entity key (store://...) or entity name.
1463
+ entity_id : str
1464
+ Entity ID.
1465
+ delete_all_versions : bool
1466
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
1467
+ cascade : bool
1468
+ Cascade delete.
1469
+ **kwargs : dict
1470
+ Parameters to pass to the API call.
1471
+
1472
+ Returns
1473
+ -------
1474
+ dict
1475
+ Response from backend.
1476
+
1477
+ Examples
1478
+ --------
1479
+ If delete_all_versions is False:
1480
+ >>> project.delete_function("store://my-function-key")
1481
+
1482
+ Otherwise:
1483
+ >>> project.delete_function("my-function-name",
1484
+ >>> delete_all_versions=True)
1485
+ """
1486
+ delete_function(
1487
+ identifier=identifier,
1488
+ project=self.name,
1489
+ entity_id=entity_id,
1490
+ delete_all_versions=delete_all_versions,
1491
+ cascade=cascade,
1492
+ **kwargs,
1493
+ )
1494
+ self.refresh()
1495
+
1496
+ ##############################
1497
+ # Workflows
1498
+ ##############################
1499
+
1500
+ def new_workflow(
1501
+ self,
1502
+ name: str,
1503
+ kind: str,
1504
+ uuid: str | None = None,
1505
+ description: str | None = None,
1506
+ labels: list[str] | None = None,
1507
+ embedded: bool = False,
1508
+ **kwargs,
1509
+ ) -> Workflow:
1510
+ """
1511
+ Create a new object.
1512
+
1513
+ Parameters
1514
+ ----------
1515
+ name : str
1516
+ Object name.
1517
+ kind : str
1518
+ Kind the object.
1519
+ uuid : str
1520
+ ID of the object.
1521
+ description : str
1522
+ Description of the object (human readable).
1523
+ labels : list[str]
1524
+ List of labels.
1525
+ embedded : bool
1526
+ Flag to determine if object spec must be embedded in project spec.
1527
+ **kwargs : dict
1528
+ Spec keyword arguments.
1529
+
1530
+ Returns
1531
+ -------
1532
+ Workflow
1533
+ Object instance.
1534
+
1535
+ Examples
1536
+ --------
1537
+ >>> obj = project.new_workflow(name="my-workflow",
1538
+ >>> kind="kfp",
1539
+ >>> code_src="pipeline.py",
1540
+ >>> handler="pipeline-handler")
1541
+ """
1542
+ obj = new_workflow(
1543
+ project=self.name,
1544
+ name=name,
1545
+ kind=kind,
1546
+ uuid=uuid,
1547
+ description=description,
1548
+ labels=labels,
1549
+ embedded=embedded,
1550
+ **kwargs,
1551
+ )
1552
+ self.refresh()
1553
+ return obj
1554
+
1555
+ def get_workflow(
1556
+ self,
1557
+ identifier: str,
1558
+ entity_id: str | None = None,
1559
+ **kwargs,
1560
+ ) -> Workflow:
1561
+ """
1562
+ Get object from backend.
1563
+
1564
+ Parameters
1565
+ ----------
1566
+ identifier : str
1567
+ Entity key (store://...) or entity name.
1568
+ entity_id : str
1569
+ Entity ID.
1570
+ **kwargs : dict
1571
+ Parameters to pass to the API call.
1572
+
1573
+ Returns
1574
+ -------
1575
+ Workflow
1576
+ Object instance.
1577
+
1578
+ Examples
1579
+ --------
1580
+ Using entity key:
1581
+ >>> obj = project.get_workflow("store://my-workflow-key")
1582
+
1583
+ Using entity name:
1584
+ >>> obj = project.get_workflow("my-workflow-name"
1585
+ >>> entity_id="my-workflow-id")
1586
+ """
1587
+ obj = get_workflow(
1588
+ identifier=identifier,
1589
+ project=self.name,
1590
+ entity_id=entity_id,
1591
+ **kwargs,
1592
+ )
1593
+ self.refresh()
1594
+ return obj
1595
+
1596
+ def get_workflow_versions(
1597
+ self,
1598
+ identifier: str,
1599
+ **kwargs,
1600
+ ) -> list[Workflow]:
1601
+ """
1602
+ Get object versions from backend.
1603
+
1604
+ Parameters
1605
+ ----------
1606
+ identifier : str
1607
+ Entity key (store://...) or entity name.
1608
+ **kwargs : dict
1609
+ Parameters to pass to the API call.
1610
+
1611
+ Returns
1612
+ -------
1613
+ list[Workflow]
1614
+ List of object instances.
1615
+
1616
+ Examples
1617
+ --------
1618
+ Using entity key:
1619
+ >>> obj = project.get_workflow_versions("store://my-workflow-key")
1620
+
1621
+ Using entity name:
1622
+ >>> obj = project.get_workflow_versions("my-workflow-name")
1623
+ """
1624
+ return get_workflow_versions(identifier, project=self.name, **kwargs)
1625
+
1626
+ def list_workflows(self, **kwargs) -> list[Workflow]:
1627
+ """
1628
+ List all latest version objects from backend.
1629
+
1630
+ Parameters
1631
+ ----------
1632
+ **kwargs : dict
1633
+ Parameters to pass to the API call.
1634
+
1635
+ Returns
1636
+ -------
1637
+ list[Workflow]
1638
+ List of object instances.
1639
+
1640
+ Examples
1641
+ --------
1642
+ >>> objs = project.list_workflows()
1643
+ """
1644
+ return list_workflows(self.name, **kwargs)
1645
+
1646
+ def import_workflow(
1647
+ self,
1648
+ file: str,
1649
+ **kwargs,
1650
+ ) -> Workflow:
1651
+ """
1652
+ Import object from a YAML file.
1653
+
1654
+ Parameters
1655
+ ----------
1656
+ file : str
1657
+ Path to YAML file.
1658
+ **kwargs : dict
1659
+ Parameters to pass to the API call.
1660
+
1661
+ Returns
1662
+ -------
1663
+ Workflow
1664
+ Object instance.
1665
+
1666
+ Examples
1667
+ --------
1668
+ >>> obj = project.import_workflow("my-workflow.yaml")
1669
+ """
1670
+ return import_workflow(file, **kwargs)
1671
+
1672
+ def update_workflow(self, entity: Workflow) -> Workflow:
1673
+ """
1674
+ Update object. Note that object spec are immutable.
1675
+
1676
+ Parameters
1677
+ ----------
1678
+ entity : Workflow
1679
+ Object to update.
1680
+
1681
+ Returns
1682
+ -------
1683
+ Workflow
1684
+ Entity updated.
1685
+
1686
+ Examples
1687
+ --------
1688
+ >>> obj = project.update_workflow(obj)
1689
+ """
1690
+ if entity.project != self.name:
1691
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
1692
+ return update_workflow(entity)
1693
+
1694
+ def delete_workflow(
1695
+ self,
1696
+ identifier: str,
1697
+ entity_id: str | None = None,
1698
+ delete_all_versions: bool = False,
1699
+ cascade: bool = True,
1700
+ **kwargs,
1701
+ ) -> None:
1702
+ """
1703
+ Delete object from backend.
1704
+
1705
+ Parameters
1706
+ ----------
1707
+ identifier : str
1708
+ Entity key (store://...) or entity name.
1709
+ entity_id : str
1710
+ Entity ID.
1711
+ delete_all_versions : bool
1712
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
1713
+ cascade : bool
1714
+ Cascade delete.
1715
+ **kwargs : dict
1716
+ Parameters to pass to the API call.
1717
+
1718
+ Returns
1719
+ -------
1720
+ dict
1721
+ Response from backend.
1722
+
1723
+ Examples
1724
+ --------
1725
+ If delete_all_versions is False:
1726
+ >>> project.delete_workflow("store://my-workflow-key")
1727
+
1728
+ Otherwise:
1729
+ >>> project.delete_workflow("my-workflow-name",
1730
+ >>> delete_all_versions=True)
1731
+ """
1732
+ delete_workflow(
1733
+ identifier=identifier,
1734
+ project=self.name,
1735
+ entity_id=entity_id,
1736
+ delete_all_versions=delete_all_versions,
1737
+ cascade=cascade,
1738
+ **kwargs,
1739
+ )
1740
+ self.refresh()
1741
+
1742
+ ##############################
1743
+ # Secrets
1744
+ ##############################
1745
+
1746
+ def new_secret(
1747
+ self,
1748
+ name: str,
1749
+ uuid: str | None = None,
1750
+ description: str | None = None,
1751
+ labels: list[str] | None = None,
1752
+ embedded: bool = False,
1753
+ secret_value: str | None = None,
1754
+ **kwargs,
1755
+ ) -> Secret:
1756
+ """
1757
+ Create a new object.
1758
+
1759
+ Parameters
1760
+ ----------
1761
+ name : str
1762
+ Object name.
1763
+ uuid : str
1764
+ ID of the object.
1765
+ description : str
1766
+ Description of the object (human readable).
1767
+ labels : list[str]
1768
+ List of labels.
1769
+ embedded : bool
1770
+ Flag to determine if object spec must be embedded in project spec.
1771
+ secret_value : str
1772
+ Value of the secret.
1773
+ **kwargs : dict
1774
+ Spec keyword arguments.
1775
+
1776
+ Returns
1777
+ -------
1778
+ Secret
1779
+ Object instance.
1780
+
1781
+ Examples
1782
+ --------
1783
+ >>> obj = project.new_secret(name="my-secret",
1784
+ >>> secret_value="my-secret-value")
1785
+ """
1786
+ obj = new_secret(
1787
+ project=self.name,
1788
+ name=name,
1789
+ uuid=uuid,
1790
+ description=description,
1791
+ labels=labels,
1792
+ embedded=embedded,
1793
+ secret_value=secret_value,
1794
+ **kwargs,
1795
+ )
1796
+ self.refresh()
1797
+ return obj
1798
+
1799
+ def get_secret(
1800
+ self,
1801
+ identifier: str,
1802
+ entity_id: str | None = None,
1803
+ **kwargs,
1804
+ ) -> Secret:
1805
+ """
1806
+ Get object from backend.
1807
+
1808
+ Parameters
1809
+ ----------
1810
+ identifier : str
1811
+ Entity key (store://...) or entity name.
1812
+ entity_id : str
1813
+ Entity ID.
1814
+ **kwargs : dict
1815
+ Parameters to pass to the API call.
1816
+
1817
+ Returns
1818
+ -------
1819
+ Secret
1820
+ Object instance.
1821
+
1822
+ Examples
1823
+ --------
1824
+ Using entity key:
1825
+ >>> obj = project.get_secret("store://my-secret-key")
1826
+
1827
+ Using entity name:
1828
+ >>> obj = project.get_secret("my-secret-name"
1829
+ >>> entity_id="my-secret-id")
1830
+ """
1831
+ obj = get_secret(
1832
+ identifier=identifier,
1833
+ project=self.name,
1834
+ entity_id=entity_id,
1835
+ **kwargs,
1836
+ )
1837
+ self.refresh()
1838
+ return obj
1839
+
1840
+ def get_secret_versions(
1841
+ self,
1842
+ identifier: str,
1843
+ **kwargs,
1844
+ ) -> list[Secret]:
1845
+ """
1846
+ Get object versions from backend.
1847
+
1848
+ Parameters
1849
+ ----------
1850
+ identifier : str
1851
+ Entity key (store://...) or entity name.
1852
+ **kwargs : dict
1853
+ Parameters to pass to the API call.
1854
+
1855
+ Returns
1856
+ -------
1857
+ list[Secret]
1858
+ List of object instances.
1859
+
1860
+ Examples
1861
+ --------
1862
+ Using entity key:
1863
+ >>> obj = project.get_secret_versions("store://my-secret-key")
1864
+
1865
+ Using entity name:
1866
+ >>> obj = project.get_secret_versions("my-secret-name")
1867
+ """
1868
+ return get_secret_versions(identifier, project=self.name, **kwargs)
1869
+
1870
+ def list_secrets(self, **kwargs) -> list[Secret]:
1871
+ """
1872
+ List all latest version objects from backend.
1873
+
1874
+ Parameters
1875
+ ----------
1876
+ **kwargs : dict
1877
+ Parameters to pass to the API call.
1878
+
1879
+ Returns
1880
+ -------
1881
+ list[Secret]
1882
+ List of object instances.
1883
+
1884
+ Examples
1885
+ --------
1886
+ >>> objs = project.list_secrets()
1887
+ """
1888
+ return list_secrets(self.name, **kwargs)
1889
+
1890
+ def import_secret(
1891
+ self,
1892
+ file: str,
1893
+ **kwargs,
1894
+ ) -> Secret:
1895
+ """
1896
+ Import object from a YAML file.
1897
+
1898
+ Parameters
1899
+ ----------
1900
+ file : str
1901
+ Path to YAML file.
1902
+ **kwargs : dict
1903
+ Parameters to pass to the API call.
1904
+
1905
+ Returns
1906
+ -------
1907
+ Secret
1908
+ Object instance.
1909
+
1910
+ Examples
1911
+ --------
1912
+ >>> obj = project.import_secret("my-secret.yaml")
1913
+ """
1914
+ return import_secret(file, **kwargs)
1915
+
1916
+ def update_secret(self, entity: Secret) -> Secret:
1917
+ """
1918
+ Update object. Note that object spec are immutable.
1919
+
1920
+ Parameters
1921
+ ----------
1922
+ entity : Secret
1923
+ Object to update.
1924
+
1925
+ Returns
1926
+ -------
1927
+ Secret
1928
+ Entity updated.
1929
+
1930
+ Examples
1931
+ --------
1932
+ >>> obj = project.update_secret(obj)
1933
+ """
1934
+ if entity.project != self.name:
1935
+ raise ValueError(f"Entity {entity.name} is not in project {self.name}.")
1936
+ return update_secret(entity)
1937
+
1938
+ def delete_secret(
1939
+ self,
1940
+ identifier: str,
1941
+ entity_id: str | None = None,
1942
+ delete_all_versions: bool = False,
1943
+ **kwargs,
1944
+ ) -> None:
1945
+ """
1946
+ Delete object from backend.
1947
+
1948
+ Parameters
1949
+ ----------
1950
+ identifier : str
1951
+ Entity key (store://...) or entity name.
1952
+ entity_id : str
1953
+ Entity ID.
1954
+ delete_all_versions : bool
1955
+ Delete all versions of the named entity. If True, use entity name instead of entity key as identifier.
1956
+ **kwargs : dict
1957
+ Parameters to pass to the API call.
1958
+
1959
+ Returns
1960
+ -------
1961
+ dict
1962
+ Response from backend.
1963
+
1964
+ Examples
1965
+ --------
1966
+ If delete_all_versions is False:
1967
+ >>> project.delete_secret("store://my-secret-key")
1968
+
1969
+ Otherwise:
1970
+ >>> project.delete_secret("my-secret-name",
1971
+ >>> delete_all_versions=True)
1972
+ """
1973
+ delete_secret(
1974
+ identifier=identifier,
1975
+ project=self.name,
1976
+ entity_id=entity_id,
1977
+ delete_all_versions=delete_all_versions,
1978
+ **kwargs,
1979
+ )
1980
+ self.refresh()
1981
+
1982
+ ##############################
1983
+ # Runs
1984
+ ##############################
1985
+
1986
+ def get_run(
1987
+ self,
1988
+ identifier: str,
1989
+ **kwargs,
1990
+ ) -> Run:
1991
+ """
1992
+ Get object from backend.
1993
+
1994
+ Parameters
1995
+ ----------
1996
+ identifier : str
1997
+ Entity key (store://...) or entity ID.
1998
+ **kwargs : dict
1999
+ Parameters to pass to the API call.
2000
+
2001
+ Returns
2002
+ -------
2003
+ Run
2004
+ Object instance.
2005
+
2006
+ Examples
2007
+ --------
2008
+ Using entity key:
2009
+ >>> obj = project.get_run("store://my-secret-key")
2010
+
2011
+ Using entity ID:
2012
+ >>> obj = project.get_run("123")
2013
+ """
2014
+ obj = get_run(
2015
+ identifier=identifier,
2016
+ project=self.name,
2017
+ **kwargs,
2018
+ )
2019
+ self.refresh()
2020
+ return obj
2021
+
2022
+ def list_runs(self, **kwargs) -> list[Run]:
2023
+ """
2024
+ List all latest objects from backend.
2025
+
2026
+ Parameters
2027
+ ----------
2028
+ **kwargs : dict
2029
+ Parameters to pass to the API call.
2030
+
2031
+ Returns
2032
+ -------
2033
+ list[Run]
2034
+ List of object instances.
2035
+
2036
+ Examples
2037
+ --------
2038
+ >>> objs = project.list_runs()
2039
+ """
2040
+ if kwargs is None:
2041
+ kwargs = {}
2042
+ return list_runs(self.name, **kwargs)
2043
+
2044
+ def delete_run(
2045
+ self,
2046
+ identifier: str,
2047
+ **kwargs,
2048
+ ) -> None:
2049
+ """
2050
+ Delete run from backend.
2051
+
2052
+ Parameters
2053
+ ----------
2054
+ identifier : str
2055
+ Entity key (store://...) or entity ID.
2056
+ **kwargs : dict
2057
+ Parameters to pass to the API call.
2058
+
2059
+ Returns
2060
+ -------
2061
+ dict
2062
+ Response from backend.
2063
+
2064
+ Examples
2065
+ --------
2066
+ >>> project.delete_run("store://my-run-key")
2067
+
2068
+ """
2069
+ delete_run(
2070
+ identifier=identifier,
2071
+ project=self.name,
2072
+ **kwargs,
2073
+ )
2074
+ self.refresh()
2075
+
2076
+ ##############################
2077
+ # Project methods
2078
+ ##############################