digitalhub 0.10.0b5__py3-none-any.whl → 0.10.0b7__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 (49) 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 +22 -0
  7. digitalhub/client/dhcore/params_builder.py +178 -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/entities/_base/context/entity.py +4 -4
  12. digitalhub/entities/_base/executable/entity.py +2 -2
  13. digitalhub/entities/_base/material/entity.py +3 -3
  14. digitalhub/entities/_base/unversioned/entity.py +2 -2
  15. digitalhub/entities/_base/versioned/entity.py +2 -2
  16. digitalhub/entities/_commons/enums.py +1 -0
  17. digitalhub/entities/_commons/metrics.py +164 -0
  18. digitalhub/entities/_commons/utils.py +0 -26
  19. digitalhub/entities/_processors/base.py +527 -0
  20. digitalhub/entities/{_operations/processor.py → _processors/context.py} +85 -739
  21. digitalhub/entities/_processors/utils.py +158 -0
  22. digitalhub/entities/artifact/crud.py +10 -10
  23. digitalhub/entities/dataitem/crud.py +10 -10
  24. digitalhub/entities/function/crud.py +9 -9
  25. digitalhub/entities/model/_base/entity.py +26 -78
  26. digitalhub/entities/model/_base/status.py +1 -1
  27. digitalhub/entities/model/crud.py +10 -10
  28. digitalhub/entities/project/_base/entity.py +317 -9
  29. digitalhub/entities/project/crud.py +10 -9
  30. digitalhub/entities/run/_base/entity.py +32 -84
  31. digitalhub/entities/run/_base/status.py +1 -1
  32. digitalhub/entities/run/crud.py +8 -8
  33. digitalhub/entities/secret/_base/entity.py +3 -3
  34. digitalhub/entities/secret/crud.py +9 -9
  35. digitalhub/entities/task/_base/entity.py +4 -4
  36. digitalhub/entities/task/_base/models.py +10 -0
  37. digitalhub/entities/task/crud.py +8 -8
  38. digitalhub/entities/workflow/crud.py +9 -9
  39. digitalhub/stores/s3/enums.py +7 -7
  40. digitalhub/stores/sql/enums.py +6 -6
  41. digitalhub/utils/git_utils.py +16 -9
  42. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/METADATA +1 -4
  43. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/RECORD +46 -43
  44. digitalhub/entities/_base/project/entity.py +0 -341
  45. digitalhub/entities/_commons/models.py +0 -13
  46. digitalhub/entities/_operations/__init__.py +0 -0
  47. /digitalhub/entities/{_base/project → _processors}/__init__.py +0 -0
  48. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/WHEEL +0 -0
  49. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/licenses/LICENSE.txt +0 -0
@@ -3,26 +3,26 @@ from __future__ import annotations
3
3
  import typing
4
4
  from typing import Any
5
5
 
6
- from digitalhub.client.api import get_client
7
- from digitalhub.context.api import delete_context, get_context
8
- from digitalhub.entities._commons.enums import ApiCategories, BackendOperations, EntityTypes, Relationship
9
- from digitalhub.entities._commons.utils import get_project_from_key, parse_entity_key
6
+ from digitalhub.entities._commons.enums import ApiCategories, BackendOperations, Relationship
7
+ from digitalhub.entities._processors.utils import (
8
+ get_context_from_identifier,
9
+ get_context_from_project,
10
+ parse_identifier,
11
+ )
10
12
  from digitalhub.factory.api import build_entity_from_dict, build_entity_from_params
11
- from digitalhub.utils.exceptions import ContextError, EntityAlreadyExistsError, EntityError, EntityNotExistsError
13
+ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, EntityNotExistsError
12
14
  from digitalhub.utils.io_utils import read_yaml
13
15
  from digitalhub.utils.types import SourcesOrListOfSources
14
16
 
15
17
  if typing.TYPE_CHECKING:
16
- from digitalhub.client._base.client import Client
17
18
  from digitalhub.context.context import Context
18
19
  from digitalhub.entities._base.context.entity import ContextEntity
19
20
  from digitalhub.entities._base.executable.entity import ExecutableEntity
20
21
  from digitalhub.entities._base.material.entity import MaterialEntity
21
- from digitalhub.entities._base.project.entity import ProjectEntity
22
22
  from digitalhub.entities._base.unversioned.entity import UnversionedEntity
23
23
 
24
24
 
25
- class OperationsProcessor:
25
+ class ContextEntityOperationsProcessor:
26
26
  """
27
27
  Processor for Entity operations.
28
28
 
@@ -31,500 +31,6 @@ class OperationsProcessor:
31
31
  Operations can be CRUD, search, list, etc.
32
32
  """
33
33
 
