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
@@ -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
- if not identifier.startswith("store://"):
653
- if project is None or entity_type is None:
654
- raise ValueError("Project and entity type must be specified.")
655
- entity_name = identifier
656
- else:
657
- project, entity_type, _, entity_name, entity_id = parse_entity_key(identifier)
158
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
159
+ identifier,
160
+ project=project,
161
+ entity_type=entity_type,
162
+ entity_id=entity_id,
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,16 +429,18 @@ class OperationsProcessor:
918
429
  list[dict]
919
430
  Object instances.
920
431
  """
921
- if not identifier.startswith("store://"):
922
- if project is None or entity_type is None:
923
- raise ValueError("Project and entity type must be specified.")
924
- entity_name = identifier
925
- else:
926
- project, entity_type, _, entity_name, _ = parse_entity_key(identifier)
432
+ project, entity_type, _, entity_name, _ = parse_identifier(
433
+ identifier,
434
+ project=project,
435
+ entity_type=entity_type,
436
+ )
927
437
 
928
- kwargs = self._set_params(**kwargs)
929
- kwargs["params"]["name"] = entity_name
930
- kwargs["params"]["versions"] = "all"
438
+ kwargs = context.client.build_parameters(
439
+ ApiCategories.CONTEXT.value,
440
+ BackendOperations.READ.value,
441
+ entity_name=entity_name,
442
+ **kwargs,
443
+ )
931
444
 
932
445
  api = context.client.build_api(
933
446
  ApiCategories.CONTEXT.value,
@@ -963,7 +476,7 @@ class OperationsProcessor:
963
476
  list[ContextEntity]
964
477
  List of object instances.
965
478
  """
