digitalhub 0.11.0b0__py3-none-any.whl → 0.11.0b1__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.

@@ -276,6 +276,7 @@ class ClientDHCore(Client):
276
276
  dict
277
277
  Response object.
278
278
  """
279
+ self._configurator.check_config()
279
280
  if kwargs is None:
280
281
  kwargs = {}
281
282
  url = self._configurator.build_url(api)
@@ -31,10 +31,29 @@ class ClientDHCoreConfigurator:
31
31
  Configurator object used to configure the client.
32
32
  """
33
33
 
34
+ def __init__(self) -> None:
35
+ self._current_env = configurator.get_current_env()
36
+
34
37
  ##############################
35
38
  # Configuration methods
36
39
  ##############################
37
40
 
41
+ def check_config(self) -> None:
42
+ """
43
+ Check if the config is valid.
44
+
45
+ Parameters
46
+ ----------
47
+ config : dict
48
+ Configuration dictionary.
49
+
50
+ Returns
51
+ -------
52
+ None
53
+ """
54
+ if configurator.get_current_env() != self._current_env:
55
+ self.configure()
56
+
38
57
  def configure(self, config: dict | None = None) -> None:
39
58
  """
40
59
  Configure the client attributes with config (given or from
@@ -68,4 +68,5 @@ def refresh_token() -> None:
68
68
  None
69
69
  """
70
70
  client: ClientDHCore = get_client(local=False)
71
+ client._configurator.check_config()
71
72
  client._configurator.get_new_access_token()
@@ -4,7 +4,7 @@ import os
4
4
 
5
5
  from digitalhub.stores.configurator.credentials_store import CredentialsStore
6
6
  from digitalhub.stores.configurator.enums import SetCreds
7
- from digitalhub.stores.configurator.ini_module import load_from_file, write_config
7
+ from digitalhub.stores.configurator.ini_module import load_from_file, read_env_from_file, set_current_env, write_config
8
8
 
9
9
 
10
10
  class EnvConfigurator:
@@ -37,6 +37,7 @@ class EnvConfigurator:
37
37
  None
38
38
  """
39
39
  self._environment = creds_set
40
+ set_current_env(creds_set)
40
41
 
41
42
  def get_current_env(self) -> str:
42
43
  """
@@ -106,6 +107,7 @@ class EnvConfigurator:
106
107
  str | None
107
108
  Environment variable value.
108
109
  """
110
+ self._environment = read_env_from_file()
109
111
  return load_from_file(var)
110
112
 
111
113
  def write_env(self, key_to_include: list[str] | None = None) -> None:
@@ -13,6 +13,23 @@ from digitalhub.utils.exceptions import ClientError
13
13
  ENV_FILE = Path.home() / ".dhcore.ini"
14
14
 
15
15
 
16
+ def load_file() -> ConfigParser:
17
+ """
18
+ Load current credentials set from the .dhcore.ini file.
19
+
20
+ Returns
21
+ -------
22
+ ConfigParser
23
+ Credentials set name.
24
+ """
25
+ try:
26
+ file = ConfigParser()
27
+ file.read(ENV_FILE)
28
+ return file
29
+ except Exception as e:
30
+ raise ClientError(f"Failed to read env file: {e}")
31
+
32
+
16
33
  def load_from_file(var: str) -> str | None:
17
34
  """
18
35
  Load variable from config file.
@@ -29,9 +46,8 @@ def load_from_file(var: str) -> str | None:
29
46
  str | None
30
47
  Environment variable value.
31
48
  """
32
- cfg = ConfigParser()
33
- cfg.read(ENV_FILE)
34
49
  try:
50
+ cfg = load_file()
35
51
  profile = cfg["DEFAULT"]["current_environment"]
36
52
  return cfg[profile].get(var)
37
53
  except KeyError:
@@ -55,8 +71,7 @@ def write_config(creds: dict, environment: str) -> None:
55
71
  None
56
72
  """
57
73
  try:
58
- cfg = ConfigParser()
59
- cfg.read(ENV_FILE)
74
+ cfg = load_file()
60
75
 
61
76
  sections = cfg.sections()
62
77
  if environment not in sections:
@@ -72,3 +87,42 @@ def write_config(creds: dict, environment: str) -> None:
72
87
 
73
88
  except Exception as e:
74
89
  raise ClientError(f"Failed to write env file: {e}")
90
+
91
+
92
+ def set_current_env(environment: str) -> None:
93
+ """
94
+ Set the current credentials set.
95
+
96
+ Parameters
97
+ ----------
98
+ environment : str
99
+ Credentials set name.
100
+
101
+ Returns
102
+ -------
103
+ None
104
+ """
105
+ try:
106
+ cfg = load_file()
107
+ cfg["DEFAULT"]["current_environment"] = environment
108
+ with open(ENV_FILE, "w") as inifile:
109
+ cfg.write(inifile)
110
+
111
+ except Exception as e:
112
+ raise ClientError(f"Failed to write env file: {e}")
113
+
114
+
115
+ def read_env_from_file() -> str:
116
+ """
117
+ Read the current credentials set from the .dhcore.ini file.
118
+
119
+ Returns
120
+ -------
121
+ str
122
+ Credentials set name.
123
+ """
124
+ try:
125
+ cfg = load_file()
126
+ return cfg["DEFAULT"]["current_environment"]
127
+ except Exception as e:
128
+ raise ClientError(f"Failed to read env file: {e}")
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import typing
4
4
 
5
- from digitalhub.context.api import get_context
6
5
  from digitalhub.stores.data.builder import store_builder
7
6
 
8
7
  if typing.TYPE_CHECKING:
@@ -27,5 +26,4 @@ def get_store(project: str, uri: str) -> Store:
27
26
  Store
28
27
  Store instance.
29
28
  """
30
- config = get_context(project).config
31
- return store_builder.get(project, uri, config)
29
+ return store_builder.get(project, uri)
@@ -46,7 +46,7 @@ class StoreBuilder:
46
46
  def __init__(self) -> None:
47
47
  self._instances: dict[str, dict[str, Store]] = {}
48
48
 
49
- def build(self, project: str, store_type: str, config: dict) -> None:
49
+ def build(self, project: str, store_type: str) -> None:
50
50
  """
51
51
  Build a store instance and register it.
52
52
 
@@ -55,7 +55,6 @@ class StoreBuilder:
55
55
  store_type : str
56
56
  Store type.
57
57
  config : dict
58
- Store configuration.
59
58
 
60
59
  Returns
61
60
  -------
@@ -64,9 +63,9 @@ class StoreBuilder:
64
63
  env = get_current_env()
65
64
  if env not in self._instances:
66
65
  self._instances[env] = {}
67
- self._instances[env][store_type] = _get_class_from_type(store_type)(config)
66
+ self._instances[env][store_type] = _get_class_from_type(store_type)()
68
67
 
69
- def get(self, project: str, uri: str, config: dict) -> Store:
68
+ def get(self, project: str, uri: str) -> Store:
70
69
  """
71
70
  Get a store instance by URI.
72
71
 
@@ -87,7 +86,7 @@ class StoreBuilder:
87
86
  try:
88
87
  return self._instances[env][store_type]
89
88
  except KeyError:
90
- self.build(project, store_type, config)
89
+ self.build(project, store_type)
91
90
  return self._instances[env][store_type]
92
91
 
93
92
 
@@ -17,9 +17,6 @@ class LocalStore(Store):
17
17
  artifacts on local filesystem based storage.
18
18
  """
19
19
 
20
- def __init__(self, config: dict):
21
- pass
22
-
23
20
  ##############################
24
21
  # I/O methods
25
22
  ##############################
@@ -16,9 +16,6 @@ class RemoteStore(Store):
16
16
  artifacts from remote HTTP based storage.