34
- ##############################
35
- # CRUD base entity
36
- ##############################
37
-
38
- def _create_base_entity(
39
- self,
40
- client: Client,
41
- entity_type: str,
42
- entity_dict: dict,
43
- **kwargs,
44
- ) -> dict:
45
- """
46
- Create object in backend.
47
-
48
- Parameters
49
- ----------
50
- client : Client
51
- Client instance.
52
- entity_type : str
53
- Entity type.
54
- entity_dict : dict
55
- Object instance.
56
- **kwargs : dict
57
- Parameters to pass to the API call.
58
-
59
- Returns
60
- -------
61
- dict
62
- Object instance.
63
- """
64
- api = client.build_api(
65
- ApiCategories.BASE.value,
66
- BackendOperations.CREATE.value,
67
- entity_type=entity_type,
68
- )
69
- return client.create_object(api, entity_dict, **kwargs)
70
-
71
- def create_project_entity(
72
- self,
73
- _entity: ProjectEntity | None = None,
74
- **kwargs,
75
- ) -> ProjectEntity:
76
- """
77
- Create object in backend.
78
-
79
- Parameters
80
- ----------
81
- _entity : ProjectEntity
82
- Object instance.
83
- **kwargs : dict
84
- Parameters to pass to entity builder.
85
-
86
- Returns
87
- -------
88
- Project
89
- Object instance.
90
- """
91
- if _entity is not None:
92
- client = _entity._client
93
- obj = _entity
94
- else:
95
- client = get_client(kwargs.get("local"), kwargs.pop("config", None))
96
- obj = build_entity_from_params(**kwargs)
97
- ent = self._create_base_entity(client, obj.ENTITY_TYPE, obj.to_dict())
98
- ent["local"] = client.is_local()
99
- return build_entity_from_dict(ent)
100
-
101
- def _read_base_entity(
102
- self,
103
- client: Client,
104
- entity_type: str,
105
- entity_name: str,
106
- **kwargs,
107
- ) -> dict:
108
- """
109
- Read object from backend.
110
-
111
- Parameters
112
- ----------
113
- client : Client
114
- Client instance.
115
- entity_type : str
116
- Entity type.
117
- entity_name : str
118
- Entity name.
119
- **kwargs : dict
120
- Parameters to pass to the API call.
121
-
122
- Returns
123
- -------
124
- dict
125
- Object instance.
126
- """
127
- api = client.build_api(
128
- ApiCategories.BASE.value,
129
- BackendOperations.READ.value,
130
- entity_type=entity_type,
131
- entity_name=entity_name,
132
- )
133
- return client.read_object(api, **kwargs)
134
-
135
- def read_project_entity(
136
- self,
137
- entity_type: str,
138
- entity_name: str,
139
- **kwargs,
140
- ) -> ProjectEntity:
141
- """
142
- Read object from backend.
143
-
144
- Parameters
145
- ----------
146
- entity_type : str
147
- Entity type.
148
- entity_name : str
149
- Entity name.
150
- **kwargs : dict
151
- Parameters to pass to entity builder.
152
-
153
- Returns
154
- -------
155
- ProjectEntity
156
- Object instance.
157
- """
158
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
159
- obj = self._read_base_entity(client, entity_type, entity_name, **kwargs)
160
- obj["local"] = client.is_local()
161
- return build_entity_from_dict(obj)
162
-
163
- def import_project_entity(
164
- self,
165
- file: str,
166
- **kwargs,
167
- ) -> ProjectEntity:
168
- """
169
- Import object from a YAML file and create a new object into the backend.
170
-
171
- Parameters
172
- ----------
173
- file : str
174
- Path to YAML file.
175
- **kwargs : dict
176
- Additional keyword arguments.
177
-
178
- Returns
179
- -------
180
- ProjectEntity
181
- Object instance.
182
- """
183
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
184
- obj: dict = read_yaml(file)
185
- obj["status"] = {}
186
- obj["local"] = client.is_local()
187
- ent: ProjectEntity = build_entity_from_dict(obj)
188
-
189
- try:
190
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
191
- except EntityAlreadyExistsError:
192
- raise EntityError(f"Entity {ent.name} already exists. If you want to update it, use load instead.")
193
-
194
- # Import related entities
195
- ent._import_entities(obj)
196
- ent.refresh()
197
- return ent
198
-
199
- def load_project_entity(
200
- self,
201
- file: str,
202
- **kwargs,
203
- ) -> ProjectEntity:
204
- """
205
- Load object from a YAML file and update an existing object into the backend.
206
-
207
- Parameters
208
- ----------
209
- file : str
210
- Path to YAML file.
211
- **kwargs : dict
212
- Additional keyword arguments.
213
-
214
- Returns
215
- -------
216
- ProjectEntity
217
- Object instance.
218
- """
219
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
220
- obj: dict = read_yaml(file)
221
- obj["local"] = client.is_local()
222
- ent: ProjectEntity = build_entity_from_dict(obj)
223
-
224
- try:
225
- self._update_base_entity(ent._client, ent.ENTITY_TYPE, ent.name, ent.to_dict())
226
- except EntityNotExistsError:
227
- self._create_base_entity(ent._client, ent.ENTITY_TYPE, ent.to_dict())
228
-
229
- # Load related entities
230
- ent._load_entities(obj)
231
- ent.refresh()
232
- return ent
233
-
234
- def _list_base_entities(
235
- self,
236
- client: Client,
237
- entity_type: str,
238
- **kwargs,
239
- ) -> list[dict]:
240
- """
241
- List objects from backend.
242
-
243
- Parameters
244
- ----------
245
- client : Client
246
- Client instance.
247
- entity_type : str
248
- Entity type.
249
- **kwargs : dict
250
- Parameters to pass to the API call.
251
-
252
- Returns
253
- -------
254
- list[dict]
255
- List of objects.
256
- """
257
- api = client.build_api(
258
- ApiCategories.BASE.value,
259
- BackendOperations.LIST.value,
260
- entity_type=entity_type,
261
- )
262
- return client.list_objects(api, **kwargs)
263
-
264
- def list_project_entities(
265
- self,
266
- entity_type: str,
267
- **kwargs,
268
- ) -> list[ProjectEntity]:
269
- """
270
- List objects from backend.
271
-
272
- Parameters
273
- ----------
274
- entity_type : str
275
- Entity type.
276
- **kwargs : dict
277
- Parameters to pass to API call.
278
-
279
- Returns
280
- -------
281
- list[ProjectEntity]
282
- List of objects.
283
- """
284
- client = get_client(kwargs.pop("local", False))
285
- objs = self._list_base_entities(client, entity_type, **kwargs)
286
- entities = []
287
- for obj in objs:
288
- obj["local"] = client.is_local()
289
- ent = build_entity_from_dict(obj)
290
- entities.append(ent)
291
- return entities
292
-
293
- def _update_base_entity(
294
- self,
295
- client: Client,
296
- entity_type: str,
297
- entity_name: str,
298
- entity_dict: dict,
299
- **kwargs,
300
- ) -> dict:
301
- """
302
- Update object method.
303
-
304
- Parameters
305
- ----------
306
- client : Client
307
- Client instance.
308
- entity_type : str
309
- Entity type.
310
- entity_name : str
311
- Entity name.
312
- entity_dict : dict
313
- Object instance.
314
- **kwargs : dict
315
- Parameters to pass to the API call.
316
-
317
- Returns
318
- -------
319
- dict
320
- Object instance.
321
- """
322
- api = client.build_api(
323
- ApiCategories.BASE.value,
324
- BackendOperations.UPDATE.value,
325
- entity_type=entity_type,
326
- entity_name=entity_name,
327
- )
328
- return client.update_object(api, entity_dict, **kwargs)
329
-
330
- def update_project_entity(
331
- self,
332
- entity_type: str,
333
- entity_name: str,
334
- entity_dict: dict,
335
- **kwargs,
336
- ) -> ProjectEntity:
337
- """
338
- Update object method.
339
-
340
- Parameters
341
- ----------
342
- entity_type : str
343
- Entity type.
344
- entity_name : str
345
- Entity name.
346
- entity_dict : dict
347
- Object instance.
348
- **kwargs : dict
349
- Parameters to pass to entity builder.
350
-
351
- Returns
352
- -------
353
- ProjectEntity
354
- Object instance.
355
- """
356
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
357
- obj = self._update_base_entity(client, entity_type, entity_name, entity_dict, **kwargs)
358
- obj["local"] = client.is_local()
359
- return build_entity_from_dict(obj)
360
-
361
- def _delete_base_entity(
362
- self,
363
- client: Client,
364
- entity_type: str,
365
- entity_name: str,
366
- **kwargs,
367
- ) -> dict:
368
- """
369
- Delete object method.
370
-
371
- Parameters
372
- ----------
373
- client : Client
374
- Client instance.
375
- entity_type : str
376
- Entity type.
377
- entity_name : str
378
- Entity name.
379
- **kwargs : dict
380
- Parameters to pass to the API call.
381
-
382
- Returns
383
- -------
384
- dict
385
- Response from backend.
386
- """
387
- api = client.build_api(
388
- ApiCategories.BASE.value,
389
- BackendOperations.DELETE.value,
390
- entity_type=entity_type,
391
- entity_name=entity_name,
392
- )
393
- return client.delete_object(api, **kwargs)
394
-
395
- def delete_project_entity(
396
- self,
397
- entity_type: str,
398
- entity_name: str,
399
- **kwargs,
400
- ) -> dict:
401
- """
402
- Delete object method.
403
-
404
- Parameters
405
- ----------
406
- entity_type : str
407
- Entity type.
408
- entity_name : str
409
- Entity name.
410
- **kwargs : dict
411
- Parameters to pass to entity builder.
412
-
413
- Returns
414
- -------
415
- dict
416
- Response from backend.
417
- """
418
- kwargs = self._set_params(**kwargs)
419
- if cascade := kwargs.pop("cascade", None) is not None:
420
- kwargs["params"]["cascade"] = str(cascade).lower()
421
- if kwargs.pop("clean_context", True):
422
- delete_context(entity_name)
423
-
424
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
425
- return self._delete_base_entity(
426
- client,
427
- entity_type,
428
- entity_name,
429
- **kwargs,
430
- )
431
-
432
- ##############################
433
- # Base entity operations
434
- ##############################
435
-
436
- def _build_base_entity_key(
437
- self,
438
- client: Client,
439
- entity_id: str,
440
- ) -> str:
441
- """
442
- Build object key.
443
-
444
- Parameters
445
- ----------
446
- client : Client
447
- Client instance.
448
- entity_id : str
449
- Entity ID.
450
-
451
- Returns
452
- -------
453
- str
454
- Object key.
455
- """
456
- return client.build_key(ApiCategories.BASE.value, entity_id)
457
-
458
- def build_project_key(
459
- self,
460
- entity_id: str,
461
- **kwargs,
462
- ) -> str:
463
- """
464
- Build object key.
465
-
466
- Parameters
467
- ----------
468
- entity_id : str
469
- Entity ID.
470
- **kwargs : dict
471
- Parameters to pass to entity builder.
472
-
473
- Returns
474
- -------
475
- str
476
- Object key.
477
- """
478
- client = get_client(kwargs.pop("local", False))
479
- return self._build_base_entity_key(client, entity_id)
480
-
481
- def share_project_entity(
482
- self,
483
- entity_type: str,
484
- entity_name: str,
485
- **kwargs,
486
- ) -> None:
487
- """
488
- Share object method.
489
-
490
- Parameters
491
- ----------
492
- entity_type : str
493
- Entity type.
494
- entity_name : str
495
- Entity name.
496
- **kwargs : dict
497
- Parameters to pass to entity builder.
498
-
499
- Returns
500
- -------
501
- None
502
- """
503
- client = get_client(kwargs.pop("local", False), kwargs.pop("config", None))
504
- api = client.build_api(
505
- ApiCategories.BASE.value,
506
- BackendOperations.SHARE.value,
507
- entity_type=entity_type,
508
- entity_name=entity_name,
509
- )
510
- user = kwargs.pop("user")
511
- unshare = kwargs.pop("unshare", False)
512
- kwargs = self._set_params(**kwargs)
513
-
514
- # Unshare
515
- if unshare:
516
- users = client.read_object(api, **kwargs)
517
- for u in users:
518
- if u["user"] == user:
519
- kwargs["params"]["id"] = u["id"]
520
- client.delete_object(api, **kwargs)
521
- break
522
- return
523
-
524
- # Share
525
- kwargs["params"]["user"] = user
526
- client.create_object(api, obj={}, **kwargs)
527
-
528
34
  ##############################
