digitalhub 0.10.0b5__py3-none-any.whl → 0.10.0b7__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 (49) 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 +22 -0
  7. digitalhub/client/dhcore/params_builder.py +178 -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/entities/_base/context/entity.py +4 -4
  12. digitalhub/entities/_base/executable/entity.py +2 -2
  13. digitalhub/entities/_base/material/entity.py +3 -3
  14. digitalhub/entities/_base/unversioned/entity.py +2 -2
  15. digitalhub/entities/_base/versioned/entity.py +2 -2
  16. digitalhub/entities/_commons/enums.py +1 -0
  17. digitalhub/entities/_commons/metrics.py +164 -0
  18. digitalhub/entities/_commons/utils.py +0 -26
  19. digitalhub/entities/_processors/base.py +527 -0
  20. digitalhub/entities/{_operations/processor.py → _processors/context.py} +85 -739
  21. digitalhub/entities/_processors/utils.py +158 -0
  22. digitalhub/entities/artifact/crud.py +10 -10
  23. digitalhub/entities/dataitem/crud.py +10 -10
  24. digitalhub/entities/function/crud.py +9 -9
  25. digitalhub/entities/model/_base/entity.py +26 -78
  26. digitalhub/entities/model/_base/status.py +1 -1
  27. digitalhub/entities/model/crud.py +10 -10
  28. digitalhub/entities/project/_base/entity.py +317 -9
  29. digitalhub/entities/project/crud.py +10 -9
  30. digitalhub/entities/run/_base/entity.py +32 -84
  31. digitalhub/entities/run/_base/status.py +1 -1
  32. digitalhub/entities/run/crud.py +8 -8
  33. digitalhub/entities/secret/_base/entity.py +3 -3
  34. digitalhub/entities/secret/crud.py +9 -9
  35. digitalhub/entities/task/_base/entity.py +4 -4
  36. digitalhub/entities/task/_base/models.py +10 -0
  37. digitalhub/entities/task/crud.py +8 -8
  38. digitalhub/entities/workflow/crud.py +9 -9
  39. digitalhub/stores/s3/enums.py +7 -7
  40. digitalhub/stores/sql/enums.py +6 -6
  41. digitalhub/utils/git_utils.py +16 -9
  42. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/METADATA +1 -4
  43. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/RECORD +46 -43
  44. digitalhub/entities/_base/project/entity.py +0 -341
  45. digitalhub/entities/_commons/models.py +0 -13
  46. digitalhub/entities/_operations/__init__.py +0 -0
  47. /digitalhub/entities/{_base/project → _processors}/__init__.py +0 -0
  48. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/WHEEL +0 -0
  49. {digitalhub-0.10.0b5.dist-info → digitalhub-0.10.0b7.dist-info}/licenses/LICENSE.txt +0 -0
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.entities._commons.enums import EntityTypes
6
- from digitalhub.entities._operations.processor import processor
6
+ from digitalhub.entities._processors.context import context_processor
7
7
  from digitalhub.utils.exceptions import EntityError
8
8
 
9
9
  if typing.TYPE_CHECKING:
@@ -53,7 +53,7 @@ def new_run(
53
53
  >>> kind="python+run",
54
54
  >>> task="task-string")
55
55
  """
56
- return processor.create_context_entity(
56
+ return context_processor.create_context_entity(
57
57
  project=project,
58
58
  kind=kind,
59
59
  uuid=uuid,
@@ -95,7 +95,7 @@ def get_run(
95
95
  >>> obj = get_run("my-run-id"
96
96
  >>> project="my-project")
97
97
  """