17
17
  """
18
18
 
19
- def __init__(self, config: dict):
20
- pass
21
-
22
19
  ##############################
23
20
  # I/O methods
24
21
  ##############################
@@ -18,40 +18,20 @@ class S3StoreConfigurator:
18
18
  S3StoreEnv.ENDPOINT_URL,
19
19
  S3StoreEnv.ACCESS_KEY_ID,
20
20
  S3StoreEnv.SECRET_ACCESS_KEY,
21
- S3StoreEnv.BUCKET_NAME,
22
21
  ]
23
22
  optional_vars = [
24
23
  S3StoreEnv.REGION,
25
24
  S3StoreEnv.SIGNATURE_VERSION,
26
25
  S3StoreEnv.SESSION_TOKEN,
27
26
  ]
28
- project_vars = [
29
- S3StoreEnv.BUCKET_NAME,
30
- ]
31
27
 
32
28
  def __init__(self, config: dict) -> None:
33
- self.config = self.configure(config)
29
+ ...
34
30
 
35
31
  ##############################
36
32
  # Configuration methods
37
33
  ##############################
38
34
 
39
- def configure(self, config: dict) -> dict:
40
- """
41
- Configure the store by getting vars from project.
42
-
43
- Parameters
44
- ----------
45
- config : dict
46
- Configuration dictionary.
47
-
48
- Returns
49
- -------
50
- dict
51
- Configuration dictionary.
52
- """
53
- return {k: v for k, v in config.items() if k in self.project_vars}
54
-
55
35
  def get_boto3_client_config(self, origin: str) -> dict:
56
36
  """
