digitalhub 0.14.0b2__py3-none-any.whl → 0.14.0b3__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 (63) 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 +5 -25
  7. digitalhub/entities/_base/material/entity.py +3 -23
  8. digitalhub/entities/_base/unversioned/entity.py +1 -1
  9. digitalhub/entities/_base/versioned/entity.py +1 -1
  10. digitalhub/entities/_processors/base/__init__.py +3 -0
  11. digitalhub/entities/_processors/{base.py → base/crud.py} +6 -226
  12. digitalhub/entities/_processors/base/import_export.py +122 -0
  13. digitalhub/entities/_processors/base/processor.py +302 -0
  14. digitalhub/entities/_processors/base/special_ops.py +108 -0
  15. digitalhub/entities/_processors/context/__init__.py +3 -0
  16. digitalhub/entities/_processors/context/crud.py +654 -0
  17. digitalhub/entities/_processors/context/import_export.py +242 -0
  18. digitalhub/entities/_processors/context/material.py +123 -0
  19. digitalhub/entities/_processors/context/processor.py +400 -0
  20. digitalhub/entities/_processors/context/special_ops.py +476 -0
  21. digitalhub/entities/_processors/processors.py +12 -0
  22. digitalhub/entities/artifact/crud.py +8 -24
  23. digitalhub/entities/dataitem/crud.py +8 -24
  24. digitalhub/entities/dataitem/table/entity.py +2 -6
  25. digitalhub/entities/function/crud.py +8 -24
  26. digitalhub/entities/model/_base/entity.py +3 -23
  27. digitalhub/entities/model/crud.py +8 -22
  28. digitalhub/entities/project/_base/entity.py +40 -129
  29. digitalhub/entities/project/crud.py +7 -22
  30. digitalhub/entities/run/_base/builder.py +0 -4
  31. digitalhub/entities/run/_base/entity.py +3 -59
  32. digitalhub/entities/run/crud.py +7 -19
  33. digitalhub/entities/secret/_base/entity.py +1 -5
  34. digitalhub/entities/secret/crud.py +8 -22
  35. digitalhub/entities/task/_base/builder.py +0 -4
  36. digitalhub/entities/task/_base/entity.py +1 -1
  37. digitalhub/entities/task/crud.py +7 -19
  38. digitalhub/entities/trigger/_base/entity.py +1 -5
  39. digitalhub/entities/trigger/crud.py +8 -24
  40. digitalhub/entities/workflow/crud.py +8 -24
  41. digitalhub/factory/registry.py +0 -24
  42. digitalhub/stores/client/dhcore/client.py +0 -18
  43. digitalhub/stores/client/dhcore/configurator.py +5 -28
  44. digitalhub/stores/client/dhcore/error_parser.py +0 -4
  45. digitalhub/stores/credentials/configurator.py +0 -24
  46. digitalhub/stores/credentials/handler.py +0 -12
  47. digitalhub/stores/credentials/store.py +0 -4
  48. digitalhub/stores/data/_base/store.py +0 -16
  49. digitalhub/stores/data/builder.py +0 -4
  50. digitalhub/stores/data/remote/store.py +0 -4
  51. digitalhub/stores/data/s3/configurator.py +0 -8
  52. digitalhub/stores/data/s3/store.py +0 -12
  53. digitalhub/stores/data/sql/configurator.py +0 -8
  54. digitalhub/stores/data/sql/store.py +0 -4
  55. digitalhub/stores/readers/data/factory.py +0 -8
  56. digitalhub/stores/readers/data/pandas/reader.py +0 -16
  57. digitalhub/utils/io_utils.py +0 -4
  58. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b3.dist-info}/METADATA +1 -1
  59. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b3.dist-info}/RECORD +62 -52
  60. digitalhub/entities/_processors/context.py +0 -1499
  61. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b3.dist-info}/WHEEL +0 -0
  62. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b3.dist-info}/licenses/AUTHORS +0 -0
  63. {digitalhub-0.14.0b2.dist-info → digitalhub-0.14.0b3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,654 @@
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
+
9
+ from digitalhub.entities._commons.enums import ApiCategories, BackendOperations
10
+ from digitalhub.entities._processors.utils import (
11
+ get_context_from_identifier,
12
+ get_context_from_project,
13
+ parse_identifier,
14
+ )
15
+ from digitalhub.factory.entity import entity_factory
16
+
17
+ if typing.TYPE_CHECKING:
18
+ from digitalhub.context.context import Context
19
+ from digitalhub.entities._base.context.entity import ContextEntity
20
+ from digitalhub.entities._base.unversioned.entity import UnversionedEntity
21
+
22
+
23
+ class ContextEntityCRUDProcessor:
24
+ """
25
+ Processor for core CRUD operations on context entities.
26
+
27
+ Handles creation, reading, updating, deletion, and listing of
28
+ context-level entities within projects.
29
+ """
30
+
31
+ def _create_context_entity(
32
+ self,
33
+ context: Context,
34
+ entity_type: str,
35
+ entity_dict: dict,
36
+ ) -> dict:
37
+ """
38
+ Create a context entity in the backend.
39
+
40
+ Builds the appropriate API endpoint and sends a create request
41
+ to the backend for context-level entities within a project.
42
+
43
+ Parameters
44
+ ----------
45
+ context : Context
46
+ The project context instance.
47
+ entity_type : str
48
+ The type of entity to create (e.g., 'artifact', 'function').
49
+ entity_dict : dict
50
+ The entity data dictionary to create.
51
+
52
+ Returns
53
+ -------
54
+ dict
55
+ The created entity data returned from the backend.
56
+ """
57
+ api = context.client.build_api(
58
+ ApiCategories.CONTEXT.value,
59
+ BackendOperations.CREATE.value,
60
+ project=context.name,
61
+ entity_type=entity_type,
62
+ )
63
+ return context.client.create_object(api, entity_dict)
64
+
65
+ def create_context_entity(
66
+ self,
67
+ _entity: ContextEntity | None = None,
68
+ **kwargs,
69
+ ) -> ContextEntity:
70
+ """
71
+ Create a context entity in the backend.
72
+
73
+ Creates a new context entity either from an existing entity object
74
+ or by building one from the provided parameters. Handles entity
75
+ creation within a project context.
76
+
77
+ Parameters
78
+ ----------
79
+ _entity : ContextEntity, optional
80
+ An existing context entity object to create. If None,
81
+ a new entity will be built from kwargs.
82
+ **kwargs : dict
83
+ Parameters for entity creation, including 'project' and
84
+ entity-specific parameters.
85
+
86
+ Returns
87
+ -------
88
+ ContextEntity
89
+ The created context entity with backend data populated.
90
+ """
91
+ if _entity is not None:
92
+ context = _entity._context()
93
+ obj = _entity
94
+ else:
95
+ context = get_context_from_project(kwargs["project"])
96
+ obj: ContextEntity = entity_factory.build_entity_from_params(**kwargs)
97
+ new_obj = self._create_context_entity(context, obj.ENTITY_TYPE, obj.to_dict())
98
+ return entity_factory.build_entity_from_dict(new_obj)
99
+
100
+ def _read_context_entity(
101
+ self,
102
+ context: Context,
103
+ identifier: str,
104
+ entity_type: str | None = None,
105
+ project: str | None = None,
106
+ entity_id: str | None = None,
107
+ **kwargs,
108
+ ) -> dict:
109
+ """
110
+ Read a context entity from the backend.
111
+
112
+ Retrieves entity data from the backend using either entity ID
113
+ for direct access or entity name for latest version lookup.
114
+ Handles both specific version reads and latest version queries.
115
+
116
+ Parameters
117
+ ----------
118
+ context : Context
119
+ The project context instance.
120
+ identifier : str
121
+ Entity key (store://...) or entity name identifier.
122
+ entity_type : str, optional
123
+ The type of entity to read.
124
+ project : str, optional
125
+ Project name (used for identifier parsing).
126
+ entity_id : str, optional
127
+ Specific entity ID to read.
128
+ **kwargs : dict
129
+ Additional parameters to pass to the API call.
130
+
131
+ Returns
132
+ -------
133
+ dict
134
+ The entity data retrieved from the backend.
135
+ """
136
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
137
+ identifier,
138
+ project=project,
139
+ entity_type=entity_type,
140
+ entity_id=entity_id,
141
+ )
142
+
143
+ if entity_id is None:
144
+ kwargs["entity_name"] = entity_name
145
+ kwargs = context.client.build_parameters(
146
+ ApiCategories.CONTEXT.value,
147
+ BackendOperations.READ.value,
148
+ **kwargs,
149
+ )
150
+
151
+ if entity_id is None:
152
+ api = context.client.build_api(
153
+ ApiCategories.CONTEXT.value,
154
+ BackendOperations.LIST.value,
155
+ project=context.name,
156
+ entity_type=entity_type,
157
+ )
158
+ return context.client.list_first_object(api, **kwargs)
159
+
160
+ api = context.client.build_api(
161
+ ApiCategories.CONTEXT.value,
162
+ BackendOperations.READ.value,
163
+ project=context.name,
164
+ entity_type=entity_type,
165
+ entity_id=entity_id,
166
+ )
167
+ return context.client.read_object(api, **kwargs)
168
+
169
+ def read_context_entity(
170
+ self,
171
+ identifier: str,
172
+ entity_type: str | None = None,
173
+ project: str | None = None,
174
+ entity_id: str | None = None,
175
+ **kwargs,
176
+ ) -> ContextEntity:
177
+ """
178
+ Read a context entity from the backend.
179
+
180
+ Retrieves entity data from the backend and constructs a context
181
+ entity object. Handles post-processing for metrics and file info.
182
+
183
+ Parameters
184
+ ----------
185
+ identifier : str
186
+ Entity key (store://...) or entity name identifier.
187
+ entity_type : str, optional
188
+ The type of entity to read.
189
+ project : str, optional
190
+ Project name for context resolution.
191
+ entity_id : str, optional
192
+ Specific entity ID to read.
193
+ **kwargs : dict
194
+ Additional parameters to pass to the API call.
195
+
196
+ Returns
197
+ -------
198
+ ContextEntity
199
+ The context entity object populated with backend data.
200
+ """
201
+ context = get_context_from_identifier(identifier, project)
202
+ obj = self._read_context_entity(
203
+ context,
204
+ identifier,
205
+ entity_type=entity_type,
206
+ project=project,
207
+ entity_id=entity_id,
208
+ **kwargs,
209
+ )
210
+ entity = entity_factory.build_entity_from_dict(obj)
211
+ return self._post_process_get(entity)
212
+
213
+ def read_unversioned_entity(
214
+ self,
215
+ identifier: str,
216
+ entity_type: str | None = None,
217
+ project: str | None = None,
218
+ entity_id: str | None = None,
219
+ **kwargs,
220
+ ) -> UnversionedEntity:
221
+ """
222
+ Read an unversioned entity from the backend.
223
+
224
+ Retrieves unversioned entity data (runs, tasks) from the backend.
225
+ Handles identifier parsing for entities that don't follow the
226
+ standard versioned naming convention.
227
+
228
+ Parameters
229
+ ----------
230
+ identifier : str
231
+ Entity key (store://...) or entity ID.
232
+ entity_type : str, optional
233
+ The type of entity to read.
234
+ project : str, optional
235
+ Project name for context resolution.
236
+ entity_id : str, optional
237
+ Specific entity ID to read.
238
+ **kwargs : dict
239
+ Additional parameters to pass to the API call.
240
+
241
+ Returns
242
+ -------
243
+ UnversionedEntity
244
+ The unversioned entity object populated with backend data.
245
+ """
246
+ from digitalhub.entities._commons.utils import is_valid_key
247
+
248
+ if not is_valid_key(identifier):
249
+ entity_id = identifier
250
+ else:
251
+ splt = identifier.split(":")
252
+ if len(splt) == 3:
253
+ identifier = f"{splt[0]}:{splt[1]}"
254
+ return self.read_context_entity(
255
+ identifier,
256
+ entity_type=entity_type,
257
+ project=project,
258
+ entity_id=entity_id,
259
+ **kwargs,
260
+ )
261
+
262
+ def _read_context_entity_versions(
263
+ self,
264
+ context: Context,
265
+ identifier: str,
266
+ entity_type: str | None = None,
267
+ project: str | None = None,
268
+ **kwargs,
269
+ ) -> list[dict]:
270
+ """
271
+ Read all versions of a context entity from the backend.
272
+
273
+ Retrieves all available versions of a named entity from the
274
+ backend using the entity name identifier.
275
+
276
+ Parameters
277
+ ----------
278
+ context : Context
279
+ The project context instance.
280
+ identifier : str
281
+ Entity key (store://...) or entity name identifier.
282
+ entity_type : str, optional
283
+ The type of entity to read versions for.
284
+ project : str, optional
285
+ Project name (used for identifier parsing).
286
+ **kwargs : dict
287
+ Additional parameters to pass to the API call.
288
+
289
+ Returns
290
+ -------
291
+ list[dict]
292
+ List of entity data dictionaries for all versions.
293
+ """
294
+ project, entity_type, _, entity_name, _ = parse_identifier(
295
+ identifier,
296
+ project=project,
297
+ entity_type=entity_type,
298
+ )
299
+
300
+ kwargs = context.client.build_parameters(
301
+ ApiCategories.CONTEXT.value,
302
+ BackendOperations.READ_ALL_VERSIONS.value,
303
+ entity_name=entity_name,
304
+ **kwargs,
305
+ )
306
+
307
+ api = context.client.build_api(
308
+ ApiCategories.CONTEXT.value,
309
+ BackendOperations.LIST.value,
310
+ project=context.name,
311
+ entity_type=entity_type,
312
+ )
313
+ return context.client.list_objects(api, **kwargs)
314
+
315
+ def read_context_entity_versions(
316
+ self,
317
+ identifier: str,
318
+ entity_type: str | None = None,
319
+ project: str | None = None,
320
+ **kwargs,
321
+ ) -> list[ContextEntity]:
322
+ """
323
+ Read all versions of a context entity from the backend.
324
+
325
+ Retrieves all available versions of a named entity and constructs
326
+ context entity objects for each version. Applies post-processing
327
+ for metrics and file info.
328
+
329
+ Parameters
330
+ ----------
331
+ identifier : str
332
+ Entity key (store://...) or entity name identifier.
333
+ entity_type : str, optional
334
+ The type of entity to read versions for.
335
+ project : str, optional
336
+ Project name for context resolution.
337
+ **kwargs : dict
338
+ Additional parameters to pass to the API call.
339
+
340
+ Returns
341
+ -------
342
+ list[ContextEntity]
343
+ List of context entity objects for all versions.
344
+ """
345
+ context = get_context_from_identifier(identifier, project)
346
+ objs = self._read_context_entity_versions(
347
+ context,
348
+ identifier,
349
+ entity_type=entity_type,
350
+ project=project,
351
+ **kwargs,
352
+ )
353
+ objects = []
354
+ for o in objs:
355
+ entity: ContextEntity = entity_factory.build_entity_from_dict(o)
356
+ entity = self._post_process_get(entity)
357
+ objects.append(entity)
358
+ return objects
359
+
360
+ def _list_context_entities(
361
+ self,
362
+ context: Context,
363
+ entity_type: str,
364
+ **kwargs,
365
+ ) -> list[dict]:
366
+ """
367
+ List context entities from the backend.
368
+
369
+ Retrieves a list of entities of a specific type from the backend
370
+ within the project context.
371
+
372
+ Parameters
373
+ ----------
374
+ context : Context
375
+ The project context instance.
376
+ entity_type : str
377
+ The type of entities to list.
378
+ **kwargs : dict
379
+ Additional parameters to pass to the API call for filtering
380
+ or pagination.
381
+
382
+ Returns
383
+ -------
384
+ list[dict]
385
+ List of entity data dictionaries from the backend.
386
+ """
387
+ api = context.client.build_api(
388
+ ApiCategories.CONTEXT.value,
389
+ BackendOperations.LIST.value,
390
+ project=context.name,
391
+ entity_type=entity_type,
392
+ )
393
+ return context.client.list_objects(api, **kwargs)
394
+
395
+ def list_context_entities(
396
+ self,
397
+ project: str,
398
+ entity_type: str,
399
+ **kwargs,
400
+ ) -> list[ContextEntity]:
401
+ """
402
+ List all latest version context entities from the backend.
403
+
404
+ Retrieves a list of entities of a specific type from the backend
405
+ and constructs context entity objects. Only returns the latest
406
+ version of each entity. Applies post-processing for metrics and
407
+ file info.
408
+
409
+ Parameters
410
+ ----------
411
+ project : str
412
+ The project name to list entities from.
413
+ entity_type : str
414
+ The type of entities to list.
415
+ **kwargs : dict
416
+ Additional parameters to pass to the API call for filtering
417
+ or pagination.
418
+
419
+ Returns
420
+ -------
421
+ list[ContextEntity]
422
+ List of context entity objects (latest versions only).
423
+ """
424
+ context = get_context_from_project(project)
425
+ objs = self._list_context_entities(context, entity_type, **kwargs)
426
+ objects = []
427
+ for o in objs:
428
+ entity: ContextEntity = entity_factory.build_entity_from_dict(o)
429
+ entity = self._post_process_get(entity)
430
+ objects.append(entity)
431
+ return objects
432
+
433
+ def _update_context_entity(
434
+ self,
435
+ context: Context,
436
+ entity_type: str,
437
+ entity_id: str,
438
+ entity_dict: dict,
439
+ **kwargs,
440
+ ) -> dict:
441
+ """
442
+ Update a context entity in the backend.
443
+
444
+ Updates an existing context entity with new data. Entity
445
+ specifications are typically immutable, so this primarily
446
+ updates status and metadata.
447
+
448
+ Parameters
449
+ ----------
450
+ context : Context
451
+ The project context instance.
452
+ entity_type : str
453
+ The type of entity to update.
454
+ entity_id : str
455
+ The unique identifier of the entity to update.
456
+ entity_dict : dict
457
+ The updated entity data dictionary.
458
+ **kwargs : dict
459
+ Additional parameters to pass to the API call.
460
+
461
+ Returns
462
+ -------
463
+ dict
464
+ Response data from the backend update operation.
465
+ """
466
+ api = context.client.build_api(
467
+ ApiCategories.CONTEXT.value,
468
+ BackendOperations.UPDATE.value,
469
+ project=context.name,
470
+ entity_type=entity_type,
471
+ entity_id=entity_id,
472
+ )
473
+ return context.client.update_object(api, entity_dict, **kwargs)
474
+
475
+ def update_context_entity(
476
+ self,
477
+ project: str,
478
+ entity_type: str,
479
+ entity_id: str,
480
+ entity_dict: dict,
481
+ **kwargs,
482
+ ) -> ContextEntity:
483
+ """
484
+ Update a context entity in the backend.
485
+
486
+ Updates an existing context entity with new data and returns
487
+ the updated context entity object. Entity specifications are
488
+ typically immutable.
489
+
490
+ Parameters
491
+ ----------
492
+ project : str
493
+ The project name containing the entity.
494
+ entity_type : str
495
+ The type of entity to update.
496
+ entity_id : str
497
+ The unique identifier of the entity to update.
498
+ entity_dict : dict
499
+ The updated entity data dictionary.
500
+ **kwargs : dict
501
+ Additional parameters to pass to the API call.
502
+
503
+ Returns
504
+ -------
505
+ ContextEntity
506
+ The updated context entity object.
507
+ """
508
+ context = get_context_from_project(project)
509
+ obj = self._update_context_entity(
510
+ context,
511
+ entity_type,
512
+ entity_id,
513
+ entity_dict,
514
+ **kwargs,
515
+ )
516
+ return entity_factory.build_entity_from_dict(obj)
517
+
518
+ def _delete_context_entity(
519
+ self,
520
+ context: Context,
521
+ identifier: str,
522
+ entity_type: str | None = None,
523
+ project: str | None = None,
524
+ entity_id: str | None = None,
525
+ **kwargs,
526
+ ) -> dict:
527
+ """
528
+ Delete a context entity from the backend.
529
+
530
+ Removes an entity from the backend, with options for deleting
531
+ specific versions or all versions of a named entity. Handles
532
+ cascade deletion if supported.
533
+
534
+ Parameters
535
+ ----------
536
+ context : Context
537
+ The project context instance.
538
+ identifier : str
539
+ Entity key (store://...) or entity name identifier.
540
+ entity_type : str, optional
541
+ The type of entity to delete.
542
+ project : str, optional
543
+ Project name (used for identifier parsing).
544
+ entity_id : str, optional
545
+ Specific entity ID to delete.
546
+ **kwargs : dict
547
+ Additional parameters including:
548
+ - 'delete_all_versions': delete all versions of named entity
549
+ - 'cascade': cascade deletion options
550
+
551
+ Returns
552
+ -------
553
+ dict
554
+ Response data from the backend delete operation.
555
+ """
556
+ project, entity_type, _, entity_name, entity_id = parse_identifier(
557
+ identifier,
558
+ project=project,
559
+ entity_type=entity_type,
560
+ entity_id=entity_id,
561
+ )
562
+
563
+ delete_all_versions: bool = kwargs.pop("delete_all_versions", False)
564
+ kwargs = context.client.build_parameters(
565
+ ApiCategories.CONTEXT.value,
566
+ BackendOperations.DELETE.value,
567
+ entity_id=entity_id,
568
+ entity_name=entity_name,
569
+ cascade=kwargs.pop("cascade", None),
570
+ delete_all_versions=delete_all_versions,
571
+ **kwargs,
572
+ )
573
+
574
+ if delete_all_versions:
575
+ api = context.client.build_api(
576
+ ApiCategories.CONTEXT.value,
577
+ BackendOperations.LIST.value,
578
+ project=context.name,
579
+ entity_type=entity_type,
580
+ )
581
+ else:
582
+ api = context.client.build_api(
583
+ ApiCategories.CONTEXT.value,
584
+ BackendOperations.DELETE.value,
585
+ project=context.name,
586
+ entity_type=entity_type,
587
+ entity_id=entity_id,
588
+ )
589
+ return context.client.delete_object(api, **kwargs)
590
+
591
+ def delete_context_entity(
592
+ self,
593
+ identifier: str,
594
+ project: str | None = None,
595
+ entity_type: str | None = None,
596
+ entity_id: str | None = None,
597
+ **kwargs,
598
+ ) -> dict:
599
+ """
600
+ Delete a context entity from the backend.
601
+
602
+ Removes an entity from the backend with support for deleting
603
+ specific versions or all versions of a named entity.
604
+
605
+ Parameters
606
+ ----------
607
+ identifier : str
608
+ Entity key (store://...) or entity name identifier.
609
+ project : str, optional
610
+ Project name for context resolution.
611
+ entity_type : str, optional
612
+ The type of entity to delete.
613
+ entity_id : str, optional
614
+ Specific entity ID to delete.
615
+ **kwargs : dict
616
+ Additional parameters including deletion options.
617
+
618
+ Returns
619
+ -------
620
+ dict
621
+ Response data from the backend delete operation.
622
+ """
623
+ context = get_context_from_identifier(identifier, project)
624
+ return self._delete_context_entity(
625
+ context,
626
+ identifier,
627
+ entity_type,
628
+ context.name,
629
+ entity_id,
630
+ **kwargs,
631
+ )
632
+
633
+ def _post_process_get(self, entity: ContextEntity) -> ContextEntity:
634
+ """
635
+ Post-process a retrieved context entity.
636
+
637
+ Applies additional processing to entities after retrieval,
638
+ including loading metrics and file information if available.
639
+
640
+ Parameters
641
+ ----------
642
+ entity : ContextEntity
643
+ The entity to post-process.
644
+
645
+ Returns
646
+ -------
647
+ ContextEntity
648
+ The post-processed entity with additional data loaded.
649
+ """
650
+ if hasattr(entity.status, "metrics"):
651
+ entity._get_metrics()
652
+ if hasattr(entity.status, "files"):
653
+ entity._get_files_info()
654
+ return entity