digitalhub 0.14.0b2__py3-none-any.whl → 0.14.0b4__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 (75) hide show
  1. digitalhub/context/builder.py +0 -4
  2. digitalhub/context/context.py +12 -8
  3. digitalhub/entities/_base/_base/entity.py +0 -4
  4. digitalhub/entities/_base/context/entity.py +1 -1
  5. digitalhub/entities/_base/entity/entity.py +0 -8
  6. digitalhub/entities/_base/executable/entity.py +161 -79
  7. digitalhub/entities/_base/material/entity.py +7 -23
  8. digitalhub/entities/_base/material/utils.py +28 -0
  9. digitalhub/entities/_base/unversioned/entity.py +1 -1
  10. digitalhub/entities/_base/versioned/entity.py +1 -1
  11. digitalhub/entities/_commons/enums.py +0 -31
  12. digitalhub/entities/_constructors/_resources.py +151 -0
  13. digitalhub/entities/_constructors/name.py +18 -0
  14. digitalhub/entities/_processors/base/__init__.py +3 -0
  15. digitalhub/entities/_processors/{base.py → base/crud.py} +7 -227
  16. digitalhub/entities/_processors/base/import_export.py +122 -0
  17. digitalhub/entities/_processors/base/processor.py +302 -0
  18. digitalhub/entities/_processors/base/special_ops.py +108 -0
  19. digitalhub/entities/_processors/context/__init__.py +3 -0
  20. digitalhub/entities/_processors/context/crud.py +654 -0
  21. digitalhub/entities/_processors/context/import_export.py +242 -0
  22. digitalhub/entities/_processors/context/material.py +123 -0
  23. digitalhub/entities/_processors/context/processor.py +400 -0
  24. digitalhub/entities/_processors/context/special_ops.py +476 -0
  25. digitalhub/entities/_processors/processors.py +12 -0
  26. digitalhub/entities/_processors/utils.py +2 -1
  27. digitalhub/entities/artifact/crud.py +45 -41
  28. digitalhub/entities/dataitem/crud.py +45 -37
  29. digitalhub/entities/dataitem/table/entity.py +5 -6
  30. digitalhub/entities/function/crud.py +47 -43
  31. digitalhub/entities/model/_base/entity.py +3 -23
  32. digitalhub/entities/model/crud.py +45 -39
  33. digitalhub/entities/project/_base/entity.py +45 -134
  34. digitalhub/entities/project/crud.py +13 -42
  35. digitalhub/entities/run/_base/builder.py +0 -4
  36. digitalhub/entities/run/_base/entity.py +4 -60
  37. digitalhub/entities/run/crud.py +61 -40
  38. digitalhub/entities/secret/_base/entity.py +1 -5
  39. digitalhub/entities/secret/crud.py +14 -42
  40. digitalhub/entities/task/_base/builder.py +0 -4
  41. digitalhub/entities/task/_base/entity.py +1 -1
  42. digitalhub/entities/task/crud.py +47 -44
  43. digitalhub/entities/trigger/_base/entity.py +1 -5
  44. digitalhub/entities/trigger/crud.py +51 -43
  45. digitalhub/entities/workflow/crud.py +47 -40
  46. digitalhub/factory/registry.py +0 -24
  47. digitalhub/stores/client/_base/enums.py +39 -0
  48. digitalhub/stores/client/_base/key_builder.py +1 -1
  49. digitalhub/stores/client/_base/params_builder.py +48 -0
  50. digitalhub/stores/client/dhcore/api_builder.py +2 -1
  51. digitalhub/stores/client/dhcore/client.py +67 -73
  52. digitalhub/stores/client/dhcore/configurator.py +5 -28
  53. digitalhub/stores/client/dhcore/error_parser.py +0 -4
  54. digitalhub/stores/client/dhcore/params_builder.py +130 -75
  55. digitalhub/stores/client/local/api_builder.py +1 -1
  56. digitalhub/stores/client/local/params_builder.py +18 -41
  57. digitalhub/stores/credentials/configurator.py +0 -24
  58. digitalhub/stores/credentials/handler.py +0 -12
  59. digitalhub/stores/credentials/store.py +0 -4
  60. digitalhub/stores/data/_base/store.py +0 -16
  61. digitalhub/stores/data/builder.py +0 -4
  62. digitalhub/stores/data/remote/store.py +0 -4
  63. digitalhub/stores/data/s3/configurator.py +0 -8
  64. digitalhub/stores/data/s3/store.py +8 -17
  65. digitalhub/stores/data/sql/configurator.py +0 -8
  66. digitalhub/stores/data/sql/store.py +0 -4
  67. digitalhub/stores/readers/data/factory.py +0 -8
  68. digitalhub/stores/readers/data/pandas/reader.py +0 -16
  69. digitalhub/utils/io_utils.py +0 -4
  70. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b4.dist-info}/METADATA +1 -1
  71. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b4.dist-info}/RECORD +74 -62
  72. digitalhub/entities/_processors/context.py +0 -1499
  73. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b4.dist-info}/WHEEL +0 -0
  74. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b4.dist-info}/licenses/AUTHORS +0 -0
  75. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b4.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,151 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ ANIMALS = [
8
+ "ant",
9
+ "bear",
10
+ "bee",
11
+ "bison",
12
+ "cat",
13
+ "cheetah",
14
+ "cougar",
15
+ "crane",
16
+ "deer",
17
+ "dolphin",
18
+ "duck",
19
+ "eagle",
20
+ "falcon",
21
+ "finch",
22
+ "fox",
23
+ "frog",
24
+ "gecko",
25
+ "hawk",
26
+ "heron",
27
+ "horse",
28
+ "jaguar",
29
+ "koala",
30
+ "leopard",
31
+ "lion",
32
+ "llama",
33
+ "lynx",
34
+ "mole",
35
+ "moose",
36
+ "otter",
37
+ "owl",
38
+ "panda",
39
+ "penguin",
40
+ "rabbit",
41
+ "robin",
42
+ "seal",
43
+ "shark",
44
+ "sparrow",
45
+ "tiger",
46
+ "tortoise",
47
+ "wolf",
48
+ ]
49
+
50
+ ADJECTIVES = [
51
+ "able",
52
+ "agile",
53
+ "alert",
54
+ "alpha",
55
+ "amber",
56
+ "apex",
57
+ "arctic",
58
+ "atomic",
59
+ "balanced",
60
+ "basic",
61
+ "bold",
62
+ "bright",
63
+ "brisk",
64
+ "calm",
65
+ "clever",
66
+ "clear",
67
+ "cloudy",
68
+ "crisp",
69
+ "curious",
70
+ "cyber",
71
+ "daring",
72
+ "deep",
73
+ "delta",
74
+ "digital",
75
+ "dynamic",
76
+ "early",
77
+ "easy",
78
+ "electric",
79
+ "epic",
80
+ "fast",
81
+ "firm",
82
+ "fluent",
83
+ "focused",
84
+ "fresh",
85
+ "friendly",
86
+ "full",
87
+ "future",
88
+ "gentle",
89
+ "global",
90
+ "golden",
91
+ "grand",
92
+ "great",
93
+ "green",
94
+ "happy",
95
+ "high",
96
+ "honest",
97
+ "hyper",
98
+ "ideal",
99
+ "infinite",
100
+ "inner",
101
+ "instant",
102
+ "keen",
103
+ "kind",
104
+ "known",
105
+ "large",
106
+ "light",
107
+ "linear",
108
+ "logical",
109
+ "lucky",
110
+ "lunar",
111
+ "magic",
112
+ "major",
113
+ "mega",
114
+ "mild",
115
+ "modern",
116
+ "neat",
117
+ "noble",
118
+ "open",
119
+ "outer",
120
+ "peak",
121
+ "perfect",
122
+ "plain",
123
+ "prime",
124
+ "pure",
125
+ "quick",
126
+ "quiet",
127
+ "rapid",
128
+ "rare",
129
+ "ready",
130
+ "real",
131
+ "red",
132
+ "right",
133
+ "safe",
134
+ "sharp",
135
+ "silent",
136
+ "simple",
137
+ "smart",
138
+ "solid",
139
+ "solar",
140
+ "speedy",
141
+ "stable",
142
+ "steady",
143
+ "stellar",
144
+ "strong",
145
+ "swift",
146
+ "true",
147
+ "ultra",
148
+ "vast",
149
+ "vital",
150
+ "wise",
151
+ ]
@@ -4,8 +4,12 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import random
8
+
7
9
  from pydantic import BaseModel, Field
