digitalhub 0.13.0b4__py3-none-any.whl → 0.14.0b0__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 (61) hide show
  1. digitalhub/__init__.py +3 -8
  2. digitalhub/entities/_base/_base/entity.py +0 -11
  3. digitalhub/entities/_base/entity/builder.py +5 -5
  4. digitalhub/entities/_base/executable/entity.py +1 -1
  5. digitalhub/entities/_base/runtime_entity/builder.py +53 -18
  6. digitalhub/entities/_commons/utils.py +64 -21
  7. digitalhub/entities/_processors/base.py +11 -3
  8. digitalhub/entities/_processors/context.py +71 -22
  9. digitalhub/entities/_processors/utils.py +3 -3
  10. digitalhub/entities/artifact/crud.py +20 -4
  11. digitalhub/entities/artifact/utils.py +1 -1
  12. digitalhub/entities/dataitem/crud.py +20 -4
  13. digitalhub/entities/dataitem/table/entity.py +0 -21
  14. digitalhub/entities/dataitem/utils.py +1 -1
  15. digitalhub/entities/function/_base/entity.py +1 -1
  16. digitalhub/entities/function/crud.py +15 -4
  17. digitalhub/entities/model/_base/entity.py +21 -1
  18. digitalhub/entities/model/crud.py +21 -5
  19. digitalhub/entities/model/utils.py +1 -1
  20. digitalhub/entities/project/_base/entity.py +65 -33
  21. digitalhub/entities/project/crud.py +8 -1
  22. digitalhub/entities/run/_base/entity.py +21 -1
  23. digitalhub/entities/run/crud.py +22 -5
  24. digitalhub/entities/secret/crud.py +22 -5
  25. digitalhub/entities/task/crud.py +22 -5
  26. digitalhub/entities/trigger/crud.py +20 -4
  27. digitalhub/entities/workflow/_base/entity.py +1 -1
  28. digitalhub/entities/workflow/crud.py +15 -4
  29. digitalhub/factory/enums.py +18 -0
  30. digitalhub/factory/factory.py +136 -57
  31. digitalhub/factory/utils.py +3 -54
  32. digitalhub/stores/client/api.py +6 -10
  33. digitalhub/stores/client/builder.py +3 -3
  34. digitalhub/stores/client/dhcore/client.py +104 -162
  35. digitalhub/stores/client/dhcore/configurator.py +92 -289
  36. digitalhub/stores/client/dhcore/enums.py +0 -16
  37. digitalhub/stores/client/dhcore/params_builder.py +41 -83
  38. digitalhub/stores/client/dhcore/utils.py +14 -22
  39. digitalhub/stores/client/local/client.py +77 -45
  40. digitalhub/stores/credentials/ini_module.py +0 -16
  41. digitalhub/stores/data/local/store.py +0 -103
  42. digitalhub/stores/data/s3/configurator.py +60 -6
  43. digitalhub/stores/data/s3/store.py +44 -2
  44. digitalhub/stores/data/sql/store.py +15 -0
  45. digitalhub/utils/file_utils.py +0 -17
  46. digitalhub/utils/generic_utils.py +1 -2
  47. digitalhub/utils/store_utils.py +44 -0
  48. {digitalhub-0.13.0b4.dist-info → digitalhub-0.14.0b0.dist-info}/METADATA +3 -2
  49. {digitalhub-0.13.0b4.dist-info → digitalhub-0.14.0b0.dist-info}/RECORD +58 -59
  50. digitalhub/entities/task/_base/utils.py +0 -22
  51. digitalhub/stores/client/dhcore/models.py +0 -40
  52. digitalhub/stores/data/s3/utils.py +0 -78
  53. /digitalhub/entities/{_base/entity/_constructors → _constructors}/__init__.py +0 -0
  54. /digitalhub/entities/{_base/entity/_constructors → _constructors}/metadata.py +0 -0
  55. /digitalhub/entities/{_base/entity/_constructors → _constructors}/name.py +0 -0
  56. /digitalhub/entities/{_base/entity/_constructors → _constructors}/spec.py +0 -0
  57. /digitalhub/entities/{_base/entity/_constructors → _constructors}/status.py +0 -0
  58. /digitalhub/entities/{_base/entity/_constructors → _constructors}/uuid.py +0 -0
  59. {digitalhub-0.13.0b4.dist-info → digitalhub-0.14.0b0.dist-info}/WHEEL +0 -0
  60. {digitalhub-0.13.0b4.dist-info → digitalhub-0.14.0b0.dist-info}/licenses/AUTHORS +0 -0
  61. {digitalhub-0.13.0b4.dist-info → digitalhub-0.14.0b0.dist-info}/licenses/LICENSE +0 -0
