digitalhub 0.8.0b14__py3-none-any.whl → 0.8.1__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.

@@ -5,13 +5,14 @@ import json
5
5
  import os
6
6
  import typing
7
7
  from urllib.parse import urlparse
8
+ from warnings import warn
8
9
 
9
- from dotenv import load_dotenv, set_key
10
+ from dotenv import get_key, set_key
10
11
  from requests import request
11
12
  from requests.exceptions import HTTPError, JSONDecodeError, RequestException
12
13
 
13
14
  from digitalhub.client._base.client import Client
14
- from digitalhub.client.dhcore.env import ENV_FILE, FALLBACK_USER, MAX_API_LEVEL, MIN_API_LEVEL
15
+ from digitalhub.client.dhcore.env import ENV_FILE, FALLBACK_USER, MAX_API_LEVEL, MIN_API_LEVEL, LIB_VERSION
15
16
  from digitalhub.client.dhcore.models import BasicAuth, OAuth2TokenAuth
16
17
  from digitalhub.utils.exceptions import (
17
18
  BackendError,
@@ -332,6 +333,8 @@ class ClientDHCore(Client):
332
333
  core_api_level = int(response.headers["X-Api-Level"])
333
334
  if not (MIN_API_LEVEL <= core_api_level <= MAX_API_LEVEL):
334
335
  raise BackendError("Backend API level not supported.")
336
+ if LIB_VERSION < core_api_level:
337
+ warn("Backend API level is higher than library version. You should consider updating the library.")
335
338
 
336
339
  def _raise_for_error(self, response: Response) -> None:
337
340
  """
@@ -462,8 +465,6 @@ class ClientDHCore(Client):
462
465
  -------
463
466
  None
464
467
  """
465
- # Load env from file
466
- self._load_env()
467
468
 
468
469
  self._get_endpoints_from_env()
469
470
 
@@ -487,7 +488,8 @@ class ClientDHCore(Client):
487
488
  self._get_auth_from_env()
488
489
 
489
490
  # Propagate access and refresh token to env file
490
- self._write_env()
491
+ if not ENV_FILE.exists():
492
+ self._write_env()
491
493
 
492
494
  def _get_endpoints_from_env(self) -> None:
493
495
  """
@@ -563,11 +565,21 @@ class ClientDHCore(Client):
563
565
  url = self._get_refresh_endpoint()
564
566
 
565
567
  # Call refresh token endpoint
566
- response = self._call_refresh_token_endpoint(url)
568
+ # Try token from env
569
+ refresh_token = os.getenv("DHCORE_REFRESH_TOKEN")
570
+ response = self._call_refresh_token_endpoint(url, refresh_token)
571
+
572
+ # Otherwise try token from file
573
+ if response.status_code in (400, 401, 403):
574
+ refresh_token = get_key(ENV_FILE, "DHCORE_REFRESH_TOKEN")
575
+ response = self._call_refresh_token_endpoint(url, refresh_token)
576
+
577
+ response.raise_for_status()
578
+ dict_response = response.json()
567
579
 
568
580
  # Read new access token and refresh token
569
- self._access_token = response["access_token"]
570
- self._refresh_token = response["refresh_token"]
581
+ self._access_token = dict_response["access_token"]
582
+ self._refresh_token = dict_response["refresh_token"]
571
583
 
572
584
  # Propagate new access token to env
573
585
  self._write_env()
@@ -593,7 +605,7 @@ class ClientDHCore(Client):
593
605
  self._raise_for_error(r)
594
606
  return r.json().get("token_endpoint")
595
607
 
596
- def _call_refresh_token_endpoint(self, url: str) -> dict:
608
+ def _call_refresh_token_endpoint(self, url: str, refresh_token: str) -> Response:
597
609
  """
598
610
  Call the refresh token endpoint.
599
611
 
@@ -601,17 +613,14 @@ class ClientDHCore(Client):
601
613
  ----------
602
614
  url : str
603
615
  Refresh token endpoint.
616
+ refresh_token : str
617
+ Refresh token.
604
618
 
605
619
  Returns
606
620
  -------
607
- dict
621
+ Response
608
622
  Response object.
609
623
  """
610
- # Get refersh token from .core file to avoid concurrency
611
- # in a shared workspace
612
- self._load_env()
613
- refresh_token = os.getenv("DHCORE_REFRESH_TOKEN")
614
-
615
624
  # Send request to get new access token
616
625
  payload = {
617
626
  "grant_type": "refresh_token",
@@ -619,20 +628,7 @@ class ClientDHCore(Client):
619
628
  "refresh_token": refresh_token,
620
629
  }
621
630
  headers = {"Content-Type": "application/x-www-form-urlencoded"}
622
- r = request("POST", url, data=payload, headers=headers, timeout=60)
623
- self._raise_for_error(r)
624
- return r.json()
625
-
626
- @staticmethod
627
- def _load_env() -> None:
628
- """
629
- Load the env variables from the .dhcore file.
630
-
631
- Returns
632
- -------
633
- None
634
- """
635
- load_dotenv(dotenv_path=ENV_FILE, override=True)
631
+ return request("POST", url, data=payload, headers=headers, timeout=60)
636
632
 
637
633
  def _write_env(self) -> None:
638
634
  """
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
+ from pathlib import Path
4
5
 
5
6
  # Use env user as fallback in the API calls
6
7
  try:
@@ -13,9 +14,10 @@ except Exception:
13
14
  # but refresh token is only available once. Is it's used, we cannot
14
15
  # overwrite it with coder, so we need to store the new one in a file,
15
16
  # preserved for jupyter restart
16
- ENV_FILE = ".dhcore"
17
+ ENV_FILE = Path.home() / ".dhcore"
17
18
 
18
19
 
19
20
  # API levels that are supported
20
21
  MAX_API_LEVEL = 20
21
22
  MIN_API_LEVEL = 8
23
+ LIB_VERSION = 8
digitalhub/context/api.py CHANGED
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.context.builder import context_builder
6
+ from digitalhub.utils.exceptions import ContextError
6
7
 
7
8
  if typing.TYPE_CHECKING:
8
9
  from digitalhub.context.context import Context
@@ -24,8 +25,7 @@ def check_context(project: str) -> None:
24
25
  True if the project is in the context, False otherwise.
25
26
  """
26
27
  if project not in context_builder._instances:
27
- msg = f"Context missing. Set context by creating or importing a project named '{project}'."
28
- raise RuntimeError(msg)
28
+ raise ContextError
29
29
 
30
30
 
31
31
  def set_context(project: Project) -> None:
@@ -2,15 +2,19 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
 
5
+ from digitalhub.client.api import build_client, get_client
5
6
  from digitalhub.context.api import check_context
6
7
  from digitalhub.entities._base.api_utils import (
7
8
  delete_entity_api_ctx,
8
9
  list_entity_api_ctx,
10
+ read_entity_api_base,
9
11
  read_entity_api_ctx,
10
12
  read_entity_api_ctx_versions,
11
13
  )
14
+ from digitalhub.entities.utils.entity_types import EntityTypes
15
+ from digitalhub.entities.utils.utils import parse_entity_key
12
16
  from digitalhub.factory.api import build_entity_from_dict, build_entity_from_params
13
- from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError
17
+ from digitalhub.utils.exceptions import ContextError, EntityAlreadyExistsError, EntityError, EntityNotExistsError
14
18
  from digitalhub.utils.io_utils import read_yaml
15
19
 
16
20
  if typing.TYPE_CHECKING:
@@ -21,6 +25,58 @@ if typing.TYPE_CHECKING:
21
25
  from digitalhub.entities._base.versioned.entity import VersionedEntity
22
26
 
23
27
 
28
+ def _check_context(project: str) -> None:
29
+ """
30
+ Check if the given project is in the context.
31
+ Otherwise try to get the project from remote.
32
+
33
+ Parameters
34
+ ----------
35
+ project : str
36
+ Project name.
37
+
38
+ Returns
39
+ -------
40
+ None
41
+ """
42
+ try:
43
+ check_context(project)
44
+ except ContextError:
45
+ try:
46
+ build_client()
47
+ client = get_client()
48
+ obj = read_entity_api_base(client, EntityTypes.PROJECT.value, project)
49
+ build_entity_from_dict(obj)
50
+ except EntityNotExistsError:
51
+ raise ContextError(f"Project '{project}' not found.")
52
+
53
+
54
+ def _check_project_from_identifier(identifier: str, project: str | None = None) -> None:
55
+ """
56
+ Check if the given project is in the context.
57
+ Otherwise try to get the project from remote.
58
+
59
+ Parameters
60
+ ----------
61
+ identifier : str
62
+ Entity key (store://...) or entity name.
63
+ project : str
64
+ Project name.
65
+
66
+ Returns
67
+ -------
68
+ None
69
+ """
70
+ if not identifier.startswith("store://"):
71
+ if project is None:
72
+ raise EntityError("Specify project if you do not specify entity key.")
73
+
74
+ else:
75
+ project, _, _, _, _ = parse_entity_key(identifier)
76
+
77
+ _check_context(project)
78
+
79
+
24
80
  def new_context_entity(**kwargs) -> ContextEntity:
25
81
  """
26
82
  Create a new object.
@@ -45,7 +101,7 @@ def new_context_entity(**kwargs) -> ContextEntity:
45
101
  ContextEntity
46
102
  Object instance.
47
103
  """
48
- check_context(kwargs["project"])
104
+ _check_context(kwargs["project"])
49
105
  obj = build_entity_from_params(**kwargs)
50
106
  obj.save()
51
107
  return obj
@@ -79,6 +135,7 @@ def get_versioned_entity(
79
135
  VersionedEntity
80
136
  Object instance.
81
137
  """
138
+ _check_project_from_identifier(identifier, project)
82
139
  obj = read_entity_api_ctx(
83
140
  identifier,
84
141
  entity_type=entity_type,
@@ -116,8 +173,8 @@ def get_unversioned_entity(
116
173
  UnversionedEntity
117
174
  Object instance.
118
175
  """
119
- if not identifier.startswith("store://") and project is None:
120
- raise EntityError("Specify entity key or entity ID combined with project")
176
+ _check_project_from_identifier(identifier, project)
177
+
121
178
  obj = read_entity_api_ctx(
122
179
  identifier,
123
180
  entity_type=entity_type,
@@ -191,6 +248,7 @@ def get_context_entity_versions(
191
248
  list[ContextEntity]
192
249
  List of object instances.
193
250
  """
251
+ _check_project_from_identifier(identifier, project)
194
252
  obj = read_entity_api_ctx_versions(
195
253
  identifier,
196
254
  entity_type=entity_type,
@@ -225,6 +283,7 @@ def get_material_entity_versions(
225
283
  list[MaterialEntity]
226
284
  List of object instances.
227
285
  """
286
+ _check_project_from_identifier(identifier, project)
228
287
  objs = read_entity_api_ctx_versions(
229
288
  identifier,
230
289
  entity_type=entity_type,
@@ -257,6 +316,7 @@ def list_context_entities(project: str, entity_type: str, **kwargs) -> list[Cont
257
316
  list[ContextEntity]
258
317
  List of object instances.
259
318
  """
319
+ _check_context(project)
260
320
  objs = list_entity_api_ctx(
261
321
  project=project,
262
322
  entity_type=entity_type,
@@ -287,6 +347,7 @@ def list_material_entities(
287
347
  list[MaterialEntity]
288
348
  List of object instances.
289
349
  """
350
+ _check_context(project)
290
351
  objs = list_entity_api_ctx(
291
352
  project=project,
292
353
  entity_type=entity_type,
@@ -316,7 +377,7 @@ def import_context_entity(file: str) -> ContextEntity:
316
377
  """
317
378
  dict_obj: dict = read_yaml(file)
318
379
 
319
- check_context(dict_obj["project"])
380
+ _check_context(dict_obj["project"])
320
381
 
321
382
  obj = build_entity_from_dict(dict_obj)
322
383
  try:
@@ -348,7 +409,7 @@ def import_executable_entity(file: str) -> ExecutableEntity:
348
409
  exec_dict = dict_obj
349
410
  tsk_dicts = []
350
411
 
351
- check_context(exec_dict["project"])
412
+ _check_context(exec_dict["project"])
352
413
 
353
414
  obj: ExecutableEntity = build_entity_from_dict(exec_dict)
354
415
 
@@ -395,6 +456,7 @@ def delete_entity(
395
456
  dict
396
457
  Response from backend.
397
458
  """
459
+ _check_project_from_identifier(identifier, project)
398
460
  return delete_entity_api_ctx(
399
461
  identifier=identifier,
400
462
  entity_type=entity_type,
@@ -23,4 +23,4 @@ def build_uuid(uuid: str | None = None) -> str:
23
23
  if slugify_string(uuid) != uuid:
24
24
  raise ValueError(f"Invalid ID: {uuid}. Must pass slugified ID.")
25
25
  return uuid
26
- return str(uuid4())
26
+ return uuid4().hex
@@ -227,13 +227,10 @@ class Project(Entity):
227
227
  """
228
228
  # Cycle over entity types
229
229
  for entity_type in self._get_entity_types():
230
-
231
230
  # Entity types are stored as a list of entities
232
231
  for idx, entity in enumerate(obj.get("spec", {}).get(entity_type, [])):
233
-
234
232
  # Export entity if not embedded is in metadata, else do nothing
235
233
  if not self._is_embedded(entity):
236
-
237
234
  # Get entity object from backend
238
235
  obj_dict: dict = read_entity_api_ctx(entity["key"])
239
236
 
@@ -264,16 +261,13 @@ class Project(Entity):
264
261
 
265
262
  # Cycle over entity types
266
263
  for entity_type in entity_types:
267
-
268
264
  # Entity types are stored as a list of entities
269
265
  for entity in obj.get("spec", {}).get(entity_type, []):
270
-
271
266
  embedded = self._is_embedded(entity)
272
267
  ref = entity["metadata"].get("ref")
273
268
 
274
269
  # Import entity if not embedded and there is a ref
275
270
  if not embedded and ref is not None:
276
-
277
271
  # Import entity from local ref
278
272
  if map_uri_scheme(ref) == "local":
279
273
  try:
@@ -291,7 +285,6 @@ class Project(Entity):
291
285
 
292
286
  # If entity is embedded, create it and try to save
293
287
  elif embedded:
294
-
295
288
  # It's possible that embedded field in metadata is not shown
296
289
  if entity["metadata"].get("embedded") is None:
297
290
  entity["metadata"]["embedded"] = True
@@ -159,6 +159,8 @@ def import_project(
159
159
  # Import related entities
160
160
  obj._import_entities(dict_obj)
161
161
 
162
+ obj.refresh()
163
+
162
164
  return obj
163
165
 
164
166
 
@@ -284,22 +284,21 @@ class S3Store(Store):
284
284
  """
285
285
  client, bucket = self._check_factory()
286
286
 
287
+ # Get list of files
287
288
  src_pth = Path(src)
288
289
  files = [i for i in src_pth.rglob("*") if i.is_file()]
290
+
291
+ # Build keys
289
292
  keys = []
290
293
  for i in files:
291
- if src_pth.is_absolute():
292
- i = i.relative_to(src_pth)
294
+ i = i.relative_to(src_pth)
293
295
  keys.append(f"{dst}{i}")
294
296
 
295
297
  # Upload files
296
298
  paths = []
297
- for i in zip(files, keys):
298
- f, k = i
299
+ for f, k in zip(files, keys):
299
300
  self._upload_file(f, k, client, bucket)
300
- if src_pth.is_absolute():
301
- f = f.relative_to(src_pth)
302
- paths.append((k, str(f)))
301
+ paths.append((k, str(f.relative_to(src_pth))))
303
302
  return paths
304
303
 
305
304
  def _upload_file_list(self, src: list[str], dst: str) -> list[tuple[str, str]]:
@@ -328,8 +327,7 @@ class S3Store(Store):
328
327
 
329
328
  # Upload files
330
329
  paths = []
331
- for i in zip(files, keys):
332
- f, k = i
330
+ for f, k in zip(files, keys):
333
331
  self._upload_file(f, k, client, bucket)
334
332
  paths.append((k, Path(f).name))
335
333
  return paths
@@ -59,3 +59,9 @@ class EntityError(Exception):
59
59
  """
60
60
  Raised when incontered errors on entities.
61
61
  """
62
+
63
+
64
+ class ContextError(Exception):
65
+ """
66
+ Raised when context errors.
67
+ """
@@ -62,7 +62,7 @@ class NoDatesSafeLoader(yaml.SafeLoader):
62
62
  -------
63
63
  None
64
64
  """
65
- if not "yaml_implicit_resolvers" in cls.__dict__:
65
+ if "yaml_implicit_resolvers" not in cls.__dict__:
66
66
  cls.yaml_implicit_resolvers = cls.yaml_implicit_resolvers.copy()
67
67
 
68
68
  for first_letter, mappings in cls.yaml_implicit_resolvers.items():
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: digitalhub
3
- Version: 0.8.0b14
3
+ Version: 0.8.1
4
4
  Summary: Python SDK for Digitalhub
5
5
  Author-email: Fondazione Bruno Kessler <dslab@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
6
- License: Apache License
6
+ License: Apache License
7
7
  Version 2.0, January 2004
8
8
  http://www.apache.org/licenses/
9
9
 
@@ -240,6 +240,13 @@ Requires-Dist: python-dotenv
240
240
  Requires-Dist: GitPython>=3
241
241
  Requires-Dist: psycopg2-binary
242
242
  Requires-Dist: python-slugify
243
+ Provides-Extra: full
244
+ Requires-Dist: pandas<2.2,>=1.2; extra == "full"
245
+ Requires-Dist: mlflow; extra == "full"
246
+ Provides-Extra: pandas
247
+ Requires-Dist: pandas<2.2,>=1.2; extra == "pandas"
248
+ Provides-Extra: mlflow
249
+ Requires-Dist: mlflow; extra == "mlflow"
243
250
  Provides-Extra: dev
244
251
  Requires-Dist: black; extra == "dev"
245
252
  Requires-Dist: pytest; extra == "dev"
@@ -250,13 +257,6 @@ Provides-Extra: docs
250
257
  Requires-Dist: Sphinx>=7; extra == "docs"
251
258
  Requires-Dist: pydata-sphinx-theme>=0.15; extra == "docs"
252
259
  Requires-Dist: numpydoc>=1.6; extra == "docs"
253
- Provides-Extra: full
254
- Requires-Dist: pandas<2.2,>=1.2; extra == "full"
255
- Requires-Dist: mlflow; extra == "full"
256
- Provides-Extra: mlflow
257
- Requires-Dist: mlflow; extra == "mlflow"
258
- Provides-Extra: pandas
259
- Requires-Dist: pandas<2.2,>=1.2; extra == "pandas"
260
260
 
261
261
  # Digitalhub Library
262
262
 
@@ -5,14 +5,14 @@ digitalhub/client/builder.py,sha256=83PoMCus4s4nbkoWmvcjW2hIpXbNx74sUW93wgQgbuo,
5
5
  digitalhub/client/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  digitalhub/client/_base/client.py,sha256=HDv9Vr9DZpoaZVsAT5SSBD9j1oHoVuxA4ILGDl0mBz4,1299
7
7
  digitalhub/client/dhcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- digitalhub/client/dhcore/client.py,sha256=eh-IQu72Kz4K82uUlMRtatQAQNymvOCMJZZPjB9TdqQ,19169
9
- digitalhub/client/dhcore/env.py,sha256=F5A5dPTliwd4UUbpw7hQQ3hoVjZYjcVF8MbniTuTFHE,563
8
+ digitalhub/client/dhcore/client.py,sha256=qzZaM0y5wxXkp7aTMbAGWyrXIulGwtrzpVx2ZtnZTZo,19397
9
+ digitalhub/client/dhcore/env.py,sha256=5IsPR4SG0lg2TkqgW4vhHvThieuWVOZyZsBodWH6kKs,618
10
10
  digitalhub/client/dhcore/models.py,sha256=KiTg5xR8EzI7Xa1pmYmzixabLdnqlnn5kn-IILZDGIw,900
11
11
  digitalhub/client/dhcore/utils.py,sha256=TaLjA3LT6heKpPclmufZx-kZKZNOe4OzS_Jtpj2S5wY,2990
12
12
  digitalhub/client/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  digitalhub/client/local/client.py,sha256=VBJJVEqbFFb_fzFogoo1kVyifezt0L7d489UTZxV0x8,16780
14
14
  digitalhub/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- digitalhub/context/api.py,sha256=cZzS_1Kz-wW5iFMtEt3x9dD1PncnAsNnPoIfmoOQ5-g,1781
15
+ digitalhub/context/api.py,sha256=-76HPxc7ird13HJoOl_-Z_q2l2g8Yv3rcsXjHphn2to,1729
16
16
  digitalhub/context/builder.py,sha256=qpw8T-xho80Njf9wNPTooKkwjWuMT30BeKoQUDWm_yc,2132
17
17
  digitalhub/context/context.py,sha256=hDZEW4riMjR5-v2zWiirt-Z5puxdc7d_Da6vFhyuRF4,3338
18
18
  digitalhub/datastores/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -32,7 +32,7 @@ digitalhub/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
32
32
  digitalhub/entities/builders.py,sha256=wKNC3ly-IUrF9uaSXWQ5cMzEj7JikM467uXIOdgko2c,1951
33
33
  digitalhub/entities/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  digitalhub/entities/_base/api_utils.py,sha256=cxnQ8Bi1QtHi8pQi-CM8P1zOOuFZbhRf7dWOrrXPX1I,13346
35
- digitalhub/entities/_base/crud.py,sha256=OThKNECVYRHUuaqR5cvBY9Tb6gooIFd_wFSDfAoSl-g,9148
35
+ digitalhub/entities/_base/crud.py,sha256=m5A7Fya2DmfGdBis54U5SA--6BVc6WQ3SUhg4nXjaws,10852
36
36
  digitalhub/entities/_base/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  digitalhub/entities/_base/_base/entity.py,sha256=DLJHhviHVKCo26jCEYg7iXwkfS9mDBQrHxBtHF_yE-0,2180
38
38
  digitalhub/entities/_base/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -48,7 +48,7 @@ digitalhub/entities/_base/entity/_constructors/metadata.py,sha256=IGB1l6EJ1xlnGM
48
48
  digitalhub/entities/_base/entity/_constructors/name.py,sha256=sNU54TzzdYug5sqio8uaus6pP5RkEJYIEl6j0fwR4ho,485
49
49
  digitalhub/entities/_base/entity/_constructors/spec.py,sha256=ymUHuJ6m3B8eVL4622XRdNMQdeYxRwBV5drao0L5MiQ,879
50
50
  digitalhub/entities/_base/entity/_constructors/status.py,sha256=xrr2u2wlDMmlqrUIV9xVqFRHfn5LV_TqzdrCEWNCzE0,1132
51
- digitalhub/entities/_base/entity/_constructors/uuid.py,sha256=8wys6Uhk8L1uUo18moh7Rq5YnFHtmUVXfNOkcsTVUN8,556
51
+ digitalhub/entities/_base/entity/_constructors/uuid.py,sha256=QzG0nsVpGU2UDD5CjpkOM2RfVaCHPdLp2HoQt8TM_tk,555
52
52
  digitalhub/entities/_base/executable/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  digitalhub/entities/_base/executable/entity.py,sha256=NJCb82RAp9f_KERdCPQYev39WxchlicY6gnEi1P2QTg,10075
54
54
  digitalhub/entities/_base/material/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -136,10 +136,10 @@ digitalhub/entities/model/sklearn/entity.py,sha256=pPy4mOqOmbkqNkKFUnhrsIQNt2mGN
136
136
  digitalhub/entities/model/sklearn/spec.py,sha256=Md0aKlfNHZ2fhZbJgp9wZxF0Hu6XIkcniQHCgwoRdkk,301
137
137
  digitalhub/entities/model/sklearn/status.py,sha256=eqkPPtERX-6_BjPb_GD8j1FIeavpl43k-dfXZGqzGI0,187
138
138
  digitalhub/entities/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
- digitalhub/entities/project/crud.py,sha256=P2IhKR2-YNmiNy0rpu0PG-LKD9nJGKsAahxvhsovmJA,8971
139
+ digitalhub/entities/project/crud.py,sha256=z2UhAESn8nmZf6nF6KnTQClUyNjO1LCG04OJucNGJfs,8990
140
140
  digitalhub/entities/project/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
141
141
  digitalhub/entities/project/_base/builder.py,sha256=Fx_p8M75SkE_ssVBvKGu45wwqwqAZ5N6l6UZZj9LSNc,3612
142
- digitalhub/entities/project/_base/entity.py,sha256=OZ4vH38ORWTdYS6yE4sxc0jdIpqgKszDJp_IrpeQJMQ,53559
142
+ digitalhub/entities/project/_base/entity.py,sha256=CA3MqkwJlvnoI0shUIqsf-SsOoTZUA4Z41wnn0jbT5c,53552
143
143
  digitalhub/entities/project/_base/spec.py,sha256=zRJKFztK7z79LU4spxX7Rykv_1sK6kV9F9Qg95HBc6s,1346
144
144
  digitalhub/entities/project/_base/status.py,sha256=w1Hj_yFwr_5X7ZH7SmtZRto4qUdCWb010viFfvbqX48,168
145
145
  digitalhub/entities/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -202,16 +202,16 @@ digitalhub/stores/local/store.py,sha256=KjJ8OG6vfNrckMWbkbEA8KDM6b0Ds0Ed3fwxvTnG
202
202
  digitalhub/stores/remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
203
  digitalhub/stores/remote/store.py,sha256=MBsotmc5Zk-eT5vgAufnYyR2xJmQvgBR28u3bhaSJtM,3615
204
204
  digitalhub/stores/s3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
- digitalhub/stores/s3/store.py,sha256=dS0TumNf3tDkpVcn_0_kp-ERogP3w87tEa-osIU11AQ,15515
205
+ digitalhub/stores/s3/store.py,sha256=MFP0zCVWXpgg13cz2BB40R5TFeOl0GcxO0rycAYTqIY,15427
206
206
  digitalhub/stores/sql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
207
  digitalhub/stores/sql/store.py,sha256=NdELCkP2Rl5ewiRuI4J9eRvTiBzVmpF0cMowZ1NME_8,8654
208
208
  digitalhub/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
209
209
  digitalhub/utils/data_utils.py,sha256=2eETyxml610Ij7uyDnNc3YiELl2WFLIkj3FL4y6EPk8,2733
210
- digitalhub/utils/exceptions.py,sha256=MjLhgaGSAe0oJXoR-dnEtAh02RYDj3wZ1ZS1SLFUD4A,964
210
+ digitalhub/utils/exceptions.py,sha256=4jiWXyt4wNtFGRbcEm17hc7EQmwE8D0RhaeNW1z3EtA,1045
211
211
  digitalhub/utils/file_utils.py,sha256=Qe71D2b6mOil_Y0Hy2QCJbnIaQOyXvhjFRbJoZXhsGQ,4006
212
212
  digitalhub/utils/generic_utils.py,sha256=YHWCCF77JFqgm4TNr3_U2GbX4SjEQjUmxA6i9PkRqG8,3527
213
213
  digitalhub/utils/git_utils.py,sha256=aFYL1cpfY-2VnlW7eHmjjjlTLECc5UUUfjb_IQPOY5k,3244
214
- digitalhub/utils/io_utils.py,sha256=Yg24Lt_0aAUaj4Yv5-1iy7VIA0umLxQGW6lkDRWcjrE,2997
214
+ digitalhub/utils/io_utils.py,sha256=7pe0LwLPblx9Lx5_lugALZ84_eHGDifJ0RchK5fU1io,2997
215
215
  digitalhub/utils/logger.py,sha256=ml3ne6D8wuRdNZ4F6ywmvWotSxjmZWnmKgNiuHb4R5M,437
216
216
  digitalhub/utils/s3_utils.py,sha256=oXLzp4K7o45IwK0XOMt4OElDyB09fKRic5WTNA82WUA,1113
217
217
  digitalhub/utils/uri_utils.py,sha256=wArWRQ3ygGUNHexGKP3YM-aBE7TyGxhPvfEc7R4T4p4,1144
@@ -224,8 +224,8 @@ test/local/CRUD/test_artifacts.py,sha256=Y3J_C7SDRSsQd2SGIZjPIOvyTL92B1sTFrUONG3
224
224
  test/local/CRUD/test_dataitems.py,sha256=LQqTzI59uwTGy4zoq8jL0yWVe2W9vXlatkgDU9aB6xg,2968
225
225
  test/local/CRUD/test_models.py,sha256=msosbZuRwIMbZtmi3ZaOva4TjQ4lrzkNu9AguIFhrSo,2929
226
226
  test/local/imports/test_imports.py,sha256=W-YugO0rpJwvtWp57MXaXfEmE-f5iWuCiLY-n0ZU4z8,1271
227
- digitalhub-0.8.0b14.dist-info/LICENSE.txt,sha256=_yVOtnbW7Ss28mp058UEEc1X4Rgj8-kQBP_kj8_Sc88,11585
228
- digitalhub-0.8.0b14.dist-info/METADATA,sha256=ZCqntN3pfX1zYGBO3TwzSli4gxGmsyqB8dnJZXXL8Jk,15289
229
- digitalhub-0.8.0b14.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
230
- digitalhub-0.8.0b14.dist-info/top_level.txt,sha256=ae9pDfCF27ZoaVAxuBKONMP0lm5P-N_I-e-no1WlvD8,16
231
- digitalhub-0.8.0b14.dist-info/RECORD,,
227
+ digitalhub-0.8.1.dist-info/LICENSE.txt,sha256=_yVOtnbW7Ss28mp058UEEc1X4Rgj8-kQBP_kj8_Sc88,11585
228
+ digitalhub-0.8.1.dist-info/METADATA,sha256=1-dYS0X78aKXA0SvnWJF-AhbFOItvrU8P7AahsxqJY0,15316
229
+ digitalhub-0.8.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
230
+ digitalhub-0.8.1.dist-info/top_level.txt,sha256=ae9pDfCF27ZoaVAxuBKONMP0lm5P-N_I-e-no1WlvD8,16
231
+ digitalhub-0.8.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5