57
37
  Get S3 credentials (access key, secret key,
@@ -73,7 +53,6 @@ class S3StoreConfigurator:
73
53
  creds = self._get_file_config()
74
54
  else:
75
55
  raise StoreError(f"Unknown origin: {origin}")
76
- creds = {**creds, **self.config}
77
56
  return {
78
57
  "endpoint_url": creds[S3StoreEnv.ENDPOINT_URL.value],
79
58
  "aws_access_key_id": creds[S3StoreEnv.ACCESS_KEY_ID.value],
@@ -28,8 +28,8 @@ class S3Store(Store):
28
28
  artifacts on S3 based storage.
29
29
  """
30
30
 
31
- def __init__(self, config: dict) -> None:
32
- self._configurator = S3StoreConfigurator(config)
31
+ def __init__(self) -> None:
32
+ self._configurator = S3StoreConfigurator()
33
33
 
34
34
  ##############################
35
35
  # I/O methods
@@ -19,33 +19,14 @@ class SqlStoreConfigurator:
19
19
  SqlStoreEnv.PORT,
20
20
  SqlStoreEnv.DATABASE,
21
21
  ]
22
- project_vars = [
23
- SqlStoreEnv.DATABASE,
24
- ]
25
22
 
26
- def __init__(self, config: dict) -> None:
27
- self.config = self.configure(config)
23
+ def __init__(self) -> None:
24
+ self.config = self.configure()
28
25
 
29
26
  ##############################
30
27
  # Configuration methods
31
28
  ##############################
32
29
 
33
- def configure(self, config: dict) -> dict:
34
- """
35
- Configure the store by getting vars from project.
36
-
37
- Parameters
38
- ----------
39
- config : dict
40
- Configuration dictionary.
41
-
42
- Returns
43
- -------
44
- dict
45
- Configuration dictionary.
46
- """
47
- return {k: v for k, v in config.items() if k in self.project_vars}
48
-
49
30
  def get_sql_conn_string(self, origin: str) -> str:
50
31
  """
51
32
  Get the connection string from environment variables.
@@ -27,8 +27,8 @@ class SqlStore(Store):
27
27
  artifacts on SQL based storage.
28
28
  """
29
29
 
30
- def __init__(self, config: dict) -> None:
31
- self._configurator = SqlStoreConfigurator(config)
30
+ def __init__(self) -> None:
31
+ self._configurator = SqlStoreConfigurator()
32
32
 
33
33
  ##############################
34
34
  # I/O methods
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalhub
3
- Version: 0.11.0b0
3
+ Version: 0.11.0b1
4
4
  Summary: Python SDK for Digitalhub
5
5
  Project-URL: Homepage, https://github.com/scc-digitalhub/digitalhub-sdk
6
6
  Author-email: Fondazione Bruno Kessler <dslab@fbk.eu>, Matteo Martini <mmartini@fbk.eu>
@@ -189,14 +189,14 @@ digitalhub/stores/client/_base/key_builder.py,sha256=xl3jM7z2eLP6HfPXusmZyLqsvfK
189
189
  digitalhub/stores/client/_base/params_builder.py,sha256=lCk4WE6DqvGP7-cx0anZEC8GtwsA7win7MVqACQQF9g,427
190
190
  digitalhub/stores/client/dhcore/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
191
191
  digitalhub/stores/client/dhcore/api_builder.py,sha256=J1kOMw4B4_PZKkEs7GPNcEkd1w-ZyJeB9G1UBZiMbl0,3975
192
- digitalhub/stores/client/dhcore/client.py,sha256=lZDZipcLu5ZjojTmrim5C5s3NvPsKxMpNALRGyoChqI,9848
193
- digitalhub/stores/client/dhcore/configurator.py,sha256=_7u1CXwRnmyhgYVIHFsvOxOmqKRwlotyLweVUz1yJR0,9331
192
+ digitalhub/stores/client/dhcore/client.py,sha256=SdwtCZ3HsQIxzYGUI3BPbwDEeRbcdpMliQNMWMEV4MA,9890
193
+ digitalhub/stores/client/dhcore/configurator.py,sha256=kLly2-87YAylsAZ8vhnTHmbfOhUSfn39Rl8M9n8Pc5g,9760
194
194
  digitalhub/stores/client/dhcore/enums.py,sha256=kaVXZTTa2WmsFbcc1CKWNLOM0JtUtcjL-KpspnTOhEE,523
195
195
  digitalhub/stores/client/dhcore/error_parser.py,sha256=GJUUkhp12cvC_LBIrC0teh4msmyb5WFxY2g4WNOkUwM,3305
196
196
  digitalhub/stores/client/dhcore/key_builder.py,sha256=YuSS5tRNRJTYlH14buetFSCU_bLuBBKLqMFO3MQ6r4g,1324
197
197
  digitalhub/stores/client/dhcore/models.py,sha256=WX53m8B9YiUqebH9ZZuUm2fhIWGoqHkagrHn3swOQDI,642
198
198
  digitalhub/stores/client/dhcore/params_builder.py,sha256=TOOiZ3UlfgGFbvQpEVfsqnKxlDqgbOHQRxp71o-Z4AU,5847
199
- digitalhub/stores/client/dhcore/utils.py,sha256=Gmk-jsv0jG3u39sO88HKhjkaP2cNKWN0LhqgyWmMGSI,1899
199
+ digitalhub/stores/client/dhcore/utils.py,sha256=kYRs-3tpOWzbwToHyIjJUoZlEG_w-bK7QFz57JPMQdY,1939
200
200
  digitalhub/stores/client/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  digitalhub/stores/client/local/api_builder.py,sha256=nUO92IpPgnXBnPOh2486NzWfqQX4RE2t9nfIUSd-rAg,3043
202
202
  digitalhub/stores/client/local/client.py,sha256=Vp93yq_Z-D03SNM6pmZrhThKvAbdgMCUjMFXNV1fUHk,18115
@@ -205,32 +205,32 @@ digitalhub/stores/client/local/key_builder.py,sha256=bS-a2zc3rklNGuhc94d04_CnL7O
205
205
  digitalhub/stores/client/local/params_builder.py,sha256=ke8toBUDuSZiSo3WN6jeALnt-EPXZKi8_i5BHJx0HDk,3481
206
206
  digitalhub/stores/configurator/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
207
  digitalhub/stores/configurator/api.py,sha256=-dRdkXh99SztWaeRfqztVXhT8f95aVBjDK7JPElj_ug,560
208
- digitalhub/stores/configurator/configurator.py,sha256=-N3Lkx7TeY21kRrG97awjU48tQGUQAKFu5goo9_GkWg,4641
208
+ digitalhub/stores/configurator/configurator.py,sha256=z9RaQ_xKm_d1S3GdrSqfbV3ikEfHg6XogQMWDL7xc84,4762
209
209
  digitalhub/stores/configurator/credentials_store.py,sha256=kiaCm37Sl1SN9OaMbsfZA1l1a9Xg6R6a00H7Upcf8Vg,1508
210
210
  digitalhub/stores/configurator/enums.py,sha256=3Sf6UbYWYiJK4LaDzfgS2ay8Jxh-jIzR_3WRLt6m9do,288
211
- digitalhub/stores/configurator/ini_module.py,sha256=3NfAFAwIoAV4QhHoY-_4frCk2A2iYANuIvWMbn5vG_Y,1826
211
+ digitalhub/stores/configurator/ini_module.py,sha256=fGMQ8n28wXqmDCnk6x_VCE99KWqa7qU1OmQEEfWhQa8,2960
212
212
  digitalhub/stores/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
213
- digitalhub/stores/data/api.py,sha256=9VAsYOGx0zAPJjcyYJGWkH9EQOExzGjir_sKQf1admw,639
214
- digitalhub/stores/data/builder.py,sha256=mPeyrfpWAB93hGZGCiQQwSUbktpJTDsNqM2GvgYXBb4,2366
213
+ digitalhub/stores/data/api.py,sha256=R-yBTWpLDrFfcFAju0PJVl0_CDROM8lV2QHKtIMwGrI,543
214
+ digitalhub/stores/data/builder.py,sha256=fh1JFFos7TpfgWlEWL9WmIEdrpt4t1dQU2Ivq8qE4QE,2291
215
215
  digitalhub/stores/data/enums.py,sha256=dqDRDnLVK55jiWyg_L-aeTwu3JBo4EcN5epxzdS_ARs,190
216
216
  digitalhub/stores/data/utils.py,sha256=aDo8Mg9AYTtDYcyzKs0vSAj1rYhM14sAtCRk3SxgYsU,912
217
217
  digitalhub/stores/data/_base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
218
218
  digitalhub/stores/data/_base/store.py,sha256=VC1r7b9EIoObuG2DiqtFk2DQDSOgaS9jYL_UmiOTMHg,5241
219
219
  digitalhub/stores/data/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
- digitalhub/stores/data/local/store.py,sha256=ez--WlPiS0W-EJUHBMp2Dw7ZkQ0-Xb5XAj5jjdicIHA,7388
220
+ digitalhub/stores/data/local/store.py,sha256=lzagCi_3-bvH5IaMNMNnGGT2mNE-KG_F-CMS45elcMo,7336
221
221
  digitalhub/stores/data/remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
222
- digitalhub/stores/data/remote/store.py,sha256=XDd61ydF7UcCsm4ZL9a65ZxH06xZj3dUL10MwarXwzk,6150
222
+ digitalhub/stores/data/remote/store.py,sha256=9KCFk8Fz1Mr7AK8gEITMh2sMw_jQldNPaVpk5_Oko9w,6098
223
223
  digitalhub/stores/data/s3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
224
- digitalhub/stores/data/s3/configurator.py,sha256=9Qw24uFovFDLWN7-Riuf5Zjl3m8U9SE4nLe6HQyB1_I,4260
224
+ digitalhub/stores/data/s3/configurator.py,sha256=3AK1EDVhm7MIRWebendNVs7ViktkgsC_oKzmH3HOqqI,3707
225
225
  digitalhub/stores/data/s3/enums.py,sha256=tmSavz83jr6SBW-Gqn4D21TJpFytxvbtbW63htmZG2A,392
226
226
  digitalhub/stores/data/s3/models.py,sha256=qeXeL7iP76EBO35wzP6bYeMj-sBOY634Tjwx8h3Di2g,371
227
- digitalhub/stores/data/s3/store.py,sha256=FQsHDN_s1tjt1vCXTPO1pg26rwh7SZIiL2VOnUOEdTs,19684
227
+ digitalhub/stores/data/s3/store.py,sha256=BXyMdDjF_bj2TqAx5RSXrzWKIGE7PMObFSqEp1n-ZPo,19664
228
228
  digitalhub/stores/data/s3/utils.py,sha256=Su-7AbIuDItbaA2BSrnl7Tm-BrrqPQPOaDXb06C_BRw,1505
229
229
  digitalhub/stores/data/sql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
230
- digitalhub/stores/data/sql/configurator.py,sha256=PEG3Kg0PJXpZRW_5dcAEhhd1-Qd56akhpi3QykJD8tg,3767
230
+ digitalhub/stores/data/sql/configurator.py,sha256=7VXnXC8ItxdVnV2R8mAWAZZAsnvuDKgRElqtOF2oT-c,3302
231
231
  digitalhub/stores/data/sql/enums.py,sha256=FCpmIXxef6SQIX_564a1hYvaSVrpvld8gi7YAv25H-o,284
232
232
  digitalhub/stores/data/sql/models.py,sha256=_itIXoCfRLzUpG0OaM44qbv2u87Lyl5e0tmAXNTvfjQ,349
233
- digitalhub/stores/data/sql/store.py,sha256=21pXhJjzumGG1ycIU8SSY-V0Nvoc3DM1lhkfSS0ECyk,11721
233
+ digitalhub/stores/data/sql/store.py,sha256=FnT4C1n7M3DM1i6LccGcEBq9_YNLtVhm__6_L2eQgvI,11701
234
234
  digitalhub/stores/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
235
235
  digitalhub/stores/readers/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
236
236
  digitalhub/stores/readers/data/api.py,sha256=rHnhzsUWp6s23qVqXcBO3jGkI2IeiWyBictHnOPbBEw,1858
@@ -252,7 +252,7 @@ digitalhub/utils/io_utils.py,sha256=8jD4Rp_b7LZEpY5JSMxVUowZsnifKnbGpHT5Hijx9-g,
252
252
  digitalhub/utils/logger.py,sha256=ml3ne6D8wuRdNZ4F6ywmvWotSxjmZWnmKgNiuHb4R5M,437
253
253
  digitalhub/utils/types.py,sha256=x8zXsbivD8vdaNeNRZLKOPvGbz6d-59nncuvO0FsueY,109
254
254
  digitalhub/utils/uri_utils.py,sha256=wVkA2OcfHG5EcQOr9YxLJzo--VV6sjFjgXDNx-gP94I,4021
255
- digitalhub-0.11.0b0.dist-info/METADATA,sha256=I_aNyRmRCJNfRvZS4VfuGbbWshofsvMT1HQ2ve91qNM,15037
256
- digitalhub-0.11.0b0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
257
- digitalhub-0.11.0b0.dist-info/licenses/LICENSE.txt,sha256=qmrTTXPlgU0kSRlRVbjhlyGs1IXs2QPxo_Y-Mn06J0k,11589
258
- digitalhub-0.11.0b0.dist-info/RECORD,,
255
+ digitalhub-0.11.0b1.dist-info/METADATA,sha256=wEs05Q94UJUZU9W-eAdYpxXJq97g5aZWzDFekImT38w,15037
256
+ digitalhub-0.11.0b1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
257
+ digitalhub-0.11.0b1.dist-info/licenses/LICENSE.txt,sha256=qmrTTXPlgU0kSRlRVbjhlyGs1IXs2QPxo_Y-Mn06J0k,11589
258
+ digitalhub-0.11.0b1.dist-info/RECORD,,