digitalhub/__init__.py CHANGED
@@ -95,16 +95,11 @@ from digitalhub.entities.workflow.crud import (
95
95
  new_workflow,
96
96
  update_workflow,
97
97
  )
98
+ from digitalhub.stores.client.dhcore.utils import refresh_token, set_dhcore_env
99
+ from digitalhub.stores.credentials.api import get_current_profile, set_current_profile
100
+ from digitalhub.utils.store_utils import get_s3_client, get_sql_engine
98
101
 
99
102
  try:
100
103
  from digitalhub.entities.model.mlflow.utils import from_mlflow_run, get_mlflow_model_metrics
101
104
  except ImportError:
102
105
  ...
103
-
104
- # Register entities into registry
105
- from digitalhub.factory.utils import register_entities, register_runtimes_entities
106
- from digitalhub.stores.client.dhcore.utils import refresh_token, set_dhcore_env
107
- from digitalhub.stores.credentials.api import get_current_profile, set_current_profile
108
-
109
- register_entities()
110
- register_runtimes_entities()
@@ -63,17 +63,6 @@ class Base:
63
63
  if k not in self.__dict__:
64
64
  setattr(self, k, v)
65
65
 
66
- def _get_private_attrs(self) -> dict:
67
- """
68
- Return all private attributes of the object.
69
-
70
- Returns
71
- -------
72
- dict
73
- A dictionary containing the private attributes of the entity instance.
74
- """
75
- return {k: v for k, v in self.__dict__.items() if k.startswith("_")}
76
-
77
66
  def __repr__(self) -> str:
78
67
  """
79
68
  Return string representation of the entity object.
@@ -7,11 +7,11 @@ from __future__ import annotations
7
7
  import typing
8
8
  from abc import abstractmethod
9
9
 
10
- from digitalhub.entities._base.entity._constructors.metadata import build_metadata
11
- from digitalhub.entities._base.entity._constructors.name import build_name
12
- from digitalhub.entities._base.entity._constructors.spec import build_spec
13
- from digitalhub.entities._base.entity._constructors.status import build_status
14
- from digitalhub.entities._base.entity._constructors.uuid import build_uuid
10
+ from digitalhub.entities._constructors.metadata import build_metadata
11
+ from digitalhub.entities._constructors.name import build_name
12
+ from digitalhub.entities._constructors.spec import build_spec
13
+ from digitalhub.entities._constructors.status import build_status
14
+ from digitalhub.entities._constructors.uuid import build_uuid
15
15
  from digitalhub.utils.exceptions import BuilderError
16
16
 
17
17
  if typing.TYPE_CHECKING:
@@ -430,7 +430,7 @@ class ExecutableEntity(VersionedEntity):
430
430
  task_string = task._get_task_string()
431
431
 
432
432
  # Get run validator for building trigger template
433
- run_kind = factory.get_run_kind(self.kind)
433
+ run_kind = factory.get_run_kind_from_action(self.kind, action)
434
434
  run_validator: SpecValidator = factory.get_spec_validator(run_kind)
435
435
  # Override kwargs
436
436
  kwargs["project"] = self.project
@@ -4,6 +4,7 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ from digitalhub.entities._commons.utils import KindAction
7
8
  from digitalhub.utils.exceptions import EntityError
8
9
 
9
10
 
@@ -13,16 +14,40 @@ class RuntimeEntityBuilder:
13
14
  """