529
35
  # CRUD context entity
530
36
  ##############################
@@ -566,7 +72,7 @@ class OperationsProcessor:
566
72
  self,
567
73
  _entity: ContextEntity | None = None,
568
74
  **kwargs,
569
- ) -> dict:
75
+ ) -> ContextEntity:
570
76
  """
571
77
  Create object in backend.
572
78
 
@@ -577,14 +83,14 @@ class OperationsProcessor:
577
83
 
578
84
  Returns
579
85
  -------
580
- dict
86
+ ContextEntity
581
87
  Object instance.
582
88
  """
583
89
  if _entity is not None:
584
90
  context = _entity._context()
585
91
  obj = _entity
586
92
  else:
587
- context = self._get_context(kwargs["project"])
93
+ context = get_context_from_project(kwargs["project"])
588
94
  obj: ContextEntity = build_entity_from_params(**kwargs)
589
95
  new_obj = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
590
96
  return build_entity_from_dict(new_obj)
@@ -607,7 +113,7 @@ class OperationsProcessor:
607
113
  Object instance.
608
114
  """
609
115
  source: SourcesOrListOfSources = kwargs.pop("source")
610
- context = self._get_context(kwargs["project"])
116
+ context = get_context_from_project(kwargs["project"])
611
117
  obj = build_entity_from_params(**kwargs)
612
118
  if context.is_running:
613
119
  obj.add_relationship(Relationship.PRODUCEDBY.value, context.get_run_ctx())
@@ -649,17 +155,22 @@ class OperationsProcessor:
649
155
  dict
650
156
  Object instance.
651
157
  """
