digitalhub 0.10.0b4__py3-none-any.whl → 0.10.0b6__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 (56) hide show
  1. digitalhub/client/_base/api_builder.py +1 -1
  2. digitalhub/client/_base/client.py +22 -0
  3. digitalhub/client/_base/params_builder.py +16 -0
  4. digitalhub/client/dhcore/api_builder.py +4 -3
  5. digitalhub/client/dhcore/client.py +4 -0
  6. digitalhub/client/dhcore/configurator.py +26 -4
  7. digitalhub/client/dhcore/params_builder.py +174 -0
  8. digitalhub/client/local/api_builder.py +4 -1
  9. digitalhub/client/local/client.py +6 -0
  10. digitalhub/client/local/params_builder.py +116 -0
  11. digitalhub/configurator/configurator.py +10 -9
  12. digitalhub/entities/_base/context/entity.py +4 -4
  13. digitalhub/entities/_base/executable/entity.py +2 -2
  14. digitalhub/entities/_base/material/entity.py +3 -3
  15. digitalhub/entities/_base/unversioned/entity.py +2 -2
  16. digitalhub/entities/_base/versioned/entity.py +2 -2
  17. digitalhub/entities/_commons/enums.py +1 -0
  18. digitalhub/entities/_commons/metrics.py +164 -0
  19. digitalhub/entities/_commons/types.py +5 -0
  20. digitalhub/entities/_commons/utils.py +0 -26
  21. digitalhub/entities/_processors/base.py +527 -0
  22. digitalhub/entities/{_operations/processor.py → _processors/context.py} +94 -716
  23. digitalhub/entities/_processors/utils.py +158 -0
  24. digitalhub/entities/artifact/crud.py +10 -10
  25. digitalhub/entities/dataitem/crud.py +10 -10
  26. digitalhub/entities/dataitem/utils.py +2 -1
  27. digitalhub/entities/function/crud.py +9 -9
  28. digitalhub/entities/model/_base/entity.py +26 -78
  29. digitalhub/entities/model/_base/status.py +1 -1
  30. digitalhub/entities/model/crud.py +10 -10
  31. digitalhub/entities/project/_base/entity.py +317 -9
  32. digitalhub/entities/project/crud.py +10 -9
  33. digitalhub/entities/run/_base/entity.py +32 -84
  34. digitalhub/entities/run/_base/status.py +1 -1
  35. digitalhub/entities/run/crud.py +8 -8
  36. digitalhub/entities/secret/_base/entity.py +3 -3
  37. digitalhub/entities/secret/crud.py +9 -9
  38. digitalhub/entities/task/_base/entity.py +4 -4
  39. digitalhub/entities/task/_base/models.py +10 -0
  40. digitalhub/entities/task/crud.py +8 -8
  41. digitalhub/entities/workflow/crud.py +9 -9
  42. digitalhub/factory/utils.py +9 -9
  43. digitalhub/readers/data/pandas/reader.py +9 -9
  44. digitalhub/stores/s3/configurator.py +1 -1
  45. digitalhub/stores/sql/configurator.py +1 -1
  46. digitalhub/{readers/data/pandas → utils}/enums.py +1 -1
  47. digitalhub/utils/git_utils.py +16 -9
  48. digitalhub/utils/types.py +0 -1
  49. {digitalhub-0.10.0b4.dist-info → digitalhub-0.10.0b6.dist-info}/METADATA +1 -4
  50. {digitalhub-0.10.0b4.dist-info → digitalhub-0.10.0b6.dist-info}/RECORD +53 -49
  51. digitalhub/entities/_base/project/entity.py +0 -341
  52. digitalhub/entities/_commons/models.py +0 -13
  53. digitalhub/entities/_operations/__init__.py +0 -0
  54. /digitalhub/entities/{_base/project → _processors}/__init__.py +0 -0
  55. {digitalhub-0.10.0b4.dist-info → digitalhub-0.10.0b6.dist-info}/WHEEL +0 -0
  56. {digitalhub-0.10.0b4.dist-info → digitalhub-0.10.0b6.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,527 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+
5
+ from digitalhub.client.api import get_client
6
+ from digitalhub.context.api import delete_context
7
+ from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
8
+ from digitalhub.factory.api import build_entity_from_dict, build_entity_from_params
9
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
10
+ from digitalhub.utils.io_utils import read_yaml
11
+
12
+ if typing.TYPE_CHECKING:
13
+ from digitalhub.client._base.client import Client
14
+ from digitalhub.entities.project._base.entity import Project
15
+
16
+
17
+ class BaseEntityOperationsProcessor:
18
+ """
19
+ Processor for Base Entity operations.
20
+
21
+ This object interacts with the context, check the category of the object,
22
+ and then calls the appropriate method to perform the requested operation.
23
+ Operations can be CRUD, search, list, etc.
24
+ """
25
+
26
+ ##############################
27
+ # CRUD base entity
28
+ ##############################
29
+
30
+ def _create_base_entity(
31
+ self,
32
+ client: Client,
33
+ entity_type: str,
34
+ entity_dict: dict,
35
+ **kwargs,
36
+ ) -> dict:
37
+ """
38
+ Create object in backend.
39
+
40
+ Parameters
41
+ ----------
42
+ client : Client
43
+ Client instance.
44
+ entity_type : str
45
+ Entity type.
46
+ entity_dict : dict
47
+ Object instance.
48
+ **kwargs : dict
49
+ Parameters to pass to the API call.
50
+
51
+ Returns
52
+ -------
53
+ dict
54
+ Object instance.
55
+ """
56
+ api = client.build_api(
57
+ ApiCategories.BASE.value,
58
+ BackendOperations.CREATE.value,
59
+ entity_type=entity_type,
60
+ )
61
+ return client.create_object(api, entity_dict, **kwargs)
62
+
63
+ def create_project_entity(
64
+ self,
65
+ _entity: Project | None = None,
66
+ **kwargs,
67
+ ) -> Project:
68
+ """
69
+ Create object in backend.
70
+
71
+ Parameters
72
+ ----------
73
+ _entity : Project
74
+ Object instance.
75
+ **kwargs : dict
76
+ Parameters to pass to entity builder.
77
+
78
+ Returns
79
+ -------
80
+ Project
81
+ Object instance.
82
+ """
83
+ if _entity is not None:
84
+ client = _entity._client
85
+ obj = _entity
86
+ else:
87
+ client = get_client(kwargs.get("local"), kwargs.pop("config", None))
88
+ obj = build_entity_from_params(**kwargs)
89
+ ent = self._create_base_entity(client, obj.ENTITY_TYPE, obj.to_dict())
90
+ ent["local"] = client.is_local()
91
+ return build_entity_from_dict(ent)
92
+
93
+ def _read_base_entity(
94
+ self,
95
+ client: Client,
96
+ entity_type: str,
97
+ entity_name: str,
98
+ **kwargs,
99
+ ) -> dict:
100
+ """
101
+ Read object from backend.
102
+
103
+ Parameters
104
+ ----------
105
+ client : Client
106
+ Client instance.
107
+ entity_type : str
108
+ Entity type.
109
+ entity_name : str
110
+ Entity name.
111
+ **kwargs : dict
112
+ Parameters to pass to the API call.
113
+
114
+ Returns
115
+ -------
116
+ dict
117
+ Object instance.
118
+ """
119
+ api = client.build_api(
120
+ ApiCategories.BASE.value,
121
+ BackendOperations.READ.value,
122
+ entity_type=entity_type,
123
+ entity_name=entity_name,
124
+ )
125
+ return client.read_object(api, **kwargs)
126
+
127
+ def read_project_entity(
128
+ self,
129
+ entity_type: str,
130
+ entity_name: str,
131
+ **kwargs,
132
+ ) -> Project:
133
+ """
134
+ Read object from backend.
135
+
136
+ Parameters
137
+ ----------
138
+ entity_type : str
139
+ Entity type.
140
+ entity_name : str
141
+ Entity name.
142
+ **kwargs : dict
143
+ Parameters to pass to entity builder.
144
+
145
+ Returns
146
+ -------
147
+ Project
148
+ Object instance.
149
+ """
150
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
151
+ obj = self._read_base_entity(client, entity_type, entity_name, **kwargs)
152
+ obj["local"] = client.is_local()
153
+ return build_entity_from_dict(obj)
154
+
155
+ def import_project_entity(
156
+ self,
157
+ file: str,
158
+ **kwargs,
159
+ ) -> Project:
160
+ """
161
+ Import object from a YAML file and create a new object into the backend.
162
+
163
+ Parameters
164
+ ----------
165
+ file : str
166
+ Path to YAML file.
167
+ **kwargs : dict
168
+ Additional keyword arguments.
169
+
170
+ Returns
171
+ -------
172
+ Project
173
+ Object instance.
174
+ """
175
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
176
+ obj: dict = read_yaml(file)
177
+ obj["status"] = {}
178
+ obj["local"] = client.is_local()
179
+ ent: Project = build_entity_from_dict(obj)
180
+
181
+ try:
182
+ self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
183
+ except EntityAlreadyExistsError:
184
+ raise EntityError(f"Entity {ent.name} already exists. If you want to update it, use load instead.")
185
+
186
+ # Import related entities
187
+ ent._import_entities(obj)
188
+ ent.refresh()
189
+ return ent
190
+
191
+ def load_project_entity(
192
+ self,
193
+ file: str,
194
+ **kwargs,
195
+ ) -> Project:
196
+ """
197
+ Load object from a YAML file and update an existing object into the backend.
198
+
199
+ Parameters
200
+ ----------
201
+ file : str
202
+ Path to YAML file.
203
+ **kwargs : dict
204
+ Additional keyword arguments.
205
+
206
+ Returns
207
+ -------
208
+ Project
209
+ Object instance.
210
+ """
211
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
212
+ obj: dict = read_yaml(file)
213
+ obj["local"] = client.is_local()
214
+ ent: Project = build_entity_from_dict(obj)
215
+
216
+ try:
217
+ self._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
218
+ except EntityNotExistsError:
219
+ self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
220
+
221
+ # Load related entities
222
+ ent._load_entities(obj)
223
+ ent.refresh()
224
+ return ent
225
+
226
+ def _list_base_entities(
227
+ self,
228
+ client: Client,
229
+ entity_type: str,
230
+ **kwargs,
231
+ ) -> list[dict]:
232
+ """
233
+ List objects from backend.
234
+
235
+ Parameters
236
+ ----------
237
+ client : Client
238
+ Client instance.
239
+ entity_type : str
240
+ Entity type.
241
+ **kwargs : dict
242
+ Parameters to pass to the API call.
243
+
244
+ Returns
245
+ -------
246
+ list[dict]
247
+ List of objects.
248
+ """
249
+ api = client.build_api(
250
+ ApiCategories.BASE.value,
251
+ BackendOperations.LIST.value,
252
+ entity_type=entity_type,
253
+ )
254
+ return client.list_objects(api, **kwargs)
255
+
256
+ def list_project_entities(
257
+ self,
258
+ entity_type: str,
259
+ **kwargs,
260
+ ) -> list[Project]:
261
+ """
262
+ List objects from backend.
263
+
264
+ Parameters
265
+ ----------
266
+ entity_type : str
267
+ Entity type.
268
+ **kwargs : dict
269
+ Parameters to pass to API call.
270
+
271
+ Returns
272
+ -------
273
+ list[Project]
274
+ List of objects.
275
+ """
276
+ client = get_client(kwargs.pop("local", False))
277
+ objs = self._list_base_entities(client, entity_type, **kwargs)
278
+ entities = []
279
+ for obj in objs:
280
+ obj["local"] = client.is_local()
281
+ ent = build_entity_from_dict(obj)
282
+ entities.append(ent)
283
+ return entities
284
+
285
+ def _update_base_entity(
286
+ self,
287
+ client: Client,
288
+ entity_type: str,
289
+ entity_name: str,
290
+ entity_dict: dict,
291
+ **kwargs,
292
+ ) -> dict:
293
+ """
294
+ Update object method.
295
+
296
+ Parameters
297
+ ----------
298
+ client : Client
299
+ Client instance.
300
+ entity_type : str
301
+ Entity type.
302
+ entity_name : str
303
+ Entity name.
304
+ entity_dict : dict
305
+ Object instance.
306
+ **kwargs : dict
307
+ Parameters to pass to the API call.
308
+
309
+ Returns
310
+ -------
311
+ dict
312
+ Object instance.
313
+ """
314
+ api = client.build_api(
315
+ ApiCategories.BASE.value,
316
+ BackendOperations.UPDATE.value,
317
+ entity_type=entity_type,
318
+ entity_name=entity_name,
319
+ )
320
+ return client.update_object(api, entity_dict, **kwargs)
321
+
322
+ def update_project_entity(
323
+ self,
324
+ entity_type: str,
325
+ entity_name: str,
326
+ entity_dict: dict,
327
+ **kwargs,
328
+ ) -> Project:
329
+ """
330
+ Update object method.
331
+
332
+ Parameters
333
+ ----------
334
+ entity_type : str
335
+ Entity type.
336
+ entity_name : str
337
+ Entity name.
338
+ entity_dict : dict
339
+ Object instance.
340
+ **kwargs : dict
341
+ Parameters to pass to entity builder.
342
+
343
+ Returns
344
+ -------
345
+ Project
346
+ Object instance.
347
+ """
348
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
349
+ obj = self._update_base_entity(client, entity_type, entity_name, entity_dict, **kwargs)
350
+ obj["local"] = client.is_local()
351
+ return build_entity_from_dict(obj)
352
+
353
+ def _delete_base_entity(
354
+ self,
355
+ client: Client,
356
+ entity_type: str,
357
+ entity_name: str,
358
+ **kwargs,
359
+ ) -> dict:
360
+ """
361
+ Delete object method.
362
+
363
+ Parameters
364
+ ----------
365
+ client : Client
366
+ Client instance.
367
+ entity_type : str
368
+ Entity type.
369
+ entity_name : str
370
+ Entity name.
371
+ **kwargs : dict
372
+ Parameters to pass to the API call.
373
+
374
+ Returns
375
+ -------
376
+ dict
377
+ Response from backend.
378
+ """
379
+ kwargs = client.build_parameters(
380
+ ApiCategories.BASE.value,
381
+ BackendOperations.DELETE.value,
382
+ **kwargs,
383
+ )
384
+ api = client.build_api(
385
+ ApiCategories.BASE.value,
386
+ BackendOperations.DELETE.value,
387
+ entity_type=entity_type,
388
+ entity_name=entity_name,
389
+ )
390
+ return client.delete_object(api, **kwargs)
391
+
392
+ def delete_project_entity(
393
+ self,
394
+ entity_type: str,
395
+ entity_name: str,
396
+ **kwargs,
397
+ ) -> dict:
398
+ """
399
+ Delete object method.
400
+
401
+ Parameters
402
+ ----------
403
+ entity_type : str
404
+ Entity type.
405
+ entity_name : str
406
+ Entity name.
407
+ **kwargs : dict
408
+ Parameters to pass to entity builder.
409
+
410
+ Returns
411
+ -------
412
+ dict
413
+ Response from backend.
414
+ """
415
+ if kwargs.pop("clean_context", True):
416
+ delete_context(entity_name)
417
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
418
+ return self._delete_base_entity(
419
+ client,
420
+ entity_type,
421
+ entity_name,
422
+ **kwargs,
423
+ )
424
+
425
+ ##############################
426
+ # Base entity operations
427
+ ##############################
428
+
429
+ def _build_base_entity_key(
430
+ self,
431
+ client: Client,
432
+ entity_id: str,
433
+ ) -> str:
434
+ """
435
+ Build object key.
436
+
437
+ Parameters
438
+ ----------
439
+ client : Client
440
+ Client instance.
441
+ entity_id : str
442
+ Entity ID.
443
+
444
+ Returns
445
+ -------
446
+ str
447
+ Object key.
448
+ """
449
+ return client.build_key(ApiCategories.BASE.value, entity_id)
450
+
451
+ def build_project_key(
452
+ self,
453
+ entity_id: str,
454
+ **kwargs,
455
+ ) -> str:
456
+ """
457
+ Build object key.
458
+
459
+ Parameters
460
+ ----------
461
+ entity_id : str
462
+ Entity ID.
463
+ **kwargs : dict
464
+ Parameters to pass to entity builder.
465
+
466
+ Returns
467
+ -------
468
+ str
469
+ Object key.
470
+ """
471
+ client = get_client(kwargs.pop("local", False))
472
+ return self._build_base_entity_key(client, entity_id)
473
+
474
+ def share_project_entity(
475
+ self,
476
+ entity_type: str,
477
+ entity_name: str,
478
+ **kwargs,
479
+ ) -> None:
480
+ """
481
+ Share object method.
482
+
483
+ Parameters
484
+ ----------
485
+ entity_type : str
486
+ Entity type.
487
+ entity_name : str
488
+ Entity name.
489
+ **kwargs : dict
490
+ Parameters to pass to entity builder.
491
+
492
+ Returns
493
+ -------
494
+ None
495
+ """
496
+ client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
497
+ api = client.build_api(
498
+ ApiCategories.BASE.value,
499
+ BackendOperations.SHARE.value,
500
+ entity_type=entity_type,
501
+ entity_name=entity_name,
502
+ )
503
+
504
+ user = kwargs.pop("user", None)
505
+ if unshare := kwargs.pop("unshare", False):
506
+ users = client.read_object(api, **kwargs)
507
+ for u in users:
508
+ if u["user"] == user:
509
+ kwargs["id"] = u["id"]
510
+ break
511
+ else:
512
+ raise ValueError(f"User '{user}' does not have access to project.")
513
+
514
+ kwargs = client.build_parameters(
515
+ ApiCategories.BASE.value,
516
+ BackendOperations.SHARE.value,
517
+ unshare=unshare,
518
+ user=user,
519
+ **kwargs,
520
+ )
521
+ if unshare:
522
+ client.delete_object(api, **kwargs)
523
+ return
524
+ client.create_object(api, obj={}, **kwargs)
525
+
526
+
527
+ base_processor = BaseEntityOperationsProcessor()