dsi-workflow 1.2.2__tar.gz → 1.2.3__tar.gz

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 (61) hide show
  1. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/PKG-INFO +1 -1
  2. dsi_workflow-1.2.3/dsi/_version.py +1 -0
  3. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/oceans11.py +18 -2
  4. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/dsi.py +2 -2
  5. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/sync.py +28 -8
  6. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/federated/federate_datasets.py +7 -3
  7. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/s3_utils.py +12 -10
  8. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/PKG-INFO +1 -1
  9. dsi_workflow-1.2.2/dsi/_version.py +0 -1
  10. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/README.rst +0 -0
  11. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/__init__.py +0 -0
  12. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/backend.py +0 -0
  13. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/duckdb.py +0 -0
  14. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/filesystem.py +0 -0
  15. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/gufi.py +0 -0
  16. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/hpss.py +0 -0
  17. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/ndp.py +0 -0
  18. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/osti.py +0 -0
  19. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/sqlalchemy.py +0 -0
  20. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/sqlite.py +0 -0
  21. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_duckdb.py +0 -0
  22. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_gufi.py +0 -0
  23. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_hpss.py +0 -0
  24. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_ndp.py +0 -0
  25. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_sqlalchemy.py +0 -0
  26. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/tests/test_sqlite.py +0 -0
  27. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/backends/webserver.py +0 -0
  28. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/cli.py +0 -0
  29. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/core.py +0 -0
  30. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/dsifederated.py +0 -0
  31. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/collection_reader.py +0 -0
  32. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/dashboard.py +0 -0
  33. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/env.py +0 -0
  34. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/file_reader.py +0 -0
  35. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/file_writer.py +0 -0
  36. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/metadata.py +0 -0
  37. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/ml_emulator.py +0 -0
  38. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/plugin.py +0 -0
  39. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/plugin_models.py +0 -0
  40. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/tests/test_collection_reader.py +0 -0
  41. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/tests/test_env.py +0 -0
  42. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/tests/test_file_reader.py +0 -0
  43. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/plugins/tests/test_file_writer.py +0 -0
  44. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/tests/test_core.py +0 -0
  45. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/tests/test_dsi.py +0 -0
  46. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/__init__.py +0 -0
  47. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/dsi_utils.py +0 -0
  48. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/federated/__init__.py +0 -0
  49. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/federation_utils.py +0 -0
  50. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/git_utils.py +0 -0
  51. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/hpc_kerberos.py +0 -0
  52. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/rsync_utils.py +0 -0
  53. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi/utils/web_utils.py +0 -0
  54. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/SOURCES.txt +0 -0
  55. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/dependency_links.txt +0 -0
  56. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/entry_points.txt +0 -0
  57. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/requires.txt +0 -0
  58. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/dsi_workflow.egg-info/top_level.txt +0 -0
  59. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/pyproject.toml +0 -0
  60. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/requirements.txt +0 -0
  61. {dsi_workflow-1.2.2 → dsi_workflow-1.2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dsi-workflow
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: A Data Science Infrastructure Project
5
5
  Author-email: Jesus Pulido <pulido@lanl.gov>, James Ahrens <ahrens@lanl.gov>, Divya Banesh <dbanesh@lanl.gov>, Hugh Greenberg <hng@lanl.gov>, Pascal Grosset <pascalgrosset@lanl.gov>, Vedant Iyer <iyer@lanl.gov>, Benjamin Sims <bsims@lanl.gov>, Terece Turton <tlturton@lanl.gov>
6
6
  License-Expression: BSD-3-Clause
@@ -0,0 +1 @@
1
+ __version__ = "1.2.3"
@@ -85,7 +85,7 @@ class Oceans11(Webserver):
85
85
  DEFAULT_URL = "https://oceans11.lanl.gov/dataCatalog/oceans11.db"
86
86
  base_url = url or DEFAULT_URL
87
87
 
88
- # ----------------------------------------------------------------------
88
+ # ----------------------------------------------------------------------
89
89
  # Auth / connection config
90
90
  # ----------------------------------------------------------------------
91
91
  self.workspace = kwargs.get(
@@ -99,6 +99,10 @@ class Oceans11(Webserver):
99
99
 
100
100
  self.base_url = base_url.rstrip("/")
101
101
 
102
+ # skip data retrieval if only checking connection to oceans11
103
+ if kwargs.get("only_validate", False):
104
+ return
105
+
102
106
  # Data storage (tiered structure)
103
107
  # Tier 1: datasets, Tier 2: per-dataset resource tables
104
108
  self._cache = OrderedDict()
@@ -131,7 +135,7 @@ class Oceans11(Webserver):
131
135
  # ----------------------------------------------------------------------
132
136
  # Connection Validation
133
137
  # ----------------------------------------------------------------------
134
- def validate_connection(self):
138
+ def validate_connection(self, **kwargs):
135
139
  """
136
140
  Validates that the base Oceans11 URL is accessible and functional.
137
141
 
@@ -162,15 +166,27 @@ class Oceans11(Webserver):
162
166
  )
163
167
 
164
168
  if info is None:
169
+ if kwargs.get("only_validate", False):
170
+ return False
165
171
  raise ConnectionError(f"Failed to download catalog from {self.base_url}")
166
172
 
167
173
  local_path = info.get("local_path")
168
174
  if not local_path or not Path(local_path).is_file():
175
+ if kwargs.get("only_validate", False):
176
+ return False
169
177
  raise RuntimeError("Downloaded catalog file is invalid or missing")
170
178
 
179
+ # skip data retrieval if only checking connection to oceans11
180
+ if kwargs.get("only_validate", False):
181
+ import shutil
182
+ shutil.rmtree(info["folder_hash"] + "/")
183
+ return True
184
+
171
185
  return local_path
172
186
 
173
187
  except Exception as e:
188
+ if kwargs.get("only_validate", False):
189
+ return False
174
190
  raise ConnectionError(f"Unable to access Oceans11 catalog: {e}") from e
175
191
 
176
192
  # ---------------------------------------------------
@@ -220,8 +220,8 @@ class DSI():
220
220
  n = OSTI()
221
221
  if n.validate_connection():
222
222
  print("OSTI : Read-only data catalog backend for discovering and querying OSTI (REST-based) open data resources.")
223
- n = Oceans11()
224
- if n.validate_connection():
223
+ n = Oceans11(only_validate=True)
224
+ if n.validate_connection(only_validate=True):
225
225
  print("Oceans11 : Read-only data catalog backend for discovering and querying Oceans11 (DSI-based) open data resources.")
226
226
  print()
227
227
 
@@ -12,6 +12,7 @@ from pathlib import Path
12
12
  from typing import Iterator
13
13
  from contextlib import redirect_stdout
14
14
  from collections import OrderedDict
15
+ from urllib.parse import urlparse
15
16
 
16
17
  from dsi.core import Terminal
17
18
  from dsi.utils.federated.federate_datasets import federate_datasets, pull_data
@@ -778,7 +779,7 @@ class Sync():
778
779
  raise ValueError(f"Cannot download data from '{db_name}' because it has not been indexed by DSI.")
779
780
  remote_loc = t2.get_table("federated")["remote_location"].iloc[0]
780
781
 
781
- with open(f"{db_data["workspace_folder"]}/host_usernames.json", "r", encoding="utf-8") as f:
782
+ with open(f'{db_data["workspace_folder"]}/host_usernames.json', "r", encoding="utf-8") as f:
782
783
  host_username = yaml.safe_load(f)
783
784
  username = (host_username or {}).get(db_data['location'], "")
784
785
 
@@ -787,13 +788,32 @@ class Sync():
787
788
 
788
789
  # add unique hash to download data
789
790
  workspace_folder = os.path.join(workspace_folder, db_data["folder_hash"])
790
-
791
- # Currently pulling all data referenced -- eventually allow user to download certain data
792
- db_info, username = pull_data(db_data["location_type"], db_data["location"], remote_loc,
793
- workspace_folder, username, internal_use=True)
794
- new_folder = Path(db_info.pop("new_db_folder"))
795
- if new_folder.is_dir() and not any(new_folder.iterdir()):
796
- new_folder.rmdir()
791
+
792
+ # if data files are URLs, then download them from filesystem, not using federated
793
+ def is_url(s):
794
+ try:
795
+ result = urlparse(s)
796
+ return all([result.scheme, result.netloc])
797
+ except Exception:
798
+ return False
799
+
800
+ if is_url(remote_loc):
801
+ remote_files = t2.get_table("filesystem")["file_remote"]
802
+ parent_url = os.path.commonprefix(remote_files.tolist())
803
+ for remote_url in remote_files:
804
+ # Downloading each file from fileystem
805
+ db_info, username = pull_data(db_data["location_type"], db_data["location"], remote_url,
806
+ workspace_folder, username, internal_use=True, parent_hash=parent_url)
807
+ new_folder = Path(db_info.pop("new_db_folder"))
808
+ if new_folder.is_dir() and not any(new_folder.iterdir()):
809
+ new_folder.rmdir()
810
+ else:
811
+ # Currently pulling all referenced data -- eventually allow user to download certain data
812
+ db_info, username = pull_data(db_data["location_type"], db_data["location"], remote_loc,
813
+ workspace_folder, username, internal_use=True)
814
+ new_folder = Path(db_info.pop("new_db_folder"))
815
+ if new_folder.is_dir() and not any(new_folder.iterdir()):
816
+ new_folder.rmdir()
797
817
 
798
818
 
799
819
  def gen_uuid(self, st):
@@ -79,7 +79,8 @@ def pull_data(location_type: str,
79
79
  abs_path_workspace_folder: str,
80
80
  username: str,
81
81
  download_limit: int = 10485760,
82
- internal_use = False) -> dict | tuple[dict | None, str]:
82
+ internal_use = False,
83
+ parent_hash: str = None) -> dict | tuple[dict | None, str]:
83
84
  """Pulls data from a specified location based on the location type (e.g., "github", "HPC", "HPC-Kerberos", "URL", "local").
84
85
  The function checks for existing files, compares them with remote versions using MD5 checksums, and downloads or skips files accordingly.
85
86
  It also handles user interactions for confirming downloads of large files and manages host usernames for HPC access.
@@ -100,8 +101,11 @@ def pull_data(location_type: str,
100
101
  filename = get_last_part(path)
101
102
 
102
103
  # Create folder for data
103
- abs_path_workspace_folder = str(Path(abs_path_workspace_folder).resolve())
104
- folder_hash, abs_path_db_folder = create_folder_from_path(location, abs_path_workspace_folder)
104
+ abs_path_workspace_folder = str(Path(abs_path_workspace_folder).resolve())
105
+ if parent_hash:
106
+ folder_hash, abs_path_db_folder = create_folder_from_path(parent_hash, abs_path_workspace_folder)
107
+ else:
108
+ folder_hash, abs_path_db_folder = create_folder_from_path(path, abs_path_workspace_folder)
105
109
 
106
110
  # Get the absolute path to the file to be downloaded
107
111
  file_path = Path(abs_path_db_folder) / filename
@@ -2,16 +2,18 @@ from pathlib import Path
2
2
  from urllib.parse import urlparse
3
3
  import getpass
4
4
  import os
5
-
6
- import boto3
7
- from botocore import UNSIGNED
8
- from botocore.config import Config
9
- from botocore.exceptions import (
10
- BotoCoreError,
11
- ClientError,
12
- NoCredentialsError,
13
- PartialCredentialsError,
14
- )
5
+ import importlib.util
6
+
7
+ if importlib.util.find_spec("duckdb") is not None:
8
+ import boto3
9
+ from botocore import UNSIGNED
10
+ from botocore.config import Config
11
+ from botocore.exceptions import (
12
+ BotoCoreError,
13
+ ClientError,
14
+ NoCredentialsError,
15
+ PartialCredentialsError,
16
+ )
15
17
 
16
18
 
17
19
  def get_s3_client(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dsi-workflow
3
- Version: 1.2.2
3
+ Version: 1.2.3
4
4
  Summary: A Data Science Infrastructure Project
5
5
  Author-email: Jesus Pulido <pulido@lanl.gov>, James Ahrens <ahrens@lanl.gov>, Divya Banesh <dbanesh@lanl.gov>, Hugh Greenberg <hng@lanl.gov>, Pascal Grosset <pascalgrosset@lanl.gov>, Vedant Iyer <iyer@lanl.gov>, Benjamin Sims <bsims@lanl.gov>, Terece Turton <tlturton@lanl.gov>
6
6
  License-Expression: BSD-3-Clause
@@ -1 +0,0 @@
1
- __version__ = "1.2.2"
File without changes
File without changes
File without changes
File without changes