14
15
 
15
16
  EXECUTABLE_KIND: str = None
16
- TASKS_KINDS: dict = None
17
- RUN_KIND: str = None
17
+ TASKS_KINDS: list[KindAction] = None
18
+ RUN_KINDS: list[KindAction] = None
18
19
 
19
20
  def __init__(self) -> None:
20
- if self.EXECUTABLE_KIND is None:
21
- raise EntityError("EXECUTABLE_KIND must be set")
22
- if self.TASKS_KINDS is None:
23
- raise EntityError("TASKS_KINDS must be set")
24
- if self.RUN_KIND is None:
25
- raise EntityError("RUN_KIND must be set")
21
+ self._validate()
22
+
23
+ def _validate(self) -> None:
24
+ """
25
+ Validate the entity.
26
+ """
27
+ for attr_name in ["EXECUTABLE_KIND", "TASKS_KINDS", "RUN_KINDS"]:
28
+ value = getattr(self, attr_name)
29
+ if value is None:
30
+ raise EntityError(f"{attr_name} must be set")
31
+
32
+ for attr_name in ["TASKS_KINDS", "RUN_KINDS"]:
33
+ self._instance_validation(getattr(self, attr_name))
34
+
35
+ def _instance_validation(self, attribute: list[KindAction]) -> None:
36
+ """
37
+ Validate if the attribute is a list of KindAction.
38
+
39
+ Parameters
40
+ ----------
41
+ attribute : list[KindAction]
42
+ Attribute to validate.
43
+ """
44
+ if not isinstance(attribute, list):
45
+ raise EntityError(f"{attribute} must be a list")
46
+ for i in attribute:
47
+ if not isinstance(i, KindAction):
48
+ raise EntityError(f"{attribute} must be a list of KindAction")
49
+ if i.kind is None:
50
+ raise EntityError(f"{attribute} must be a list of KindAction with kind set")
26
51
 
27
52
  def get_action_from_task_kind(self, task_kind: str) -> str:
28
53
  """
@@ -39,8 +64,8 @@ class RuntimeEntityBuilder:
39
64
  Action.
40
65
  """
41
66
  for task in self.TASKS_KINDS:
42
- if task["kind"] == task_kind:
43
- return task["action"]
67
+ if task.kind == task_kind:
68
+ return task.action
44
69
  msg = f"Task kind {task_kind} not allowed."
45
70
  raise EntityError(msg)
46
71
 
@@ -59,21 +84,30 @@ class RuntimeEntityBuilder:
59
84
  Task kinds.
60
85
  """
61
86
  for task in self.TASKS_KINDS:
62
- if task["action"] == action:
63
- return task["kind"]
87
+ if task.action == action:
88
+ return task.kind
64
89
  msg = f"Action {action} not allowed."
65
90
  raise EntityError(msg)
66
91
 
67
- def get_run_kind(self) -> str:
92
+ def get_run_kind_from_action(self, action: str) -> str:
68
93
  """
69
- Get run kind.
94
+ Get run kind from action.
95
+
96
+ Parameters
97
+ ----------
98
+ action : str
99
+ Action.
70
100
 
71
101
  Returns
72
102
  -------
73
103
  str
74
104
  Run kind.
75
105
  """
76
- return self.RUN_KIND
106
+ for run in self.RUN_KINDS:
107
+ if run.action == action:
108
+ return run.kind
109
+ msg = f"Action {action} not allowed."
110
+ raise EntityError(msg)
77
111
 
78
112
  def get_executable_kind(self) -> str:
79
113
  """
@@ -95,8 +129,9 @@ class RuntimeEntityBuilder:
95
129
  list[str]