98
- return processor.read_unversioned_entity(
98
+ return context_processor.read_unversioned_entity(
99
99
  identifier,
100
100
  entity_type=ENTITY_TYPE,
101
101
  project=project,
@@ -124,7 +124,7 @@ def list_runs(project: str, **kwargs) -> list[Run]:
124
124
  >>> objs = list_runs(project="my-project")
125
125
  """
126
126
  # TODO more examples: search by function, latest for task and function
127
- return processor.list_context_entities(
127
+ return context_processor.list_context_entities(
128
128
  project=project,
129
129
  entity_type=ENTITY_TYPE,
130
130
  **kwargs,
@@ -149,7 +149,7 @@ def import_run(file: str) -> Run:
149
149
  -------
150
150
  >>> obj = import_run("my-run.yaml")
151
151
  """
152
- return processor.import_context_entity(file)
152
+ return context_processor.import_context_entity(file)
153
153
 
154
154
 
155
155
  def load_run(file: str) -> Run:
@@ -170,7 +170,7 @@ def load_run(file: str) -> Run:
170
170
  --------
171
171
  >>> obj = load_run("my-run.yaml")
172
172
  """
173
- return processor.load_context_entity(file)
173
+ return context_processor.load_context_entity(file)
174
174
 
175
175
 
176
176
  def update_run(entity: Run) -> Run:
@@ -191,7 +191,7 @@ def update_run(entity: Run) -> Run:
191
191
  --------
192
192
  >>> obj = update_run(obj)
193
193
  """
194
- return processor.update_context_entity(
194
+ return context_processor.update_context_entity(
195
195
  project=entity.project,
196
196
  entity_type=entity.ENTITY_TYPE,
197
197
  entity_id=entity.id,
@@ -228,7 +228,7 @@ def delete_run(
228
228
  """
229
229
  if not identifier.startswith("store://") and project is None:
230
230
  raise EntityError("Specify entity key or entity ID combined with project")
231
- return processor.delete_context_entity(
231
+ return context_processor.delete_context_entity(
232
232
  identifier=identifier,
233
233
  entity_type=ENTITY_TYPE,
234
234
  project=project,
@@ -4,7 +4,7 @@ import typing
4
4
 
5
5
  from digitalhub.entities._base.versioned.entity import VersionedEntity
6
6
  from digitalhub.entities._commons.enums import EntityTypes
7
- from digitalhub.entities._operations.processor import processor
7
+ from digitalhub.entities._processors.context import context_processor
8
8
 
9
9
  if typing.TYPE_CHECKING:
10
10
  from digitalhub.entities._base.entity.metadata import Metadata
@@ -52,7 +52,7 @@ class Secret(VersionedEntity):
52
52
  None
53
53
  """
54
54
  obj = {self.name: value}
55
- processor.update_secret_data(self.project, self.ENTITY_TYPE, obj)
55
+ context_processor.update_secret_data(self.project, self.ENTITY_TYPE, obj)
56
56
 
57
57
  def read_secret_value(self) -> dict:
58
58
  """
@@ -64,5 +64,5 @@ class Secret(VersionedEntity):
64
64
  Value of the secret.
65
65
  """
66
66
  params = {"keys": self.name}
67
- data = processor.read_secret_data(self.project, self.ENTITY_TYPE, params=params)
67
+ data = context_processor.read_secret_data(self.project, self.ENTITY_TYPE, params=params)
68
68
  return data[self.name]
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.entities._commons.enums import EntityTypes
6
- from digitalhub.entities._operations.processor import processor
6
+ from digitalhub.entities._processors.context import context_processor
7
7
  from digitalhub.utils.exceptions import EntityNotExistsError
8
8
 
9
9
  if typing.TYPE_CHECKING:
@@ -58,7 +58,7 @@ def new_secret(
58
58
  """
59
59
  if secret_value is None:
60
60
  raise ValueError("secret_value must be provided.")
61
- obj: Secret = processor.create_context_entity(
61
+ obj: Secret = context_processor.create_context_entity(
62
62
  project=project,
63
63
  name=name,
64
64
  kind="secret",
@@ -116,7 +116,7 @@ def get_secret(
116
116
  return secret
117
117
  else:
118
118
  raise EntityNotExistsError(f"Secret {identifier} not found.")
119
- return processor.read_context_entity(
119
+ return context_processor.read_context_entity(
120
120
  identifier,
121
121
  entity_type=ENTITY_TYPE,
122
122
  project=project,
@@ -156,7 +156,7 @@ def get_secret_versions(
156
156
  >>> objs = get_secret_versions("my-secret-name",
157
157
  >>> project="my-project")
158
158
  """
159
- return processor.read_context_entity_versions(
159
+ return context_processor.read_context_entity_versions(
160
160
  identifier,
161
161
  entity_type=ENTITY_TYPE,
162
162
  project=project,
@@ -184,7 +184,7 @@ def list_secrets(project: str, **kwargs) -> list[Secret]:
184
184
  --------
185
185
  >>> objs = list_secrets(project="my-project")
186
186
  """
187
- return processor.list_context_entities(
187
+ return context_processor.list_context_entities(
188
188
  project=project,
189
189
  entity_type=ENTITY_TYPE,
190
190
  **kwargs,
@@ -209,7 +209,7 @@ def import_secret(file: str) -> Secret:
209
209
  --------
210
210
  >>> obj = import_secret("my-secret.yaml")
211
211
  """
212
- return processor.import_context_entity(file)
212
+ return context_processor.import_context_entity(file)
213
213
 
214
214
 
215
215
  def load_secret(file: str) -> Secret:
@@ -230,7 +230,7 @@ def load_secret(file: str) -> Secret:
230
230
  --------
231
231
  >>> obj = load_secret("my-secret.yaml")
232
232
  """
233
- return processor.load_context_entity(file)
233
+ return context_processor.load_context_entity(file)
234
234
 
235
235
 
236
236
  def update_secret(entity: Secret) -> Secret:
@@ -251,7 +251,7 @@ def update_secret(entity: Secret) -> Secret:
251
251
  --------
252
252
  >>> obj = update_secret(obj)
253
253
  """
254
- return processor.update_context_entity(
254
+ return context_processor.update_context_entity(
255
255
  project=entity.project,
256
256
  entity_type=entity.ENTITY_TYPE,
257
257
  entity_id=entity.id,
@@ -297,7 +297,7 @@ def delete_secret(
297
297
  >>> project="my-project",
298
298
  >>> delete_all_versions=True)
299
299
  """
300
- return processor.delete_context_entity(
300
+ return context_processor.delete_context_entity(
301
301
  identifier=identifier,
302
302
  entity_type=ENTITY_TYPE,
303
303
  project=project,
@@ -4,7 +4,7 @@ import typing
4
4
 
5
5
  from digitalhub.entities._base.unversioned.entity import UnversionedEntity
6
6
  from digitalhub.entities._commons.enums import EntityTypes
7
- from digitalhub.entities._operations.processor import processor
7
+ from digitalhub.entities._processors.context import context_processor
8
8
  from digitalhub.factory.api import build_entity_from_params, get_entity_type_from_kind, get_executable_kind
9
9
 
10
10
  if typing.TYPE_CHECKING:
@@ -107,7 +107,7 @@ class Task(UnversionedEntity):
107
107
  Run object.
108
108
  """
109
109
  if save:
110
- return processor.create_context_entity(**kwargs)
110
+ return context_processor.create_context_entity(**kwargs)
111
111
  return build_entity_from_params(**kwargs)
112
112
 
113
113
  def get_run(self, entity_key: str) -> Run:
@@ -124,7 +124,7 @@ class Task(UnversionedEntity):
124
124
  Run
125
125
  Run object.
126
126
  """
127
- return processor.read_context_entity(entity_key)
127
+ return context_processor.read_context_entity(entity_key)
128
128
 
129
129
  def delete_run(self, entity_key: str) -> dict:
130
130
  """
@@ -140,4 +140,4 @@ class Task(UnversionedEntity):
140
140
  dict
141
141
  Response from backend.
142
142
  """
143
- return processor.delete_context_entity(entity_key)
143
+ return context_processor.delete_context_entity(entity_key)
@@ -236,3 +236,13 @@ class CoreServiceType(Enum):
236
236
  CLUSTER_IP = "ClusterIP"
237
237
  NODE_PORT = "NodePort"
238
238
  LOAD_BALANCER = "LoadBalancer"
239
+
240
+
241
+ class CorePullPolicy(Enum):
242
+ """
243
+ CorePullPolicy enum.
244
+ """
245
+
246
+ ALWAYS = "Always"
247
+ IF_NOT_PRESENT = "IfNotPresent"
248
+ NEVER = "Never"
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.entities._commons.enums import EntityTypes
6
- from digitalhub.entities._operations.processor import processor
6
+ from digitalhub.entities._processors.context import context_processor
7
7
  from digitalhub.utils.exceptions import EntityError
8
8
 
9
9
  if typing.TYPE_CHECKING:
@@ -53,7 +53,7 @@ def new_task(
53
53
  >>> kind="python+job",
54
54
  >>> function="function-string")
55
55
  """
56
- return processor.create_context_entity(
56
+ return context_processor.create_context_entity(
57
57
  project=project,
58
58
  kind=kind,
59
59
  uuid=uuid,
@@ -95,7 +95,7 @@ def get_task(
95
95
  >>> obj = get_task("my-task-id"
96
96
  >>> project="my-project")
97
97
  """
98
- return processor.read_unversioned_entity(
98
+ return context_processor.read_unversioned_entity(
99
99
  identifier,
100
100
  entity_type=ENTITY_TYPE,
101
101
  project=project,
@@ -123,7 +123,7 @@ def list_tasks(project: str, **kwargs) -> list[Task]:
123
123
  --------
124
124
  >>> objs = list_tasks(project="my-project")
125
125
  """
126
- return processor.list_context_entities(
126
+ return context_processor.list_context_entities(
127
127
  project=project,
128
128
  entity_type=ENTITY_TYPE,
129
129
  **kwargs,
@@ -148,7 +148,7 @@ def import_task(file: str) -> Task:
148
148
  -------
149
149
  >>> obj = import_task("my-task.yaml")
150
150
  """
151
- return processor.import_context_entity(file)
151
+ return context_processor.import_context_entity(file)
152
152
 
153
153
 
154
154
  def load_task(file: str) -> Task:
@@ -169,7 +169,7 @@ def load_task(file: str) -> Task:
169
169
  --------
170
170
  >>> obj = load_task("my-task.yaml")
171
171
  """
172
- return processor.load_context_entity(file)
172
+ return context_processor.load_context_entity(file)
173
173
 
174
174
 
175
175
  def update_task(entity: Task) -> Task:
@@ -190,7 +190,7 @@ def update_task(entity: Task) -> Task:
190
190
  --------
191
191
  >>> obj = update_task(obj)
192
192
  """
193
- return processor.update_context_entity(
193
+ return context_processor.update_context_entity(
194
194
  project=entity.project,
195
195
  entity_type=entity.ENTITY_TYPE,
196
196
  entity_id=entity.id,
@@ -241,7 +241,7 @@ def delete_task(
241
241
  """
242
242
  if not identifier.startswith("store://"):
243
243
  raise EntityError("Task has no name. Use key instead.")
244
- return processor.delete_context_entity(
244
+ return context_processor.delete_context_entity(
245
245
  identifier=identifier,
246
246
  entity_type=ENTITY_TYPE,
247
247
  project=project,
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import typing
4
4
 
5
5
  from digitalhub.entities._commons.enums import EntityTypes
6
- from digitalhub.entities._operations.processor import processor
6
+ from digitalhub.entities._processors.context import context_processor
7
7
 
8
8
  if typing.TYPE_CHECKING:
9
9
  from digitalhub.entities.workflow._base.entity import Workflow
@@ -55,7 +55,7 @@ def new_workflow(
55
55
  >>> code_src="pipeline.py",
56
56
  >>> handler="pipeline-handler")
57
57
  """
58
- return processor.create_context_entity(
58
+ return context_processor.create_context_entity(
59
59
  project=project,
60
60
  name=name,
61
61
  kind=kind,
@@ -102,7 +102,7 @@ def get_workflow(
102
102
  >>> project="my-project",
103
103
  >>> entity_id="my-workflow-id")
104
104
  """
105
- return processor.read_context_entity(
105
+ return context_processor.read_context_entity(
106
106
  identifier,
107
107
  entity_type=ENTITY_TYPE,
108
108
  project=project,
@@ -142,7 +142,7 @@ def get_workflow_versions(
142
142
  >>> obj = get_workflow_versions("my-workflow-name"
143
143
  >>> project="my-project")
144
144
  """
145
- return processor.read_context_entity_versions(
145
+ return context_processor.read_context_entity_versions(
146
146
  identifier,
147
147
  entity_type=ENTITY_TYPE,
148
148
  project=project,
@@ -170,7 +170,7 @@ def list_workflows(project: str, **kwargs) -> list[Workflow]:
170
170
  --------
171
171
  >>> objs = list_workflows(project="my-project")
172
172
  """
173
- return processor.list_context_entities(
173
+ return context_processor.list_context_entities(
174
174
  project=project,
175
175
  entity_type=ENTITY_TYPE,
176
176
  **kwargs,
@@ -195,7 +195,7 @@ def import_workflow(file: str) -> Workflow:
195
195
  --------
196
196
  >>> obj = import_workflow("my-workflow.yaml")
197
197
  """
198
- return processor.import_executable_entity(file)
198
+ return context_processor.import_executable_entity(file)
199
199
 
200
200
 
201
201
  def load_workflow(file: str) -> Workflow:
@@ -216,7 +216,7 @@ def load_workflow(file: str) -> Workflow:
216
216
  --------
217
217
  >>> obj = load_workflow("my-workflow.yaml")
218
218
  """
219
- return processor.load_executable_entity(file)
219
+ return context_processor.load_executable_entity(file)
220
220
 
221
221
 
222
222
  def update_workflow(entity: Workflow) -> Workflow:
@@ -237,7 +237,7 @@ def update_workflow(entity: Workflow) -> Workflow:
237
237
  --------
238
238
  >>> obj = update_workflow(obj)
239
239
  """
240
- return processor.update_context_entity(
240
+ return context_processor.update_context_entity(
241
241
  project=entity.project,
242
242
  entity_type=entity.ENTITY_TYPE,
243
243
  entity_id=entity.id,
@@ -286,7 +286,7 @@ def delete_workflow(
286
286
  >>> project="my-project",
287
287
  >>> delete_all_versions=True)
288
288
  """
289
- return processor.delete_context_entity(
289
+ return context_processor.delete_context_entity(
290
290
  identifier=identifier,
291
291
  entity_type=ENTITY_TYPE,
292
292
  project=project,
@@ -8,10 +8,10 @@ class S3StoreEnv(Enum):
8
8
  S3Store environment
9
9
  """
10
10
 
11
- ENDPOINT_URL = "DHCORE_S3_ENDPOINT_URL"
12
- ACCESS_KEY_ID = "DHCORE_AWS_ACCESS_KEY_ID"
13
- SECRET_ACCESS_KEY = "DHCORE_AWS_SECRET_ACCESS_KEY"
14
- SESSION_TOKEN = "DHCORE_AWS_SESSION_TOKEN"
15
- BUCKET_NAME = "DHCORE_S3_BUCKET"
16
- REGION = "DHCORE_S3_REGION"
17
- SIGNATURE_VERSION = "DHCORE_S3_SIGNATURE_VERSION"
11
+ ENDPOINT_URL = "S3_ENDPOINT_URL"
12
+ ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID"
13
+ SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY"
14
+ SESSION_TOKEN = "AWS_SESSION_TOKEN"
15
+ BUCKET_NAME = "S3_BUCKET"
16
+ REGION = "S3_REGION"
17
+ SIGNATURE_VERSION = "S3_SIGNATURE_VERSION"
@@ -8,9 +8,9 @@ class SqlStoreEnv(Enum):
8
8
  SqlStore environment
9
9
  """
10
10
 
11
- HOST = "DHCORE_DB_HOST"
12
- PORT = "DHCORE_DB_PORT"
13
- USERNAME = "DHCORE_DB_USERNAME"
14
- PASSWORD = "DHCORE_DB_PASSWORD"
15
- DATABASE = "DHCORE_DB_DATABASE"
16
- PG_SCHEMA = "DHCORE_DB_SCHEMA"
11
+ HOST = "DB_HOST"
12
+ PORT = "DB_PORT"
13
+ USERNAME = "DB_USERNAME"
14
+ PASSWORD = "DB_PASSWORD"
15
+ DATABASE = "DB_DATABASE"
16
+ PG_SCHEMA = "DB_SCHEMA"
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import os
4
4
  import shutil
5
5
  import warnings
6
+ from enum import Enum
6
7
  from pathlib import Path
7
8
  from urllib.parse import urlparse
8
9
 
@@ -13,6 +14,16 @@ except ImportError as e:
13
14
  warnings.warn("git is not installed. Please install git and try again.", RuntimeWarning)
14
15
 
15
16
 
17
+ class GitCredentialsType(Enum):
18
+ """
19
+ Supported git credentials types.
20
+ """
21
+
22
+ USERNAME = "GIT_USERNAME"
23
+ PASSWORD = "GIT_PASSWORD"
24
+ TOKEN = "GIT_TOKEN"
25
+
26
+
16
27
  def clone_repository(path: Path, url: str) -> None:
17
28
  """
18
29
  Clone git repository.
@@ -90,12 +101,8 @@ def get_git_username_password_from_token(token: str) -> tuple[str, str]:
90
101
  """
91
102
  # Mutued from mlrun
92
103
  if token.startswith("github_pat_") or token.startswith("glpat"):
93
- username = "oauth2"
94
- password = token
95
- else:
96
- username = token
97
- password = "x-oauth-basic"
98
- return username, password
104
+ return "oauth2", token
105
+ return token, "x-oauth-basic"
99
106
 
100
107
 
101
108
  def add_credentials_git_remote_url(url: str) -> str:
@@ -115,9 +122,9 @@ def add_credentials_git_remote_url(url: str) -> str:
115
122
  url_obj = urlparse(url)
116
123
 
117
124
  # Get credentials from environment variables
118
- username = os.getenv("GIT_USERNAME")
119
- password = os.getenv("GIT_PASSWORD")
120
- token = os.getenv("GIT_TOKEN")
125
+ username = os.getenv(GitCredentialsType.USERNAME.value)
126
+ password = os.getenv(GitCredentialsType.PASSWORD.value)
127
+ token = os.getenv(GitCredentialsType.TOKEN.value)
121
128
 
122
129
  # Get credentials from token. Override username and password
123
130
  if token is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: digitalhub
3
- Version: 0.10.0b5
3
+ Version: 0.10.0b7
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>
@@ -244,16 +244,13 @@ Requires-Dist: jsonschema; extra == 'dev'
244
244
  Requires-Dist: pytest; extra == 'dev'
245
245
  Requires-Dist: pytest-cov; extra == 'dev'
246
246
  Provides-Extra: full
247
- Requires-Dist: fsspec; extra == 'full'
248
247
  Requires-Dist: mlflow; extra == 'full'
249
248
  Requires-Dist: pandas; extra == 'full'
250
- Requires-Dist: s3fs; extra == 'full'
251
249
  Provides-Extra: mlflow
252
250
  Requires-Dist: mlflow; extra == 'mlflow'
253
251
  Provides-Extra: pandas
254
252
  Requires-Dist: fsspec; extra == 'pandas'
255
253
  Requires-Dist: pandas; extra == 'pandas'
256
- Requires-Dist: s3fs; extra == 'pandas'
257
254
  Description-Content-Type: text/markdown
258
255
 
259
256
  # Digitalhub Library