966
- context = self._get_context_from_identifier(identifier, project)
479
+ context = get_context_from_identifier(identifier, project)
967
480
  objs = self._read_context_entity_versions(
968
481
  context,
969
482
  identifier,
@@ -1032,7 +545,7 @@ class OperationsProcessor:
1032
545
  list[ContextEntity]
1033
546
  List of object instances.
1034
547
  """
1035
- context = self._get_context(project)
548
+ context = get_context_from_project(project)
1036
549
  objs = self._list_context_entities(context, entity_type, **kwargs)
1037
550
  objects = []
1038
551
  for o in objs:
@@ -1108,7 +621,7 @@ class OperationsProcessor:
1108
621
  ContextEntity
1109
622
  Object instance.
1110
623
  """
1111
- context = self._get_context(project)
624
+ context = get_context_from_project(project)
1112
625
  obj = self._update_context_entity(
1113
626
  context,
1114
627
  entity_type,
@@ -1150,23 +663,23 @@ class OperationsProcessor:
1150
663
  dict
1151
664
  Response from backend.
1152
665
  """
1153
- if not identifier.startswith("store://"):
1154
- if project is None or entity_type is None:
1155
- raise ValueError("Project must be provided.")
1156
- entity_name = identifier
1157
- else:
1158
- project, _, _, entity_name, entity_id = parse_entity_key(identifier)
1159
-
1160
- kwargs = self._set_params(**kwargs)
1161
- if cascade := kwargs.pop("cascade", None) is not None:
1162
- 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
+ )
1163
672
 
1164
673
  delete_all_versions: bool = kwargs.pop("delete_all_versions", False)
1165
-
1166
- if not delete_all_versions and entity_id is None:
1167
- raise ValueError(
1168
- "If `delete_all_versions` is False, `entity_id` must be provided, either as an argument or in key `identifier`."
1169
- )
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
+ )
1170
683
 
1171
684
  if delete_all_versions:
1172
685
  api = context.client.build_api(
@@ -1175,7 +688,6 @@ class OperationsProcessor:
1175
688
  project=context.name,
1176
689
  entity_type=entity_type,
1177
690
  )
1178
- kwargs["params"]["name"] = entity_name
1179
691
  else:
1180
692
  api = context.client.build_api(
1181
693
  ApiCategories.CONTEXT.value,
@@ -1215,7 +727,7 @@ class OperationsProcessor:
1215
727
  dict
1216
728
  Response from backend.
1217
729
  """
1218
- context = self._get_context_from_identifier(identifier, project)
730
+ context = get_context_from_identifier(identifier, project)
1219
731
  return self._delete_context_entity(
1220
732
  context,
1221
733
  identifier,
@@ -1316,7 +828,7 @@ class OperationsProcessor:
1316
828
  str
1317
829
  Object key.
1318
830
  """
1319
- context = self._get_context(project)
831
+ context = get_context_from_project(project)
1320
832
  return self._build_context_entity_key(context, entity_type, entity_kind, entity_name, entity_id)
1321
833
 
1322
834
  def read_secret_data(
@@ -1342,7 +854,7 @@ class OperationsProcessor:
1342
854
  dict
1343
855
  Response from backend.
1344
856
  """
1345
- context = self._get_context(project)
857
+ context = get_context_from_project(project)
1346
858
  api = context.client.build_api(
1347
859
  ApiCategories.CONTEXT.value,
1348
860
  BackendOperations.DATA.value,
@@ -1376,7 +888,7 @@ class OperationsProcessor:
1376
888
  -------
1377
889
  None
1378
890
  """
1379
- context = self._get_context(project)
891
+ context = get_context_from_project(project)
1380
892
  api = context.client.build_api(
1381
893
  ApiCategories.CONTEXT.value,
1382
894
  BackendOperations.DATA.value,
@@ -1411,7 +923,7 @@ class OperationsProcessor:
1411
923
  dict
1412
924
  Response from backend.
1413
925
  """
1414
- context = self._get_context(project)
926
+ context = get_context_from_project(project)
1415
927
  api = context.client.build_api(
1416
928
  ApiCategories.CONTEXT.value,
1417
929
  BackendOperations.LOGS.value,
@@ -1446,7 +958,7 @@ class OperationsProcessor:
1446
958
  -------
1447
959
  None
1448
960
  """
1449
- context = self._get_context(project)
961
+ context = get_context_from_project(project)
1450
962
  api = context.client.build_api(
1451
963
  ApiCategories.CONTEXT.value,
1452
964
  BackendOperations.STOP.value,
@@ -1481,7 +993,7 @@ class OperationsProcessor:
1481
993
  -------
1482
994
  None
1483
995
  """
1484
- context = self._get_context(project)
996
+ context = get_context_from_project(project)
1485
997
  api = context.client.build_api(
1486
998
  ApiCategories.CONTEXT.value,
1487
999
  BackendOperations.RESUME.value,
@@ -1517,7 +1029,7 @@ class OperationsProcessor:
1517
1029
  list[dict]
1518
1030
  Response from backend.
1519
1031
  """
1520
- context = self._get_context(project)
1032
+ context = get_context_from_project(project)
1521
1033
  api = context.client.build_api(
1522
1034
  ApiCategories.CONTEXT.value,
1523
1035
  BackendOperations.FILES.value,
@@ -1555,7 +1067,7 @@ class OperationsProcessor:
1555
1067
  -------
1556
1068
  None
1557
1069
  """
1558
- context = self._get_context(project)
1070
+ context = get_context_from_project(project)
1559
1071
  api = context.client.build_api(
1560
1072
  ApiCategories.CONTEXT.value,
1561
1073
  BackendOperations.FILES.value,
@@ -1592,7 +1104,7 @@ class OperationsProcessor:
1592
1104
  dict
1593
1105
  Response from backend.
1594
1106
  """
1595
- context = self._get_context(project)
1107
+ context = get_context_from_project(project)
1596
1108
  api = context.client.build_api(
1597
1109
  ApiCategories.CONTEXT.value,
1598
1110
  BackendOperations.METRICS.value,
@@ -1630,7 +1142,7 @@ class OperationsProcessor:
1630
1142
  -------
1631
1143
  None
1632
1144
  """
1633
- context = self._get_context(project)
1145
+ context = get_context_from_project(project)
1634
1146
  api = context.client.build_api(
1635
1147
  ApiCategories.CONTEXT.value,
1636
1148
  BackendOperations.METRICS.value,
@@ -1643,7 +1155,7 @@ class OperationsProcessor:
1643
1155
 
1644
1156
  def _search(
1645
1157
  self,
1646
- project: str,
1158
+ context: Context,
1647
1159
  **kwargs,
1648
1160
  ) -> dict:
1649
1161
  """
@@ -1651,8 +1163,8 @@ class OperationsProcessor:
1651
1163
 
1652
1164
  Parameters
1653
1165
  ----------
1654
- project : str
1655
- Project name.
1166
+ context : Context
1167
+ Context instance.
1656
1168
  **kwargs : dict
1657
1169
  Parameters to pass to the API call.
1658
1170
 
@@ -1661,13 +1173,18 @@ class OperationsProcessor:
1661
1173
  dict
1662
1174
  Response from backend.
1663
1175
  """
1664
- context = self._get_context(project)
1176
+ kwargs = context.client.build_parameters(
1177
+ ApiCategories.CONTEXT.value,
1178
+ BackendOperations.SEARCH.value,
1179
+ **kwargs,
1180
+ )
1665
1181
  api = context.client.build_api(
1666
1182
  ApiCategories.CONTEXT.value,
1667
1183
  BackendOperations.SEARCH.value,
1668
1184
  project=context.name,
1669
1185
  )
1670
- 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"]]
1671
1188
 
1672
1189
  def search_entity(
1673
1190
  self,
@@ -1713,158 +1230,19 @@ class OperationsProcessor:
1713
1230
  list[ContextEntity]
1714
1231
  List of object instances.
1715
1232
  """
1716
- context = self._get_context(project)
1717
-
1718
- kwargs = self._set_params(**kwargs)
1719
-
1720
- # Add search query
1721
- if query is not None:
1722
- kwargs["params"]["q"] = query
1723
-
1724
- # Add search filters
1725
- fq = []
1726
-
1727
- # Entity types
1728
- if entity_types is not None:
1729
- if len(entity_types) == 1:
1730
- entity_types = entity_types[0]
1731
- else:
1732
- entity_types = " OR ".join(entity_types)
1733
- fq.append(f"type:({entity_types})")
1734
-
1735
- # Name
1736
- if name is not None:
1737
- fq.append(f'metadata.name:"{name}"')
1738
-
1739
- # Kind
1740
- if kind is not None:
1741
- fq.append(f'kind:"{kind}"')
1742
-
1743
- # Time
1744
- created = created if created is not None else "*"
1745
- updated = updated if updated is not None else "*"
1746
- fq.append(f"metadata.updated:[{created} TO {updated}]")
1747
-
1748
- # Description
1749
- if description is not None:
1750
- fq.append(f'metadata.description:"{description}"')
1751
-
1752
- # Labels
1753
- if labels is not None:
1754
- if len(labels) == 1:
1755
- labels = labels[0]
1756
- else:
1757
- labels = " AND ".join(labels)
1758
- fq.append(f"metadata.labels:({labels})")
1759
-
1760
- # Add filters
1761
- kwargs["params"]["fq"] = fq
1762
-
1763
- objs = self._search(context, **kwargs)
1764
- return objs
1765
- return [build_entity_from_dict(obj) for obj in objs]
1766
-
1767
- ##############################
1768
- # Helpers
1769
- ##############################
1770
-
1771
- @staticmethod
1772
- def _set_params(**kwargs) -> dict:
1773
- """
1774
- Format params parameter.
1775
-
1776
- Parameters
1777
- ----------
1778
- **kwargs : dict
1779
- Keyword arguments.
1780
-
1781
- Returns
1782
- -------
1783
- dict
1784
- Parameters with initialized params.
1785
- """
1786
- if not kwargs:
1787
- kwargs = {}
1788
- if "params" not in kwargs:
1789
- kwargs["params"] = {}
1790
- return kwargs
1791
-
1792
- def _get_context_from_identifier(
1793
- self,
1794
- identifier: str,
1795
- project: str | None = None,
1796
- ) -> Context:
1797
- """
1798
- Get context from project.
1799
-
1800
- Parameters
1801
- ----------
1802
- identifier : str
1803
- Entity key (store://...) or entity name.
1804
- project : str
1805
- Project name.
1806
-
1807
- Returns
1808
- -------
1809
- Context
1810
- Context.
1811
- """
1812
- if not identifier.startswith("store://"):
1813
- if project is None:
1814
- raise EntityError("Specify project if you do not specify entity key.")
1815
- else:
1816
- project = get_project_from_key(identifier)
1817
-
1818
- return self._get_context(project)
1819
-
1820
- def _get_context(
1821
- self,
1822
- project: str,
1823
- ) -> Context:
1824
- """
1825
- Check if the given project is in the context.
1826
- Otherwise try to get the project from remote.
1827
- Finally return the client.
1828
-
1829
- Parameters
1830
- ----------
1831
- project : str
1832
- Project name.
1833
-
1834
- Returns
1835
- -------
1836
- Context
1837
- Context.
1838
- """
1839
- try:
1840
- return get_context(project)
1841
- except ContextError:
1842
- return self._get_context_from_remote(project)
1843
-
1844
- def _get_context_from_remote(
1845
- self,
1846
- project: str,
1847
- ) -> Client:
1848
- """
1849
- Get context from remote.
1850
-
1851
- Parameters
1852
- ----------
1853
- project : str
1854
- Project name.
1855
-
1856
- Returns
1857
- -------
1858
- Client
1859
- Client.
1860
- """
1861
- try:
1862
- client = get_client()
1863
- obj = self._read_base_entity(client, EntityTypes.PROJECT.value, project)
1864
- build_entity_from_dict(obj)
1865
- return get_context(project)
1866
- except EntityNotExistsError:
1867
- 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
+ )
1868
1246
 
1869
1247
 
1870
- processor = OperationsProcessor()
1248
+ context_processor = ContextEntityOperationsProcessor()