96
130
  All kinds.
97
131
  """
98
- task_kinds = [i["kind"] for i in self.TASKS_KINDS]
99
- return [self.EXECUTABLE_KIND, self.RUN_KIND, *task_kinds]
132
+ task_kinds = [i.kind for i in self.TASKS_KINDS]
133
+ run_kinds = [i.kind for i in self.RUN_KINDS]
134
+ return [self.EXECUTABLE_KIND, *run_kinds, *task_kinds]
100
135
 
101
136
  def get_all_actions(self) -> list[str]:
102
137
  """
@@ -107,4 +142,4 @@ class RuntimeEntityBuilder:
107
142
  list[str]
108
143
  All actions.
109
144
  """
110
- return [i["action"] for i in self.TASKS_KINDS]
145
+ return [i.action for i in self.TASKS_KINDS]
@@ -4,8 +4,34 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import re
8
+ from collections import namedtuple
9
+
7
10
  from digitalhub.entities._commons.enums import EntityTypes
8
11
 
12
+ KindAction = namedtuple("KindAction", ["kind", "action"])
13
+
14
+
15
+ KEY_PATTERN_WITH_ID = "store://([^/]+)/([^/]+)/([^/]+)/([^:]+):(.+)"
16
+ KEY_PATTERN_NO_ID = "store://([^/]+)/([^/]+)/([^/]+)/([^:]+)"
17
+
18
+
19
+ def is_valid_key(key: str) -> bool:
20
+ """
21
+ Check if an entity key is valid.
22
+
23
+ Parameters
24
+ ----------
25
+ key : str
26
+ The entity key to validate.
27
+
28
+ Returns
29
+ -------
30
+ bool
31
+ True if the key is valid, False otherwise.
32
+ """
33
+ return bool(re.fullmatch(KEY_PATTERN_WITH_ID, key) or re.fullmatch(KEY_PATTERN_NO_ID, key))
34
+
9
35
 
10
36
  def parse_entity_key(key: str) -> tuple[str, str, str, str | None, str]:
11
37
  """
@@ -32,34 +58,34 @@ def parse_entity_key(key: str) -> tuple[str, str, str, str | None, str]:
32
58
  ValueError
33
59
  If the key format is invalid or cannot be parsed.
34
60
  """
35
- try:
36
- # Remove "store://" from the key
37
- key = key.replace("store://", "")
61
+ if not is_valid_key(key):
62
+ raise ValueError("Invalid entity key format.")
38
63
 
39
- # Split the key into parts
40
- parts = key.split("/")
64
+ # Remove "store://" from the key
65
+ key = key.replace("store://", "")
41
66
 
42
- # The project is the first part
43
- project = parts[0]
67
+ # Split the key into parts
68
+ parts = key.split("/")
44
69
 
45
- # The entity type is the second part
46
- entity_type = parts[1]
70
+ # The project is the first part
71
+ project = parts[0]
47
72
 
48
- # The kind is the third part
49
- kind = parts[2]
73
+ # The entity type is the second part
74
+ entity_type = parts[1]
50
75
 
51
- # Tasks and runs have no name and uuid
52
- if entity_type in (EntityTypes.TASK.value, EntityTypes.RUN.value):
53
- name = None
54
- uuid = parts[3]
76
+ # The kind is the third part
77
+ kind = parts[2]
55
78
 
56
- # The name and uuid are separated by a colon in the last part
57
- else:
58
- name, uuid = parts[3].split(":")
79
+ # Tasks and runs have no name and uuid
80
+ if entity_type in (EntityTypes.TASK.value, EntityTypes.RUN.value):
81
+ name = None
82
+ uuid = parts[3]
59
83
 
60
- return project, entity_type, kind, name, uuid
61
- except Exception as e:
62
- raise ValueError("Invalid key format.") from e
84
+ # The name and uuid are separated by a colon in the last part
85
+ else:
86
+ name, uuid = parts[3].split(":")
87
+
88
+ return project, entity_type, kind, name, uuid
63
89
 
64
90
 
65
91
  def get_entity_type_from_key(key: str) -> str:
@@ -112,3 +138,20 @@ def get_project_from_key(key: str) -> str:
112
138
  """