8
10
 
11
+ from digitalhub.entities._constructors._resources import ADJECTIVES, ANIMALS
12
+
9
13
  NAME_REGEX = r"^[a-zA-Z0-9._+-]+$"
10
14
 
11
15
 
@@ -33,3 +37,17 @@ def build_name(name: str) -> str:
33
37
  """
34
38
  NameValidator(name=name)
35
39
  return name
40
+
41
+
42
+ def random_name() -> str:
43
+ """
44
+ Generate a random name.
45
+
46
+ Returns
47
+ -------
48
+ str
49
+ The random name.
50
+ """
51
+ adjective = random.choice(ADJECTIVES)
52
+ animal = random.choice(ANIMALS)
53
+ return f"{adjective}-{animal}"
@@ -0,0 +1,3 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
@@ -5,34 +5,25 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import typing
8
- from warnings import warn
9
8
 
10
9
  from digitalhub.context.api import delete_context
11
- from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
12
10
  from digitalhub.factory.entity import entity_factory
11
+ from digitalhub.stores.client._base.enums import ApiCategories, BackendOperations
13
12
  from digitalhub.stores.client.api import get_client
14
- from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
15
- from digitalhub.utils.io_utils import read_yaml
16
13
 
17
14
  if typing.TYPE_CHECKING:
18
15
  from digitalhub.entities.project._base.entity import Project
19
16
  from digitalhub.stores.client._base.client import Client
20
17
 
21
18
 
22
- class BaseEntityOperationsProcessor:
19
+ class BaseEntityCRUDProcessor:
23
20
  """
