digitalhub 0.14.0b5__py3-none-any.whl → 0.14.9__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.
Files changed (93) hide show
  1. digitalhub/__init__.py +2 -2
  2. digitalhub/context/api.py +43 -6
  3. digitalhub/context/builder.py +1 -1
  4. digitalhub/context/context.py +3 -6
  5. digitalhub/entities/_base/context/entity.py +0 -3
  6. digitalhub/entities/_base/executable/entity.py +29 -11
  7. digitalhub/entities/_base/material/entity.py +2 -2
  8. digitalhub/entities/_base/material/utils.py +0 -4
  9. digitalhub/entities/_commons/enums.py +1 -0
  10. digitalhub/entities/_commons/utils.py +19 -0
  11. digitalhub/entities/_processors/base/crud.py +15 -24
  12. digitalhub/entities/_processors/base/import_export.py +3 -7
  13. digitalhub/entities/_processors/base/processor.py +4 -7
  14. digitalhub/entities/_processors/base/special_ops.py +4 -8
  15. digitalhub/entities/_processors/context/crud.py +27 -29
  16. digitalhub/entities/_processors/context/import_export.py +7 -7
  17. digitalhub/entities/_processors/context/material.py +2 -2
  18. digitalhub/entities/_processors/context/special_ops.py +25 -25
  19. digitalhub/entities/_processors/utils.py +7 -116
  20. digitalhub/entities/artifact/crud.py +3 -3
  21. digitalhub/entities/artifact/utils.py +2 -2
  22. digitalhub/entities/builders.py +2 -0
  23. digitalhub/entities/dataitem/crud.py +3 -3
  24. digitalhub/entities/dataitem/utils.py +10 -14
  25. digitalhub/entities/function/_base/entity.py +0 -3
  26. digitalhub/entities/function/crud.py +3 -3
  27. digitalhub/entities/model/crud.py +3 -3
  28. digitalhub/entities/model/mlflow/utils.py +29 -20
  29. digitalhub/entities/model/utils.py +2 -2
  30. digitalhub/entities/project/_base/builder.py +0 -6
  31. digitalhub/entities/project/_base/entity.py +264 -114
  32. digitalhub/entities/project/_base/spec.py +4 -4
  33. digitalhub/entities/project/crud.py +16 -51
  34. digitalhub/entities/project/utils.py +7 -3
  35. digitalhub/entities/secret/crud.py +2 -2
  36. digitalhub/entities/task/_base/models.py +13 -16
  37. digitalhub/entities/trigger/crud.py +28 -9
  38. digitalhub/entities/workflow/_base/entity.py +0 -5
  39. digitalhub/entities/workflow/crud.py +3 -6
  40. digitalhub/stores/client/{dhcore/api_builder.py → api_builder.py} +2 -3
  41. digitalhub/stores/client/builder.py +20 -32
  42. digitalhub/stores/client/client.py +322 -0
  43. digitalhub/stores/client/{dhcore/configurator.py → configurator.py} +148 -195
  44. digitalhub/stores/client/{_base/enums.py → enums.py} +11 -0
  45. digitalhub/stores/client/header_manager.py +61 -0
  46. digitalhub/stores/client/http_handler.py +152 -0
  47. digitalhub/stores/client/{_base/key_builder.py → key_builder.py} +14 -14
  48. digitalhub/stores/client/{dhcore/params_builder.py → params_builder.py} +51 -12
  49. digitalhub/stores/client/response_processor.py +102 -0
  50. digitalhub/stores/client/utils.py +35 -0
  51. digitalhub/stores/{credentials → configurator}/api.py +5 -9
  52. digitalhub/stores/configurator/configurator.py +123 -0
  53. digitalhub/stores/{credentials → configurator}/enums.py +26 -10
  54. digitalhub/stores/configurator/handler.py +213 -0
  55. digitalhub/stores/{credentials → configurator}/ini_module.py +31 -6
  56. digitalhub/stores/data/_base/store.py +0 -4
  57. digitalhub/stores/data/api.py +4 -6
  58. digitalhub/stores/data/builder.py +6 -38
  59. digitalhub/stores/data/s3/configurator.py +30 -114
  60. digitalhub/stores/data/s3/store.py +9 -22
  61. digitalhub/stores/data/sql/configurator.py +49 -71
  62. digitalhub/stores/data/sql/store.py +26 -61
  63. digitalhub/utils/generic_utils.py +0 -12
  64. digitalhub/utils/git_utils.py +0 -8
  65. digitalhub/utils/io_utils.py +0 -8
  66. digitalhub/utils/store_utils.py +1 -1
  67. {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.9.dist-info}/METADATA +3 -3
  68. {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.9.dist-info}/RECORD +73 -86
  69. {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.9.dist-info}/WHEEL +1 -1
  70. digitalhub/stores/client/_base/api_builder.py +0 -34
  71. digitalhub/stores/client/_base/client.py +0 -243
  72. digitalhub/stores/client/_base/params_builder.py +0 -82
  73. digitalhub/stores/client/api.py +0 -32
  74. digitalhub/stores/client/dhcore/__init__.py +0 -3
  75. digitalhub/stores/client/dhcore/client.py +0 -553
  76. digitalhub/stores/client/dhcore/enums.py +0 -18
  77. digitalhub/stores/client/dhcore/key_builder.py +0 -62
  78. digitalhub/stores/client/dhcore/utils.py +0 -86
  79. digitalhub/stores/client/local/__init__.py +0 -3
  80. digitalhub/stores/client/local/api_builder.py +0 -116
  81. digitalhub/stores/client/local/client.py +0 -605
  82. digitalhub/stores/client/local/enums.py +0 -15
  83. digitalhub/stores/client/local/key_builder.py +0 -62
  84. digitalhub/stores/client/local/params_builder.py +0 -97
  85. digitalhub/stores/credentials/__init__.py +0 -3
  86. digitalhub/stores/credentials/configurator.py +0 -185
  87. digitalhub/stores/credentials/handler.py +0 -164
  88. digitalhub/stores/credentials/store.py +0 -77
  89. digitalhub/stores/data/enums.py +0 -15
  90. /digitalhub/stores/client/{dhcore/error_parser.py → error_parser.py} +0 -0
  91. /digitalhub/stores/{client/_base → configurator}/__init__.py +0 -0
  92. {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.9.dist-info}/licenses/AUTHORS +0 -0
  93. {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,605 +0,0 @@
1
- # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from __future__ import annotations
6
-
7
- from copy import deepcopy
8
- from datetime import datetime, timezone
9
- from typing import Any
10
-
11
- from digitalhub.stores.client._base.client import Client
12
- from digitalhub.stores.client.local.api_builder import ClientLocalApiBuilder
13
- from digitalhub.stores.client.local.enums import LocalClientVar
14
- from digitalhub.stores.client.local.key_builder import ClientLocalKeyBuilder
15
- from digitalhub.stores.client.local.params_builder import ClientLocalParametersBuilder
16
- from digitalhub.utils.exceptions import BackendError
17
-
18
-
19
- class ClientLocal(Client):
20
- """
21
- Local client.
22
-
23
- The Local client can be used when a remote Digitalhub backend is not available.
24
- It handles the creation, reading, updating and deleting of objects in memory,
25
- storing them in a local dictionary.
26
- The functionality of the Local client is almost the same as the DHCore client.
27
- Main differences are:
28
- - Local client does delete objects on cascade.
29
- - The run execution are forced to be local.
30
- """
31
-
32
- def __init__(self) -> None:
33
- super().__init__()
34
- self._api_builder = ClientLocalApiBuilder()
35
- self._key_builder = ClientLocalKeyBuilder()
36
- self._params_builder = ClientLocalParametersBuilder()
37
- self._db: dict[str, dict[str, dict]] = {}
38
-
39
- ##############################
40
- # CRUD
41
- ##############################
42
-
43
- def create_object(self, api: str, obj: Any, **kwargs) -> dict:
44
- """
45
- Create an object in local.
46
-
47
- Parameters
48
- ----------
49
- api : str
50
- Create API.
51
- obj : dict
52
- Object to create.
53
-
54
- Returns
55
- -------
56
- dict
57
- The created object.
58
- """
59
- if api == LocalClientVar.EMPTY.value:
60
- return {}
61
- if not isinstance(obj, dict):
62
- raise TypeError("Object must be a dictionary")
63
-
64
- entity_type, _, context_api = self._parse_api(api)
65
- try:
66
- # Check if entity_type is valid
67
- if entity_type is None:
68
- raise TypeError
69
-
70
- # Check if entity_type exists, if not, create a mapping
71
- self._db.setdefault(entity_type, {})
72
-
73
- # Base API
74
- #
75
- # POST /api/v1/projects
76
- #
77
- # Project are not versioned, everything is stored on "entity_id" key
78
- if not context_api:
79
- if entity_type == "projects":
80
- entity_id = obj["name"]
81
- if entity_id in self._db[entity_type]:
82
- raise ValueError
83
- self._db[entity_type][entity_id] = obj
84
-
85
- # Context API
86
- #
87
- # POST /api/v1/-/<project-name>/artifacts
88
- # POST /api/v1/-/<project-name>/functions
89
- # POST /api/v1/-/<project-name>/runs
90
- #
91
- # Runs and tasks are not versioned, so we keep name as entity_id.
92
- # We have both "name" and "id" attributes for versioned objects so we use them as storage keys.
93
- # The "latest" key is used to store the latest version of the object.
94
- else:
95
- entity_id = obj["id"]
96
- name = obj.get("name", entity_id)
97
- self._db[entity_type].setdefault(name, {})
98
- if entity_id in self._db[entity_type][name]:
99
- raise ValueError
100
- self._db[entity_type][name][entity_id] = obj
101
- self._db[entity_type][name]["latest"] = obj
102
-
103
- # Return the created object
104
- return obj
105
-
106
- # Key error are possibly raised by accessing invalid objects
107
- except (KeyError, TypeError):
108
- msg = self._format_msg(1, entity_type=entity_type)
109
- raise BackendError(msg)
110
-
111
- # If try to create already existing object
112
- except ValueError:
113
- msg = self._format_msg(2, entity_type=entity_type, entity_id=entity_id)
114
- raise BackendError(msg)
115
-
116
- def read_object(self, api: str, **kwargs) -> dict:
117
- """
118
- Get an object from local.
119
-
120
- Parameters
121
- ----------
122
- api : str
123
- Read API.
124
-
125
- Returns
126
- -------
127
- dict
128
- The read object.
129
- """
130
- if api == LocalClientVar.EMPTY.value:
131
- return {}
132
- entity_type, entity_id, context_api = self._parse_api(api)
133
- if entity_id is None:
134
- msg = self._format_msg(4)
135
- raise BackendError(msg)
136
- try:
137
- # Base API
138
- #
139
- # GET /api/v1/projects/<entity_id>
140
- #
141
- # self._parse_api() should return only entity_type
142
-
143
- if not context_api:
144
- obj = self._db[entity_type][entity_id]
145
-
146
- # If the object is a project, we need to add the project spec,
147
- # for example artifacts, functions, workflows, etc.
148
- # Technically we have only projects that access base apis,
149
- # we check entity_type just in case we add something else.
150
- if entity_type == "projects":
151
- obj = self._get_project_spec(obj, entity_id)
152
- return obj
153
-
154
- # Context API
155
- #
156
- # GET /api/v1/-/<project-name>/runs/<entity_id>
157
- # GET /api/v1/-/<project-name>/artifacts/<entity_id>
158
- # GET /api/v1/-/<project-name>/functions/<entity_id>
159
- #
160
- # self._parse_api() should return entity_type and entity_id/version
161
-
162
- else:
163
- for _, v in self._db[entity_type].items():
164
- if entity_id in v:
165
- return v[entity_id]
166
- else:
167
- raise KeyError
168
-
169
- except KeyError:
170
- msg = self._format_msg(3, entity_type=entity_type, entity_id=entity_id)
171
- raise BackendError(msg)
172
-
173
- def update_object(self, api: str, obj: Any, **kwargs) -> dict:
174
- """
175
- Update an object in local.
176
-
177
- Parameters
178
- ----------
179
- api : str
180
- Update API.
181
- obj : dict
182
- Object to update.
183
-
184
- Returns
185
- -------
186
- dict
187
- The updated object.
188
- """
189
- if api == LocalClientVar.EMPTY.value:
190
- return {}
191
- if not isinstance(obj, dict):
192
- raise TypeError("Object must be a dictionary")
193
-
194
- entity_type, entity_id, context_api = self._parse_api(api)
195
- try:
196
- # API example
197
- #
198
- # PUT /api/v1/projects/<entity_id>
199
-
200
- if not context_api:
201
- self._db[entity_type][entity_id] = obj
202
-
203
- # Context API
204
- #
205
- # PUT /api/v1/-/<project-name>/runs/<entity_id>
206
- # PUT /api/v1/-/<project-name>/artifacts/<entity_id>
207
-
208
- else:
209
- name = obj.get("name", entity_id)
210
- container = self._db[entity_type][name]
211
- container[entity_id] = obj
212
-
213
- # Keep the "latest" pointer consistent when updating the latest entity
214
- try:
215
- if container.get("latest", {}).get("id") == entity_id:
216
- container["latest"] = obj
217
- except AttributeError:
218
- # In case "latest" is malformed, ignore and continue
219
- pass
220
-
221
- except KeyError:
222
- msg = self._format_msg(3, entity_type=entity_type, entity_id=entity_id)
223
- raise BackendError(msg)
224
-
225
- return obj
226
-
227
- def delete_object(self, api: str, **kwargs) -> dict:
228
- """
229
- Delete an object from local.
230
-
231
- Parameters
232
- ----------
233
- api : str
234
- Delete API.
235
- **kwargs : dict
236
- Keyword arguments parsed from request.
237
-
238
- Returns
239
- -------
240
- dict
241
- Response object.
242
- """
243
- entity_type, entity_id, context_api = self._parse_api(api)
244
- try:
245
- # Base API
246
- #
247
- # DELETE /api/v1/projects/<entity_id>
248
-
249
- if not context_api:
250
- self._db[entity_type].pop(entity_id)
251
-
252
- # Context API
253
- #
254
- # DELETE /api/v1/-/<project-name>/artifacts/<entity_id>
255
- #
256
- # We do not handle cascade in local client and
257
- # in the sdk we selectively delete objects by id,
258
- # not by name nor entity_type.
259
-
260
- else:
261
- reset_latest = False
262
-
263
- # Name is optional and extracted from kwargs
264
- # "params": {"name": <name>}
265
- name_param = kwargs.get("params", {}).get("name")
266
-
267
- # Delete by name (remove the whole named container)
268
- if entity_id is None and name_param is not None:
269
- self._db[entity_type].pop(name_param, None)
270
- return {"deleted": True}
271
-
272
- # Delete by id
273
- found_name: str | None = None
274
- container: dict | None = None
275
- for n, v in self._db[entity_type].items():
276
- if entity_id in v:
277
- found_name = n
278
- container = v
279
- break
280
- else:
281
- raise KeyError
282
-
283
- # Remove the entity from the container
284
- assert container is not None # for type checkers
285
- container.pop(entity_id)
286
-
287
- # Handle latest pointer if needed
288
- if container.get("latest", {}).get("id") == entity_id:
289
- # Remove stale latest
290
- container.pop("latest", None)
291
- reset_latest = True
292
-
293
- # If container is now empty, drop it entirely
294
- if not container:
295
- assert found_name is not None
296
- self._db[entity_type].pop(found_name, None)
297
- # Otherwise, recompute latest if required
298
- elif reset_latest:
299
- latest_uuid = None
300
- latest_date = None
301
- for k, v in container.items():
302
- # Parse creation time from metadata; tolerate various formats
303
- current_created = self._safe_parse_created(v)
304
- if latest_date is None or current_created > latest_date:
305
- latest_uuid = k
306
- latest_date = current_created
307
-
308
- if latest_uuid is not None:
309
- container["latest"] = container[latest_uuid]
310
-
311
- except KeyError:
312
- msg = self._format_msg(3, entity_type=entity_type, entity_id=entity_id)
313
- raise BackendError(msg)
314
- return {"deleted": True}
315
-
316
- def list_objects(self, api: str, **kwargs) -> list:
317
- """
318
- List objects.
319
-
320
- Parameters
321
- ----------
322
- api : str
323
- List API.
324
- **kwargs : dict
325
- Keyword arguments parsed from request.
326
-
327
- Returns
328
- -------
329
- list | None
330
- The list of objects.
331
- """
332
- entity_type, _, _ = self._parse_api(api)
333
-
334
- # Name is optional and extracted from kwargs
335
- # "params": {"name": <name>}
336
- name = kwargs.get("params", {}).get("name")
337
- if name is not None:
338
- try:
339
- return [self._db[entity_type][name]["latest"]]
340
- except KeyError:
341
- return []
342
-
343
- try:
344
- # If no name is provided, get latest objects
345
- listed_objects = [v["latest"] for _, v in self._db[entity_type].items()]
346
- except KeyError:
347
- listed_objects = []
348
-
349
- # If kind is provided, return objects by kind
350
- kind = kwargs.get("params", {}).get("kind")
351
- if kind is not None:
352
- listed_objects = [obj for obj in listed_objects if obj["kind"] == kind]
353
-
354
- # If function/task is provided, return objects by function/task
355
- spec_params = ["function", "task"]
356
- for i in spec_params:
357
- p = kwargs.get("params", {}).get(i)
358
- if p is not None:
359
- listed_objects = [obj for obj in listed_objects if obj["spec"][i] == p]
360
-
361
- return listed_objects
362
-
363
- def list_first_object(self, api: str, **kwargs) -> dict:
364
- """
365
- List first objects.
366
-
367
- Parameters
368
- ----------
369
- api : str
370
- The api to list the objects with.
371
- **kwargs : dict
372
- Keyword arguments passed to the request.
373
-
374
- Returns
375
- -------
376
- dict
377
- The list of objects.
378
- """
379
- try:
380
- return self.list_objects(api, **kwargs)[0]
381
- except IndexError:
382
- raise IndexError("No objects found")
383
-
384
- def search_objects(self, api: str, **kwargs) -> dict:
385
- """
386
- Search objects from Local.
387
-
388
- Parameters
389
- ----------
390
- api : str
391
- Search API.
392
- **kwargs : dict
393
- Keyword arguments to pass to the request.
394
-
395
- Returns
396
- -------
397
- dict
398
- Response objects.
399
- """
400
- raise NotImplementedError("Local client does not support search_objects.")
401
-
402
- ##############################
403
- # Helpers
404
- ##############################
405
-
406
- def _parse_api(self, api: str) -> tuple:
407
- """
408
- Parse the given API to extract the entity_type, entity_id
409
- and if its a context API.
410
-
411
- Parameters
412
- ----------
413
- api : str
414
- API to parse.
415
-
416
- Returns
417
- -------
418
- tuple
419
- Parsed elements.
420
- """
421
- # Remove prefix from API
422
- api = api.removeprefix("/api/v1/")
423
-
424
- # Set context flag by default to False
425
- context_api = False
426
-
427
- # Remove context prefix from API and set context flag to True
428
- if api.startswith("-/"):
429
- context_api = True
430
- api = api[2:]
431
-
432
- # Return parsed elements
433
- return self._parse_api_elements(api, context_api)
434
-
435
- @staticmethod
436
- def _parse_api_elements(api: str, context_api: bool) -> tuple:
437
- """
438
- Parse the elements from the given API.
439
- Elements returned are: entity_type, entity_id, context_api.
440
-
441
- Parameters
442
- ----------
443
- api : str
444
- Parsed API.
445
- context_api : bool
446
- True if the API is a context API.
447
-
448
- Returns
449
- -------
450
- tuple
451
- Parsed elements from the API.
452
- """
453
- # Split API path
454
- parsed = api.split("/")
455
-
456
- # Base API for versioned objects
457
-
458
- # POST /api/v1/<entity_type>
459
- # Returns entity_type, None, False
460
- if len(parsed) == 1 and not context_api:
461
- return parsed[0], None, context_api
462
-
463
- # GET/DELETE/UPDATE /api/v1/<entity_type>/<entity_id>
464
- # Return entity_type, entity_id, False
465
- if len(parsed) == 2 and not context_api:
466
- return parsed[0], parsed[1], context_api
467
-
468
- # Context API for versioned objects
469
-
470
- # POST /api/v1/-/<project>/<entity_type>
471
- # Returns entity_type, None, True
472
- if len(parsed) == 2 and context_api:
473
- return parsed[1], None, context_api
474
-
475
- # GET/DELETE/UPDATE /api/v1/-/<project>/<entity_type>/<entity_id>
476
- # Return entity_type, entity_id, True
477
- if len(parsed) == 3 and context_api:
478
- return parsed[1], parsed[2], context_api
479
-
480
- raise ValueError(f"Invalid API: {api}")
481
-
482
- def _get_project_spec(self, obj: dict, name: str) -> dict:
483
- """
484
- Enrich project object with spec (artifacts, functions, etc.).
485
-
486
- Parameters
487
- ----------
488
- obj : dict
489
- The project object.
490
- name : str
491
- The project name.
492
-
493
- Returns
494
- -------
495
- dict
496
- The project object with the spec.
497
- """
498
- # Deepcopy to avoid modifying the original object
499
- project = deepcopy(obj)
500
- # Ensure spec exists on the returned project
501
- spec = project.setdefault("spec", {})
502
-
503
- # Get all entities associated with the project specs
504
- projects_entities = [k for k, _ in self._db.items() if k not in ["projects", "runs", "tasks"]]
505
-
506
- for entity_type in projects_entities:
507
- # Get all objects of the entity type for the project
508
- objs = self._db.get(entity_type, {})
509
-
510
- # Set empty list
511
- spec[entity_type] = []
512
-
513
- # Cycle through named objects
514
- for _, named_entities in objs.items():
515
- # Get latest version
516
- for version, entity in named_entities.items():
517
- if version != "latest":
518
- continue
519
-
520
- # Deepcopy to avoid modifying the original object
521
- copied = deepcopy(entity)
522
-
523
- # Remove spec if not embedded
524
- if not copied.get("metadata", {}).get("embedded", False):
525
- copied.pop("spec", None)
526
-
527
- # Add to project spec
528
- if copied["project"] == name:
529
- spec[entity_type].append(copied)
530
-
531
- return project
532
-
533
- @staticmethod
534
- def _safe_parse_created(obj: dict) -> datetime:
535
- """
536
- Safely parse the creation datetime of an object.
537
-
538
- - Accepts ISO format with optional 'Z'.
539
- - If tzinfo is missing, assume UTC.
540
- - Falls back to epoch if missing/invalid.
541
- """
542
- created_raw = obj.get("metadata", {}).get("created")
543
- fallback = datetime.fromtimestamp(0, timezone.utc)
544
- if not created_raw or not isinstance(created_raw, str):
545
- return fallback
546
- try:
547
- # Support trailing 'Z'
548
- ts = created_raw.replace("Z", "+00:00")
549
- dt = datetime.fromisoformat(ts)
550
- if dt.tzinfo is None:
551
- dt = dt.replace(tzinfo=timezone.utc)
552
- return dt
553
- except Exception:
554
- return fallback
555
-
556
- ##############################
557
- # Utils
558
- ##############################
559
-
560
- @staticmethod
561
- def _format_msg(
562
- error_code: int,
563
- entity_type: str | None = None,
564
- entity_id: str | None = None,
565
- ) -> str:
566
- """
567
- Format a message.
568
-
569
- Parameters
570
- ----------
571
- error_code : int
572
- Error code identifying the type of error.
573
- entity_type : str, optional
574
- Entity type that caused the error.
575
- entity_id : str, optional
576
- Entity ID that caused the error.
577
-
578
- Returns
579
- -------
580
- str
581
- The formatted error message.
582
- """
583
- msg = {
584
- 1: f"Object '{entity_type}' to create is not valid",
585
- 2: f"Object '{entity_type}' with id '{entity_id}' already exists",
586
- 3: f"Object '{entity_type}' with id '{entity_id}' not found",
587
- 4: "Must provide entity_id to read an object",
588
- }
589
- return msg[error_code]
590
-
591
- ##############################
592
- # Interface methods
593
- ##############################
594
-
595
- @staticmethod
596
- def is_local() -> bool:
597
- """
598
- Declare if Client is local.
599
-
600
- Returns
601
- -------
602
- bool
603
- True
604
- """
605
- return True
@@ -1,15 +0,0 @@
1
- # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from __future__ import annotations
6
-
7
- from enum import Enum
8
-
9
-
10
- class LocalClientVar(Enum):
11
- """
12
- Variables for Local.
13
- """
14
-
15
- EMPTY = "EMPTY"
@@ -1,62 +0,0 @@
1
- # SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from __future__ import annotations
6
-
7
- from digitalhub.stores.client._base.key_builder import ClientKeyBuilder
8
-
9
-
10
- class ClientLocalKeyBuilder(ClientKeyBuilder):
11
- """
12
- Class that build the key of entities.
13
- """
14
-
15
- def base_entity_key(self, entity_id: str) -> str:
16
- """
17
- Build for base entity key.
18
-
19
- Parameters
20
- ----------
21
- entity_id : str
22
- Entity id.
23
-
24
- Returns
25
- -------
26
- str
27
- Key.
28
- """
29
- return f"store://{entity_id}"
30
-
31
- def context_entity_key(
32
- self,
33
- project: str,
34
- entity_type: str,
35
- entity_kind: str,
36
- entity_name: str,
37
- entity_id: str | None = None,
38
- ) -> str:
39
- """
40
- Build for context entity key.
41
-
42
- Parameters
43
- ----------
44
- project : str
45
- Project name.
46
- entity_type : str
47
- Entity type.
48
- entity_kind : str
49
- Entity kind.
50
- entity_name : str
51
- Entity name.
52
- entity_id : str
53
- Entity ID.
54
-
55
- Returns
56
- -------
57
- str
58
- Key.
59
- """
60
- if entity_id is None:
61
- return f"store://{project}/{entity_type}/{entity_kind}/{entity_name}"
62
- return f"store://{project}/{entity_type}/{entity_kind}/{entity_name}:{entity_id}"