113
139
  project, _, _, _, _ = parse_entity_key(key)
114
140
  return project
141
+
142
+
143
+ def map_actions(kind_action_list: list[tuple[str, str]]) -> list[KindAction]:
144
+ """
145
+ Build task actions as KindAction namedtuples.
146
+
147
+ Parameters
148
+ ----------
149
+ kind_action_list : list[tuple[str, str]]
150
+ List of kind-action couples.
151
+
152
+ Returns
153
+ -------
154
+ list[KindAction]
155
+ Returns the task actions as KindAction namedtuples.
156
+ """
157
+ return [KindAction(kind, action) for (kind, action) in kind_action_list]
@@ -5,6 +5,7 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import typing
8
+ from warnings import warn
8
9
 
9
10
  from digitalhub.context.api import delete_context
10
11
  from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
@@ -190,7 +191,7 @@ class BaseEntityOperationsProcessor:
190
191
  file : str
191
192
  Path to the YAML file containing project configuration.
192
193
  **kwargs : dict
193
- Additional parameters including 'local' flag.
194
+ Additional parameters including 'local' and 'reset_id' flags.
194
195
 
195
196
  Returns
196
197
  -------
@@ -207,14 +208,21 @@ class BaseEntityOperationsProcessor:
207
208
  obj["status"] = {}
208
209
  obj["local"] = client.is_local()
209
210
  ent: Project = factory.build_entity_from_dict(obj)
211
+ reset_id = kwargs.pop("reset_id", False)
210
212
 
211
213
  try:
212
214
  self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
213
215
  except EntityAlreadyExistsError:
214
- raise EntityError(f"Entity {ent.name} already exists. If you want to update it, use load instead.")
216
+ msg = f"Entity {ent.name} already exists."
217
+ if reset_id:
218
+ ent._import_entities(obj, reset_id=reset_id)
219
+ warn(f"{msg} Other entities ids have been imported.")
220
+ ent.refresh()
221
+ return ent
222
+ raise EntityError(f"{msg} If you want to update it, use load instead.")
215
223
 
216
224
  # Import related entities
217
- ent._import_entities(obj)
225
+ ent._import_entities(obj, reset_id=reset_id)
218
226
  ent.refresh()
219
227
  return ent
220
228
 
@@ -8,6 +8,8 @@ import typing
8
8
  from typing import Any
9
9
 
10
10
  from digitalhub.entities._commons.enums import ApiCategories, BackendOperations, Relationship, State