24
- Processor for base entity operations.
21
+ Processor for core CRUD operations on base entities.
25
22
 
26
- This class handles CRUD operations and other entity management tasks
27
- for base-level entities (primarily projects). It interacts with the
28
- client layer to perform backend operations and manages entity lifecycle
29
- including creation, reading, updating, deletion, and sharing.
23
+ Handles creation, reading, updating, deletion, and listing of
24
+ base-level entities (primarily projects) within the backend.
30
25
  """
31
26
 
32
- ##############################
33
- # CRUD base entity
34
- ##############################
35
-
36
27
  def _create_base_entity(
37
28
  self,
38
29
  client: Client,
@@ -174,97 +165,6 @@ class BaseEntityOperationsProcessor:
174
165
  obj["local"] = client.is_local()
175
166
  return entity_factory.build_entity_from_dict(obj)
176
167
 
177
- def import_project_entity(
178
- self,
179
- file: str,
180
- **kwargs,
181
- ) -> Project:
182
- """
183
- Import a project entity from a YAML file and create it in the backend.
184
-
185
- Reads project configuration from a YAML file, creates a new project
186
- entity in the backend, and imports any related entities defined
187
- in the file. Raises an error if the project already exists.
188
-
189
- Parameters
190
- ----------
191
- file : str
192
- Path to the YAML file containing project configuration.
193
- **kwargs : dict
194
- Additional parameters including 'local' and 'reset_id' flags.
195
-
196
- Returns
197
- -------
198
- Project
199
- The imported and created project entity.
200
-
201
- Raises
202
- ------
203
- EntityError
204
- If the project already exists in the backend.
205
- """
206
- client = get_client(kwargs.pop("local", False))
207
- obj: dict = read_yaml(file)
208
- obj["status"] = {}
209
- obj["local"] = client.is_local()
210
- ent: Project = entity_factory.build_entity_from_dict(obj)
211
- reset_id = kwargs.pop("reset_id", False)
212
-
213
- try:
214
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
215
- except EntityAlreadyExistsError:
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.")
223
-
224
- # Import related entities
225
- ent._import_entities(obj, reset_id=reset_id)
226
- ent.refresh()
227
- return ent
228
-
229
- def load_project_entity(
230
- self,
231
- file: str,
232
- **kwargs,
233
- ) -> Project:
234
- """
235
- Load a project entity from a YAML file and update it in the backend.
236
-
237
- Reads project configuration from a YAML file and updates an existing
238
- project in the backend. If the project doesn't exist, it creates a
239
- new one. Also loads any related entities defined in the file.
240
-
241
- Parameters
242
- ----------
243
- file : str
244
- Path to the YAML file containing project configuration.
245
- **kwargs : dict
246
- Additional parameters including 'local' flag.
247
-
248
- Returns
249
- -------
250
- Project
251
- The loaded and updated project entity.
252
- """
253
- client = get_client(kwargs.pop("local", False))
254
- obj: dict = read_yaml(file)
255
- obj["local"] = client.is_local()
256
- ent: Project = entity_factory.build_entity_from_dict(obj)
257
-
258
- try:
259
- self._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
260
- except EntityNotExistsError:
261
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
262
-
263
- # Load related entities
264
- ent._load_entities(obj)
265
- ent.refresh()
266
- return ent
267
-
268
168
  def _list_base_entities(
269
169
  self,
270
170
  client: Client,
@@ -464,6 +364,8 @@ class BaseEntityOperationsProcessor:
464
364
 
465
365
  Parameters
466
366
  ----------
367
+ crud_processor : BaseEntityCRUDProcessor
368
+ The CRUD processor instance for entity operations.
467
369
  entity_type : str
468
370
  The type of entity to delete (typically 'project').
469
371
  entity_name : str
@@ -486,125 +388,3 @@ class BaseEntityOperationsProcessor:
486
388
  entity_name,
487
389
  **kwargs,
488
390
  )
489
-
490
- ##############################
491
- # Base entity operations
492
- ##############################
493
-
494
- def _build_base_entity_key(
495
- self,
496
- client: Client,
497
- entity_id: str,
498
- ) -> str:
499
- """
500
- Build a storage key for a base entity.
501
-
502
- Creates a standardized key string that can be used to identify
503
- and store the entity in various contexts.
504
-
505
- Parameters
506
- ----------
507
- client : Client
508
- The client instance to use for key building.
509
- entity_id : str
510
- The unique identifier of the entity.
511
-
512
- Returns
513
- -------
514
- str
515
- The constructed entity key string.
516
- """
517
- return client.build_key(ApiCategories.BASE.value, entity_id)
518
-
519
- def build_project_key(
520
- self,
521
- entity_id: str,
522
- **kwargs,
523
- ) -> str:
524
- """
525
- Build a storage key for a project entity.
526
-
527
- Creates a standardized key string for project identification
528
- and storage, handling both local and remote client contexts.
529
-
530
- Parameters
531
- ----------
532
- entity_id : str
533
- The unique identifier of the project entity.
534
- **kwargs : dict
535
- Additional parameters including 'local' flag.
536
-
537
- Returns
538
- -------
539
- str
540
- The constructed project entity key string.
541
- """
542
- client = get_client(kwargs.pop("local", False))
543
- return self._build_base_entity_key(client, entity_id)
544
-
545
- def share_project_entity(
546
- self,
547
- entity_type: str,
548
- entity_name: str,
549
- **kwargs,
550
- ) -> None:
551
- """
552
- Share or unshare a project entity with a user.
553
-
554
- Manages project access permissions by sharing the project with
555
- a specified user or removing user access. Handles both sharing
556
- and unsharing operations based on the 'unshare' parameter.
557
-
558
- Parameters
559
- ----------
560
- entity_type : str
561
- The type of entity to share (typically 'project').
562
- entity_name : str
563
- The name identifier of the project to share.
564
- **kwargs : dict
565
- Additional parameters including:
566
- - 'user': username to share with/unshare from
567
- - 'unshare': boolean flag for unsharing (default False)
568
- - 'local': boolean flag for local backend
569
-
570
- Returns
571
- -------
572
- None
573
-
574
- Raises
575
- ------
576
- ValueError
577
- If trying to unshare from a user who doesn't have access.
578
- """
579
- client = get_client(kwargs.pop("local", False))
580
- api = client.build_api(
581
- ApiCategories.BASE.value,
582
- BackendOperations.SHARE.value,
583
- entity_type=entity_type,
584
- entity_name=entity_name,
585
- )
586
-
587
- user = kwargs.pop("user", None)
588
- if unshare := kwargs.pop("unshare", False):
589
- users = client.read_object(api, **kwargs)
590
- for u in users:
591
- if u["user"] == user:
592
- kwargs["id"] = u["id"]
593
- break
594
- else:
595
- raise ValueError(f"User '{user}' does not have access to project.")
596
-
597
- kwargs = client.build_parameters(
598
- ApiCategories.BASE.value,
599
- BackendOperations.SHARE.value,
600
- unshare=unshare,
601
- user=user,
602
- **kwargs,
603
- )
604
- if unshare:
605
- client.delete_object(api, **kwargs)
606
- return
607
- client.create_object(api, obj={}, **kwargs)
608
-
609
-
610
- base_processor = BaseEntityOperationsProcessor()
@@ -0,0 +1,122 @@
1
+ # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ import typing
8
+ from warnings import warn
9
+
10
+ from digitalhub.factory.entity import entity_factory
11
+ from digitalhub.stores.client.api import get_client
12
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
13
+ from digitalhub.utils.io_utils import read_yaml
14
+
15
+ if typing.TYPE_CHECKING:
16
+ from digitalhub.entities.project._base.entity import Project
17
+
18
+
19
+ class BaseEntityImportExportProcessor:
20
+ """
21
+ Processor for import and export operations on base entities.
22
+
23
+ Handles loading entities from YAML files and importing/exporting
24
+ entity configurations between local files and the backend.
25
+ """
26
+
27
+ def import_project_entity(
28
+ self,
29
+ crud_processor,
30
+ file: str,
31
+ **kwargs,
32
+ ) -> Project:
33
+ """
34
+ Import a project entity from a YAML file and create it in the backend.
35
+
36
+ Reads project configuration from a YAML file, creates a new project
37
+ entity in the backend, and imports any related entities defined
38
+ in the file. Raises an error if the project already exists.
39
+
40
+ Parameters
41
+ ----------
42
+ crud_processor : BaseEntityCRUDProcessor
43
+ The CRUD processor instance for entity operations.
44
+ file : str
45
+ Path to the YAML file containing project configuration.
46
+ **kwargs : dict
47
+ Additional parameters including 'local' and 'reset_id' flags.
48
+
49
+ Returns
50
+ -------
51
+ Project
52
+ The imported and created project entity.
53
+
54
+ Raises
55
+ ------
56
+ EntityError
57
+ If the project already exists in the backend.
58
+ """
59
+ client = get_client(kwargs.pop("local", False))
60
+ obj: dict = read_yaml(file)
61
+ obj["status"] = {}
62
+ obj["local"] = client.is_local()
63
+ ent: Project = entity_factory.build_entity_from_dict(obj)
64
+ reset_id = kwargs.pop("reset_id", False)
65
+
66
+ try:
67
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
68
+ except EntityAlreadyExistsError:
69
+ msg = f"Entity {ent.name} already exists."
70
+ if reset_id:
71
+ ent._import_entities(obj, reset_id=reset_id)
72
+ warn(f"{msg} Other entities ids have been imported.")
73
+ ent.refresh()
74
+ return ent
75
+ raise EntityError(f"{msg} If you want to update it, use load instead.")
76
+
77
+ # Import related entities
78
+ ent._import_entities(obj, reset_id=reset_id)
79
+ ent.refresh()
80
+ return ent
81
+
82
+ def load_project_entity(
83
+ self,
84
+ crud_processor,
85
+ file: str,
86
+ **kwargs,
87
+ ) -> Project:
88
+ """
89
+ Load a project entity from a YAML file and update it in the backend.
90
+
91
+ Reads project configuration from a YAML file and updates an existing
92
+ project in the backend. If the project doesn't exist, it creates a
93
+ new one. Also loads any related entities defined in the file.
94
+
95
+ Parameters
96
+ ----------
97
+ crud_processor : BaseEntityCRUDProcessor
98
+ The CRUD processor instance for entity operations.
99
+ file : str
100
+ Path to the YAML file containing project configuration.
101
+ **kwargs : dict
102
+ Additional parameters including 'local' flag.
103
+
104
+ Returns
105
+ -------
106
+ Project
107
+ The loaded and updated project entity.
108
+ """
109
+ client = get_client(kwargs.pop("local", False))
110
+ obj: dict = read_yaml(file)
111
+ obj["local"] = client.is_local()
112
+ ent: Project = entity_factory.build_entity_from_dict(obj)
113
+
114
+ try:
115
+ crud_processor._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
116
+ except EntityNotExistsError:
117
+ crud_processor._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
118
+
119
+ # Load related entities
120
+ ent._load_entities(obj)
121
+ ent.refresh()
122
+ return ent