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