11
+ from digitalhub.entities._commons.utils import is_valid_key
12
+ from digitalhub.entities._constructors.uuid import build_uuid
11
13
  from digitalhub.entities._processors.utils import (
12
14
  get_context_from_identifier,
13
15
  get_context_from_project,
@@ -319,7 +321,7 @@ class ContextEntityOperationsProcessor:
319
321
  UnversionedEntity
320
322
  The unversioned entity object populated with backend data.
321
323
  """
322
- if not identifier.startswith("store://"):
324
+ if not is_valid_key(identifier):
323
325
  entity_id = identifier
324
326
  else:
325
327
  splt = identifier.split(":")
@@ -335,19 +337,25 @@ class ContextEntityOperationsProcessor:
335
337
 
336
338
  def import_context_entity(
337
339
  self,
338
- file: str,
340
+ file: str | None = None,
341
+ key: str | None = None,
342
+ reset_id: bool = False,
343
+ context: str | None = None,
339
344
  ) -> ContextEntity:
340
345
  """
341
- Import a context entity from a YAML file and create it in the backend.
342
-
343
- Reads entity configuration from a YAML file and creates a new
344
- context entity in the backend. Raises an error if the entity
345
- already exists.
346
+ Import a context entity from a YAML file or from a storage key.
346
347
 
347
348
  Parameters
348
349
  ----------
349
350
  file : str
350
351
  Path to the YAML file containing entity configuration.
352
+ key : str
353
+ Storage key (store://...) to read the entity from.
354
+ reset_id : bool
355
+ Flag to determine if the ID of context entities should be reset.
356
+ context : str, optional
357
+ Project name to use for context resolution. If None, uses
358
+ the project specified in the YAML file.
351
359
 
352
360
  Returns
353
361
  -------
@@ -359,32 +367,54 @@ class ContextEntityOperationsProcessor:
359
367
  EntityError
360
368
  If the entity already exists in the backend.
361
369
  """
362
- dict_obj: dict = read_yaml(file)
370
+ if (file is None) == (key is None):
371
+ raise ValueError("Provide key or file, not both or none.")
372
+
373
+ if file is not None:
374
+ dict_obj: dict = read_yaml(file)
375
+ else:
376
+ ctx = get_context_from_identifier(key)
377
+ dict_obj: dict = self._read_context_entity(ctx, key)
378
+
363
379
  dict_obj["status"] = {}
364
- context = get_context_from_project(dict_obj["project"])
380
+
381
+ if context is None:
382
+ context = dict_obj["project"]
383
+
384
+ ctx = get_context_from_project(context)
365
385
  obj = factory.build_entity_from_dict(dict_obj)
386
+ if reset_id:
387
+ new_id = build_uuid()
388
+ obj.id = new_id
389
+ obj.metadata.version = new_id
366
390
  try:
367
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
391
+ bck_obj = self._create_context_entity(ctx, obj.ENTITY_TYPE, obj.to_dict())
392
+ new_obj: ContextEntity = factory.build_entity_from_dict(bck_obj)
368
393
  except EntityAlreadyExistsError:
369
394
  raise EntityError(f"Entity {obj.name} already exists. If you want to update it, use load instead.")
370
- return obj
395
+ return new_obj
371
396
 
372
397
  def import_executable_entity(
373
398
  self,
374
- file: str,
399
+ file: str | None = None,
400
+ key: str | None = None,
401
+ reset_id: bool = False,
402
+ context: str | None = None,
375
403
  ) -> ExecutableEntity:
376
404
  """
377
- Import an executable entity from a YAML file and create it in the backend.
378
-
379
- Reads executable entity configuration from a YAML file and creates
380
- a new executable entity (function or workflow) in the backend.
381
- Also imports associated task definitions if present in the file.
405
+ Import an executable entity from a YAML file or from a storage key.
382
406
 
383
407
  Parameters
384
408
  ----------
385
409
  file : str
386
410
  Path to the YAML file containing executable entity configuration.
387
411
  Can contain a single entity or a list with the executable and tasks.
412
+ key : str
413
+ Storage key (store://...) to read the entity from.
414
+ reset_id : bool
415
+ Flag to determine if the ID of executable entities should be reset.
416
+ context : str, optional
417
+ Project name to use for context resolution.
388
418
 
389
419
  Returns
390
420
  -------
@@ -396,7 +426,15 @@ class ContextEntityOperationsProcessor:
396
426
  EntityError
397
427
  If the entity already exists in the backend.
398
428
  """
399
- dict_obj: dict | list[dict] = read_yaml(file)
429
+ if (file is None) == (key is None):
430
+ raise ValueError("Provide key or file, not both or none.")
431
+
432
+ if file is not None:
433
+ dict_obj: dict | list[dict] = read_yaml(file)
434
+ else:
435
+ ctx = get_context_from_identifier(key)
436
+ dict_obj: dict = self._read_context_entity(ctx, key)
437
+
400
438
  if isinstance(dict_obj, list):
401
439
  exec_dict = dict_obj[0]
402
440
  exec_dict["status"] = {}
@@ -406,18 +444,29 @@ class ContextEntityOperationsProcessor:
406
444
  tsk_dicts.append(i)
407
445
  else:
408
446
  exec_dict = dict_obj
447
+ exec_dict["status"] = {}
409
448
  tsk_dicts = []
410
449
 
411
- context = get_context_from_project(exec_dict["project"])
450
+ if context is None:
451
+ context = exec_dict["project"]
452
+
453
+ ctx = get_context_from_project(context)
412
454
  obj: ExecutableEntity = factory.build_entity_from_dict(exec_dict)
455
+
456
+ if reset_id:
457
+ new_id = build_uuid()
458
+ obj.id = new_id
459
+ obj.metadata.version = new_id
460
+
413
461
  try:
414
- self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
462
+ bck_obj = self._create_context_entity(ctx, obj.ENTITY_TYPE, obj.to_dict())
463
+ new_obj: ExecutableEntity = factory.build_entity_from_dict(bck_obj)
415
464
  except EntityAlreadyExistsError:
416
465
  raise EntityError(f"Entity {obj.name} already exists. If you want to update it, use load instead.")
417
466
 
418
- obj.import_tasks(tsk_dicts)
467
+ new_obj.import_tasks(tsk_dicts)
419
468
 
420
- return obj
469
+ return new_obj
421
470
 
422
471
  def load_context_entity(
423
472
  self,
@@ -8,7 +8,7 @@ import typing
8
8
 
9
9
  from digitalhub.context.api import get_context
10
10
  from digitalhub.entities._commons.enums import ApiCategories, BackendOperations, EntityTypes
11
- from digitalhub.entities._commons.utils import get_project_from_key, parse_entity_key
11
+ from digitalhub.entities._commons.utils import get_project_from_key, is_valid_key, parse_entity_key
12
12
  from digitalhub.factory.factory import factory
13
13
  from digitalhub.stores.client.api import get_client
14
14
  from digitalhub.utils.exceptions import ContextError, EntityError, EntityNotExistsError
@@ -57,7 +57,7 @@ def parse_identifier(
57
57
  ValueError
58
58
  If identifier is not a full key and project or entity_type is None.
59
59
  """
60
- if not identifier.startswith("store://"):
60
+ if not is_valid_key(identifier):
61
61
  if project is None or entity_type is None:
62
62
  raise ValueError("Project and entity type must be specified.")
63
63
  return project, entity_type, entity_kind, identifier, entity_id
@@ -93,7 +93,7 @@ def get_context_from_identifier(
93
93
  EntityError
94
94
  If identifier is not a full key and project parameter is None.
95
95
  """
96
- if not identifier.startswith("store://"):
96
+ if not is_valid_key(identifier):
97
97
  if project is None:
98
98
  raise EntityError("Specify project if you do not specify entity key.")
99
99
  else:
@@ -238,14 +238,25 @@ def list_artifacts(project: str, **kwargs) -> list[Artifact]:
238
238
  )
239
239
 
240
240
 
241
- def import_artifact(file: str) -> Artifact:
241
+ def import_artifact(
242
+ file: str | None = None,
243
+ key: str | None = None,
244
+ reset_id: bool = False,
245
+ context: str | None = None,
246
+ ) -> Artifact:
242
247
  """
243
- Import object from a YAML file and create a new object into the backend.
248
+ Import an object from a YAML file or from a storage key.
244
249
 
245
250
  Parameters
246
251
  ----------
247
252
  file : str
248
- Path to YAML file.
253
+ Path to the YAML file.
254
+ key : str
255
+ Entity key (store://...).
256
+ reset_id : bool
257
+ Flag to determine if the ID of executable entities should be reset.
258
+ context : str
259
+ Project name to use for context resolution.
249
260
 
250
261
  Returns
251
262
  -------
@@ -256,7 +267,12 @@ def import_artifact(file: str) -> Artifact:
256
267
  --------
257
268
  >>> obj = import_artifact("my-artifact.yaml")
258
269
  """
259
- return context_processor.import_context_entity(file)
270
+ return context_processor.import_context_entity(
271
+ file,
272
+ key,
273
+ reset_id,
274
+ context,
275
+ )
260
276
 
261
277
 
262
278
  def load_artifact(file: str) -> Artifact:
@@ -6,9 +6,9 @@ from __future__ import annotations
6
6
 
7
7
  from typing import Any
8
8
 
9
- from digitalhub.entities._base.entity._constructors.uuid import build_uuid
10
9
  from digitalhub.entities._base.material.utils import build_log_path_from_source, eval_local_source
11
10
  from digitalhub.entities._commons.enums import EntityTypes
11
+ from digitalhub.entities._constructors.uuid import build_uuid
12
12
 
13
13
 
14
14
  def eval_source(
@@ -264,14 +264,25 @@ def list_dataitems(project: str, **kwargs) -> list[Dataitem]:
264
264
  )
265
265
 
266
266
 
267
- def import_dataitem(file: str) -> Dataitem:
267
+ def import_dataitem(
268
+ file: str | None = None,
269
+ key: str | None = None,
270
+ reset_id: bool = False,
271
+ context: str | None = None,
272
+ ) -> Dataitem:
268
273
  """
269
- Import object from a YAML file and create a new object into the backend.
274
+ Import an object from a YAML file or from a storage key.
270
275
 
271
276
  Parameters
272
277
  ----------
273
278
  file : str
274
- Path to YAML file.
279
+ Path to the YAML file.
280
+ key : str
281
+ Entity key (store://...).
282
+ reset_id : bool
283
+ Flag to determine if the ID of executable entities should be reset.
284
+ context : str
285
+ Project name to use for context resolution.
275
286
 
276
287
  Returns
277
288
  -------
@@ -282,7 +293,12 @@ def import_dataitem(file: str) -> Dataitem:
282
293
  --------
283
294
  >>> obj = import_dataitem("my-dataitem.yaml")
284
295
  """
285
- return context_processor.import_context_entity(file)
296
+ return context_processor.import_context_entity(
297
+ file,
298
+ key,
299
+ reset_id,
300
+ context,
301
+ )
286
302
 
287
303
 
288
304
  def load_dataitem(file: str) -> Dataitem:
@@ -4,9 +4,7 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- import shutil
8
7
  import typing
9
- from pathlib import Path
10
8
  from typing import Any
11
9
 
12
10
  from digitalhub.entities.dataitem._base.entity import Dataitem
@@ -138,22 +136,3 @@ class DataitemTable(Dataitem):
138
136
  extension=extension,
139
137
  **kwargs,
140
138
  )
141
-
142
- @staticmethod
143
- def _clean_tmp_path(pth: Path | None, clean: bool) -> None:
144
- """
145
- Clean temporary path.
146
-
147
- Parameters
148
- ----------
149
- pth : Path | None
150
- Path to clean.
151
- clean : bool
152
- If True, the path will be cleaned.
153
-
154
- Returns
155
- -------
156
- None
157
- """
158
- if pth is not None and clean:
159
- shutil.rmtree(pth)
@@ -9,9 +9,9 @@ import typing
9
9
  from typing import Any
10
10
 
11
11
  from digitalhub.context.api import get_context
12
- from digitalhub.entities._base.entity._constructors.uuid import build_uuid
13
12
  from digitalhub.entities._base.material.utils import build_log_path_from_source, eval_local_source
14
13
  from digitalhub.entities._commons.enums import EntityKinds, EntityTypes
14
+ from digitalhub.entities._constructors.uuid import build_uuid
15
15
  from digitalhub.stores.data.api import get_store
16
16
  from digitalhub.stores.readers.data.api import get_reader_by_object
17
17
  from digitalhub.utils.enums import FileExtensions