652
- project, entity_type, _, entity_name, entity_id = self._parse_identifier(
158
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
653
159
  identifier,
654
160
  project=project,
655
161
  entity_type=entity_type,
656
162
  entity_id=entity_id,
657
163
  )
658
164
 
659
- kwargs = self._set_params(**kwargs)
165
+ if entity_id is None:
166
+ kwargs["entity_name"] = entity_name
167
+ kwargs = context.client.build_parameters(
168
+ ApiCategories.CONTEXT.value,
169
+ BackendOperations.READ.value,
170
+ **kwargs,
171
+ )
660
172
 
661
173
  if entity_id is None:
662
- kwargs["params"]["name"] = entity_name
663
174
  api = context.client.build_api(
664
175
  ApiCategories.CONTEXT.value,
665
176
  BackendOperations.LIST.value,
@@ -706,7 +217,7 @@ class OperationsProcessor:
706
217
  VersionedEntity
707
218
  Object instance.
708
219
  """
709
- context = self._get_context_from_identifier(identifier, project)
220
+ context = get_context_from_identifier(identifier, project)
710
221
  obj = self._read_context_entity(
711
222
  context,
712
223
  identifier,
@@ -780,7 +291,7 @@ class OperationsProcessor:
780
291
  """
781
292
  dict_obj: dict = read_yaml(file)
782
293
  dict_obj["status"] = {}
783
- context = self._get_context(dict_obj["project"])
294
+ context = get_context_from_project(dict_obj["project"])
784
295
  obj = build_entity_from_dict(dict_obj)
785
296
  try:
786
297
  self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
@@ -817,7 +328,7 @@ class OperationsProcessor:
817
328
  exec_dict = dict_obj
818
329
  tsk_dicts = []
819
330
 
820
- context = self._get_context(exec_dict["project"])
331
+ context = get_context_from_project(exec_dict["project"])
821
332
  obj: ExecutableEntity = build_entity_from_dict(exec_dict)
822
333
  try:
823
334
  self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
@@ -846,7 +357,7 @@ class OperationsProcessor:
846
357
  Object instance.
847
358
  """
848
359
  dict_obj: dict = read_yaml(file)
849
- context = self._get_context(dict_obj["project"])
360
+ context = get_context_from_project(dict_obj["project"])
850
361
  obj: ContextEntity = build_entity_from_dict(dict_obj)
851
362
  try:
852
363
  self._update_context_entity(context, obj.ENTITY_TYPE, obj.id, obj.to_dict())
@@ -879,7 +390,7 @@ class OperationsProcessor:
879
390
  exec_dict = dict_obj
880
391
  tsk_dicts = []
881
392
 
882
- context = self._get_context(exec_dict["project"])
393
+ context = get_context_from_project(exec_dict["project"])
883
394
  obj: ExecutableEntity = build_entity_from_dict(exec_dict)
884
395
 
885
396
  try:
@@ -918,15 +429,18 @@ class OperationsProcessor:
918
429
  list[dict]
919
430
  Object instances.
920
431
  """
921
- project, entity_type, _, entity_name, _ = self._parse_identifier(
432
+ project, entity_type, _, entity_name, _ = parse_identifier(
922
433
  identifier,
923
434
  project=project,
924
435
  entity_type=entity_type,
925
436
  )
926
437
 
927
- kwargs = self._set_params(**kwargs)
928
- kwargs["params"]["name"] = entity_name
929
- kwargs["params"]["versions"] = "all"
438
+ kwargs = context.client.build_parameters(
439
+ ApiCategories.CONTEXT.value,
440
+ BackendOperations.READ_ALL_VERSIONS.value,
441
+ entity_name=entity_name,
442
+ **kwargs,
443
+ )
930
444
 
931
445
  api = context.client.build_api(
932
446
  ApiCategories.CONTEXT.value,
@@ -962,7 +476,7 @@ class OperationsProcessor:
962
476
  list[ContextEntity]
963
477
  List of object instances.
964
478
  """
965
- context = self._get_context_from_identifier(identifier, project)
479
+ context = get_context_from_identifier(identifier, project)
966
480
  objs = self._read_context_entity_versions(
967
481
  context,
968
482
  identifier,
@@ -1031,7 +545,7 @@ class OperationsProcessor:
1031
545
  list[ContextEntity]
1032
546
  List of object instances.
1033
547
  """
1034
- context = self._get_context(project)
548
+ context = get_context_from_project(project)
1035
549
  objs = self._list_context_entities(context, entity_type, **kwargs)
1036
550
  objects = []
1037
551
  for o in objs:
@@ -1107,7 +621,7 @@ class OperationsProcessor:
1107
621
  ContextEntity
1108
622
  Object instance.
1109
623
  """
1110
- context = self._get_context(project)
624
+ context = get_context_from_project(project)
1111
625
  obj = self._update_context_entity(
1112
626
  context,
1113
627
  entity_type,
@@ -1149,23 +663,23 @@ class OperationsProcessor:
1149
663
  dict
1150
664
  Response from backend.
1151
665
  """
1152
- if not identifier.startswith("store://"):
1153
- if project is None or entity_type is None:
1154
- raise ValueError("Project must be provided.")
1155
- entity_name = identifier
1156
- else:
1157
- project, _, _, entity_name, entity_id = parse_entity_key(identifier)
1158
-
1159
- kwargs = self._set_params(**kwargs)
1160
- if cascade := kwargs.pop("cascade", None) is not None:
1161
- kwargs["params"]["cascade"] = str(cascade).lower()
666
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
667
+ identifier,
668
+ project=project,
669
+ entity_type=entity_type,
670
+ entity_id=entity_id,
671
+ )
1162
672
 
1163
673
  delete_all_versions: bool = kwargs.pop("delete_all_versions", False)
1164
-
1165
- if not delete_all_versions and entity_id is None:
1166
- raise ValueError(
1167
- "If `delete_all_versions` is False, `entity_id` must be provided, either as an argument or in key `identifier`."
1168
- )
674
+ kwargs = context.client.build_parameters(
675
+ ApiCategories.CONTEXT.value,
676
+ BackendOperations.DELETE.value,
677
+ entity_id=entity_id,
678
+ entity_name=entity_name,
679
+ cascade=kwargs.pop("cascade", None),
680
+ delete_all_versions=delete_all_versions,
681
+ **kwargs,
682
+ )
1169
683
 
1170
684
  if delete_all_versions:
1171
685
  api = context.client.build_api(
@@ -1174,7 +688,6 @@ class OperationsProcessor:
1174
688
  project=context.name,
1175
689
  entity_type=entity_type,
1176
690
  )
1177
- kwargs["params"]["name"] = entity_name
1178
691
  else:
1179
692
  api = context.client.build_api(
1180
693
  ApiCategories.CONTEXT.value,
@@ -1214,7 +727,7 @@ class OperationsProcessor:
1214
727
  dict
1215
728
  Response from backend.
1216
729
  """
1217
- context = self._get_context_from_identifier(identifier, project)
730
+ context = get_context_from_identifier(identifier, project)
1218
731
  return self._delete_context_entity(
1219
732
  context,
1220
733
  identifier,
@@ -1315,7 +828,7 @@ class OperationsProcessor:
1315
828
  str
1316
829
  Object key.
1317
830
  """
1318
- context = self._get_context(project)
831
+ context = get_context_from_project(project)
1319
832
  return self._build_context_entity_key(context, entity_type, entity_kind, entity_name, entity_id)
1320
833
 
1321
834
  def read_secret_data(
@@ -1341,7 +854,7 @@ class OperationsProcessor:
1341
854
  dict
1342
855
  Response from backend.
1343
856
  """
1344
- context = self._get_context(project)
857
+ context = get_context_from_project(project)
1345
858
  api = context.client.build_api(
1346
859
  ApiCategories.CONTEXT.value,
1347
860
  BackendOperations.DATA.value,
@@ -1375,7 +888,7 @@ class OperationsProcessor:
1375
888
  -------
1376
889
  None
1377
890
  """
1378
- context = self._get_context(project)
891
+ context = get_context_from_project(project)
1379
892
  api = context.client.build_api(
1380
893
  ApiCategories.CONTEXT.value,
1381
894
  BackendOperations.DATA.value,
@@ -1410,7 +923,7 @@ class OperationsProcessor:
1410
923
  dict
1411
924
  Response from backend.
1412
925
  """
1413
- context = self._get_context(project)
926
+ context = get_context_from_project(project)
1414
927
  api = context.client.build_api(
1415
928
  ApiCategories.CONTEXT.value,
1416
929
  BackendOperations.LOGS.value,
@@ -1445,7 +958,7 @@ class OperationsProcessor:
1445
958
  -------
1446
959
  None
1447
960
  """
1448
- context = self._get_context(project)
961
+ context = get_context_from_project(project)
1449
962
  api = context.client.build_api(
1450
963
  ApiCategories.CONTEXT.value,
1451
964
  BackendOperations.STOP.value,
@@ -1480,7 +993,7 @@ class OperationsProcessor:
1480
993
  -------
1481
994
  None
1482
995
  """
1483
- context = self._get_context(project)
996
+ context = get_context_from_project(project)
1484
997
  api = context.client.build_api(
1485
998
  ApiCategories.CONTEXT.value,
1486
999
  BackendOperations.RESUME.value,
@@ -1516,7 +1029,7 @@ class OperationsProcessor:
1516
1029
  list[dict]
1517
1030
  Response from backend.
1518
1031
  """
1519
- context = self._get_context(project)
1032
+ context = get_context_from_project(project)
1520
1033
  api = context.client.build_api(
1521
1034
  ApiCategories.CONTEXT.value,
1522
1035
  BackendOperations.FILES.value,
@@ -1554,7 +1067,7 @@ class OperationsProcessor:
1554
1067
  -------
1555
1068
  None
1556
1069
  """
1557
- context = self._get_context(project)
1070
+ context = get_context_from_project(project)
1558
1071
  api = context.client.build_api(
1559
1072
  ApiCategories.CONTEXT.value,
1560
1073
  BackendOperations.FILES.value,
@@ -1591,7 +1104,7 @@ class OperationsProcessor:
1591
1104
  dict
1592
1105
  Response from backend.
1593
1106
  """
1594
- context = self._get_context(project)
1107
+ context = get_context_from_project(project)
1595
1108
  api = context.client.build_api(
1596
1109
  ApiCategories.CONTEXT.value,
1597
1110
  BackendOperations.METRICS.value,
@@ -1629,7 +1142,7 @@ class OperationsProcessor:
1629
1142
  -------
1630
1143
  None
1631
1144
  """
1632
- context = self._get_context(project)
1145
+ context = get_context_from_project(project)
1633
1146
  api = context.client.build_api(
1634
1147
  ApiCategories.CONTEXT.value,
1635
1148
  BackendOperations.METRICS.value,
@@ -1642,7 +1155,7 @@ class OperationsProcessor:
1642
1155
 
1643
1156
  def _search(
1644
1157
  self,
1645
- project: str,
1158
+ context: Context,
1646
1159
  **kwargs,
1647
1160
  ) -> dict:
1648
1161
  """
@@ -1650,8 +1163,8 @@ class OperationsProcessor:
1650
1163
 
1651
1164
  Parameters
1652
1165
  ----------
1653
- project : str
1654
- Project name.
1166
+ context : Context
1167
+ Context instance.
1655
1168
  **kwargs : dict
1656
1169
  Parameters to pass to the API call.
1657
1170
 
@@ -1660,13 +1173,18 @@ class OperationsProcessor:
1660
1173
  dict
1661
1174
  Response from backend.
1662
1175
  """
1663
- context = self._get_context(project)
1176
+ kwargs = context.client.build_parameters(
1177
+ ApiCategories.CONTEXT.value,
1178
+ BackendOperations.SEARCH.value,
1179
+ **kwargs,
1180
+ )
1664
1181
  api = context.client.build_api(
1665
1182
  ApiCategories.CONTEXT.value,
1666
1183
  BackendOperations.SEARCH.value,
1667
1184
  project=context.name,
1668
1185
  )
1669
- return context.client.read_object(api, **kwargs)
1186
+ entities_dict = context.client.read_object(api, **kwargs)
1187
+ return [self.read_context_entity(entity["key"]) for entity in entities_dict["content"]]
1670
1188
 
1671
1189
  def search_entity(
1672
1190
  self,
@@ -1712,191 +1230,19 @@ class OperationsProcessor:
1712
1230
  list[ContextEntity]
1713
1231
  List of object instances.
1714
1232
  """
1715
- context = self._get_context(project)
1716
-
1717
- kwargs = self._set_params(**kwargs)
1718
-
1719
- # Add search query
1720
- if query is not None:
1721
- kwargs["params"]["q"] = query
1722
-
1723
- # Add search filters
1724
- fq = []
1725
-
1726
- # Entity types
1727
- if entity_types is not None:
1728
- if len(entity_types) == 1:
1729
- entity_types = entity_types[0]
1730
- else:
1731
- entity_types = " OR ".join(entity_types)
1732
- fq.append(f"type:({entity_types})")
1733
-
1734
- # Name
1735
- if name is not None:
1736
- fq.append(f'metadata.name:"{name}"')
1737
-
1738
- # Kind
1739
- if kind is not None:
1740
- fq.append(f'kind:"{kind}"')
1741
-
1742
- # Time
1743
- created = created if created is not None else "*"
1744
- updated = updated if updated is not None else "*"
1745
- fq.append(f"metadata.updated:[{created} TO {updated}]")
1746
-
1747
- # Description
1748
- if description is not None:
1749
- fq.append(f'metadata.description:"{description}"')
1750
-
1751
- # Labels
1752
- if labels is not None:
1753
- if len(labels) == 1:
1754
- labels = labels[0]
1755
- else:
1756
- labels = " AND ".join(labels)
1757
- fq.append(f"metadata.labels:({labels})")
1758
-
1759
- # Add filters
1760
- kwargs["params"]["fq"] = fq
1761
-
1762
- objs = self._search(context, **kwargs)
1763
- return objs
1764
- return [build_entity_from_dict(obj) for obj in objs]
1765
-
1766
- ##############################
1767
- # Helpers
1768
- ##############################
1769
-
1770
- @staticmethod
1771
- def _parse_identifier(
1772
- identifier: str,
1773
- project: str | None = None,
1774
- entity_type: str | None = None,
1775
- entity_kind: str | None = None,
1776
- entity_id: str | None = None,
1777
- ) -> tuple[str, str, str, str | None, str]:
1778
- """
1779
- Parse entity identifier.
1780
-
1781
- Parameters
1782
- ----------
1783
- identifier : str
1784
- Entity key (store://...) or entity name.
1785
- project : str
1786
- Project name.
1787
- entity_type : str
1788
- Entity type.
1789
- entity_id : str
1790
- Entity ID.
1791
-
1792
- Returns
1793
- -------
1794
- tuple[str, str, str, str | None, str]
1795
- Project name, entity type, entity kind, entity name, entity ID.
1796
- """
1797
- if not identifier.startswith("store://"):
1798
- if project is None or entity_type is None:
1799
- raise ValueError("Project and entity type must be specified.")
1800
- return project, entity_type, entity_kind, identifier, entity_id
1801
- return parse_entity_key(identifier)
1802
-
1803
- @staticmethod
1804
- def _set_params(**kwargs) -> dict:
1805
- """
1806
- Format params parameter.
1807
-
1808
- Parameters
1809
- ----------
1810
- **kwargs : dict
1811
- Keyword arguments.
1812
-
1813
- Returns
1814
- -------
1815
- dict
1816
- Parameters with initialized params.
1817
- """
1818
- if not kwargs:
1819
- kwargs = {}
1820
- if "params" not in kwargs:
1821
- kwargs["params"] = {}
1822
- return kwargs
1823
-
1824
- def _get_context_from_identifier(
1825
- self,
1826
- identifier: str,
1827
- project: str | None = None,
1828
- ) -> Context:
1829
- """
1830
- Get context from project.
1831
-
1832
- Parameters
1833
- ----------
1834
- identifier : str
1835
- Entity key (store://...) or entity name.
1836
- project : str
1837
- Project name.
1838
-
1839
- Returns
1840
- -------
1841
- Context
1842
- Context.
1843
- """
1844
- if not identifier.startswith("store://"):
1845
- if project is None:
1846
- raise EntityError("Specify project if you do not specify entity key.")
1847
- else:
1848
- project = get_project_from_key(identifier)
1849
-
1850
- return self._get_context(project)
1851
-
1852
- def _get_context(
1853
- self,
1854
- project: str,
1855
- ) -> Context:
1856
- """
1857
- Check if the given project is in the context.
1858
- Otherwise try to get the project from remote.
1859
- Finally return the client.
1860
-
1861
- Parameters
1862
- ----------
1863
- project : str
1864
- Project name.
1865
-
1866
- Returns
1867
- -------
1868
- Context
1869
- Context.
1870
- """
1871
- try:
1872
- return get_context(project)
1873
- except ContextError:
1874
- return self._get_context_from_remote(project)
1875
-
1876
- def _get_context_from_remote(
1877
- self,
1878
- project: str,
1879
- ) -> Client:
1880
- """
1881
- Get context from remote.
1882
-
1883
- Parameters
1884
- ----------
1885
- project : str
1886
- Project name.
1887
-
1888
- Returns
1889
- -------
1890
- Client
1891
- Client.
1892
- """
1893
- try:
1894
- client = get_client()
1895
- obj = self._read_base_entity(client, EntityTypes.PROJECT.value, project)
1896
- build_entity_from_dict(obj)
1897
- return get_context(project)
1898
- except EntityNotExistsError:
1899
- raise ContextError(f"Project '{project}' not found.")
1233
+ context = get_context_from_project(project)
1234
+ return self._search(
1235
+ context,
1236
+ query=query,
1237
+ entity_types=entity_types,
1238
+ name=name,
1239
+ kind=kind,
1240
+ created=created,
1241
+ updated=updated,
1242
+ description=description,
1243
+ labels=labels,
1244
+ **kwargs,
1245
+ )
1900
1246
 
1901
1247
 
1902
- processor = OperationsProcessor()
1248
+ context_processor = ContextEntityOperationsProcessor()