dsi-workflow 1.2.7__tar.gz → 1.2.8__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.
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/PKG-INFO +1 -1
- dsi_workflow-1.2.8/dsi/_version.py +1 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/denodo.py +29 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/duckdb.py +4 -5
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/ndp.py +29 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/oceans11.py +29 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/osti.py +29 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/rcsbpdb.py +88 -57
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/sqlite.py +3 -4
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_oceans11.py +15 -13
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_osti.py +54 -41
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/webserver.py +4 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/zenodo.py +29 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/core.py +68 -65
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/dsi.py +72 -49
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/sync.py +29 -29
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/dsi_vcs.py +1 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/plots/plot-commit-diff.py +2 -2
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task2_dsivcs_tests.py +1 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task2_git_tests.py +2 -2
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/vcs_metadata_helper.py +1 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/PKG-INFO +1 -1
- dsi_workflow-1.2.7/dsi/_version.py +0 -1
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/README.rst +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/__init__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/backend.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/filesystem.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/gufi.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/hpss.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/sqlalchemy.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_denodo.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_duckdb.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_gufi.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_hpss.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_ndp.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_rcsbpdb.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_sqlalchemy.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_sqlite.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/backends/tests/test_zenodo.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/cli.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/dsi_scout.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/dsifederated.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/collection_reader.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/dashboard.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/env.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/file_reader.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/file_writer.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/metadata.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/ml_emulator.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/plugin.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/plugin_models.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/tests/test_collection_reader.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/tests/test_env.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/tests/test_file_reader.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/tests/test_file_writer.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/plugins/vtk_reader.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/tests/test_core.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/tests/test_dsi.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/__init__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/dsi_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/federated/__init__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/federated/catalog_walk.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/federated/federate_datasets.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/federated/source_entry.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/federation_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/git_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/hpc_kerberos.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/hpc_schema_crosswalk.json +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/rsync_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/s3_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/__init__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/__main__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/cli.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/plots/plot-add-commit.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/__init__.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/csv_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/db_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/json_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/npy_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/xlsx_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/content_chunking/xml_chunking.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/exceptions.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/file_store.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/frame_codec.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/log_record.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/merkle.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/repolog/repository_log.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task1_dsivcs_tests.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task1_git_tests.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task3_dsivcs_tests.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/task3_git_tests.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/tests/test_vcs.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/version_control/vcs_db.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/web_utils.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/webserver_crosswalk.json +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi/utils/webserver_query.py +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/SOURCES.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/dependency_links.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/entry_points.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/requires.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/dsi_workflow.egg-info/top_level.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/pyproject.toml +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/requirements.txt +0 -0
- {dsi_workflow-1.2.7 → dsi_workflow-1.2.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dsi-workflow
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
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.8"
|
|
@@ -1805,8 +1805,36 @@ class Denodo(Webserver):
|
|
|
1805
1805
|
|
|
1806
1806
|
|
|
1807
1807
|
# ----------------------------------------------------------------------
|
|
1808
|
-
# DSI Interface: Find
|
|
1808
|
+
# DSI Interface: Search/Find
|
|
1809
1809
|
# ----------------------------------------------------------------------
|
|
1810
|
+
def search(self, params, download=False):
|
|
1811
|
+
"""
|
|
1812
|
+
Retrieves metadata or data for entries in a specified dataset.
|
|
1813
|
+
|
|
1814
|
+
Parameters
|
|
1815
|
+
----------
|
|
1816
|
+
`params` : dict
|
|
1817
|
+
Identifies the dataset and, optionally, a specific entry.
|
|
1818
|
+
For example, {"database_id": 1} retrieves metadata for all entries
|
|
1819
|
+
in the dataset, while {"database_id": 1, "entry_id": 1} retrieves
|
|
1820
|
+
data for a specific entry (if supported).
|
|
1821
|
+
|
|
1822
|
+
`download` : bool, optional, default=False
|
|
1823
|
+
If True, downloads specified data to a local directory.
|
|
1824
|
+
If False, returns dataset's entry metadata when no entry is specified,
|
|
1825
|
+
or references to a specified entry's data for separate download.
|
|
1826
|
+
|
|
1827
|
+
Returns
|
|
1828
|
+
-------
|
|
1829
|
+
pandas.DataFrame or list of pandas.DataFrame
|
|
1830
|
+
Metadata for a dataset's entries or data references for a specified entry.
|
|
1831
|
+
Returns a list of DataFrames when the metadata spans multiple tables.
|
|
1832
|
+
|
|
1833
|
+
None
|
|
1834
|
+
If no metadata found or data directly downloaded with (download=True)
|
|
1835
|
+
"""
|
|
1836
|
+
raise NotImplementedError
|
|
1837
|
+
|
|
1810
1838
|
def find(self, query_object, **kwargs):
|
|
1811
1839
|
"""Search table names, column names and cell values."""
|
|
1812
1840
|
return (
|
|
@@ -358,15 +358,14 @@ class DuckDB(Filesystem):
|
|
|
358
358
|
self.cur.execute(create_query)
|
|
359
359
|
units_data = artifacts["dsi_units"]
|
|
360
360
|
for table_val, col_val, unit_val in zip(units_data["table_name"], units_data["column_name"], units_data["unit"]):
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
WHERE table_name = '{table_val}' AND column_name = '{col_val}';""").fetchone()
|
|
361
|
+
unit_result = self.cur.execute("""SELECT unit FROM dsi_units WHERE
|
|
362
|
+
table_name = ? AND column_name = ?;""", [table_val, col_val]).fetchone()
|
|
364
363
|
if unit_result and unit_result[0] != unit_val: #checks if unit for same table and col exists in db and if units match
|
|
365
364
|
self.cur.execute("ROLLBACK")
|
|
366
365
|
raise TypeError(f"Cannot ingest different units for the column {col_val} in {table_val}")
|
|
367
366
|
elif not unit_result:
|
|
368
367
|
try:
|
|
369
|
-
self.cur.execute(
|
|
368
|
+
self.cur.execute("INSERT INTO dsi_units VALUES (?, ?, ?)", [table_val, col_val, unit_val])
|
|
370
369
|
except duckdb.Error as e:
|
|
371
370
|
self.cur.execute("ROLLBACK")
|
|
372
371
|
self.cur.execute("CHECKPOINT")
|
|
@@ -1003,7 +1002,7 @@ class DuckDB(Filesystem):
|
|
|
1003
1002
|
AVG("{col_name}"),
|
|
1004
1003
|
STDDEV_SAMP("{col_name}")
|
|
1005
1004
|
FROM {table_name}
|
|
1006
|
-
WHERE "{col_name}"
|
|
1005
|
+
WHERE isfinite("{col_name}")
|
|
1007
1006
|
""").fetchone()
|
|
1008
1007
|
else:
|
|
1009
1008
|
min_val = max_val = avg_val = std_dev = None
|
|
@@ -1059,8 +1059,36 @@ class NDP(Webserver):
|
|
|
1059
1059
|
|
|
1060
1060
|
|
|
1061
1061
|
# ----------------------------------------------------------------------
|
|
1062
|
-
# Find Methods
|
|
1062
|
+
# Search/Find Methods
|
|
1063
1063
|
# ----------------------------------------------------------------------
|
|
1064
|
+
def search(self, params, download=False):
|
|
1065
|
+
"""
|
|
1066
|
+
Retrieves metadata or data for entries in a specified dataset.
|
|
1067
|
+
|
|
1068
|
+
Parameters
|
|
1069
|
+
----------
|
|
1070
|
+
`params` : dict
|
|
1071
|
+
Identifies the dataset and, optionally, a specific entry.
|
|
1072
|
+
For example, {"database_id": 1} retrieves metadata for all entries
|
|
1073
|
+
in the dataset, while {"database_id": 1, "entry_id": 1} retrieves
|
|
1074
|
+
data for a specific entry (if supported).
|
|
1075
|
+
|
|
1076
|
+
`download` : bool, optional, default=False
|
|
1077
|
+
If True, downloads specified data to a local directory.
|
|
1078
|
+
If False, returns dataset's entry metadata when no entry is specified,
|
|
1079
|
+
or references to a specified entry's data for separate download.
|
|
1080
|
+
|
|
1081
|
+
Returns
|
|
1082
|
+
-------
|
|
1083
|
+
pandas.DataFrame or list of pandas.DataFrame
|
|
1084
|
+
Metadata for a dataset's entries or data references for a specified entry.
|
|
1085
|
+
Returns a list of DataFrames when the metadata spans multiple tables.
|
|
1086
|
+
|
|
1087
|
+
None
|
|
1088
|
+
If no metadata found or data directly downloaded with (download=True)
|
|
1089
|
+
"""
|
|
1090
|
+
raise NotImplementedError
|
|
1091
|
+
|
|
1064
1092
|
def find(self, query_object, **kwargs):
|
|
1065
1093
|
"""
|
|
1066
1094
|
Searches for all instances of query_object across all tables.
|
|
@@ -794,8 +794,36 @@ class Oceans11(Webserver):
|
|
|
794
794
|
return self._cache
|
|
795
795
|
|
|
796
796
|
# ------------------------------------------------------------------
|
|
797
|
-
# Find Methods
|
|
797
|
+
# Search/Find Methods
|
|
798
798
|
# ------------------------------------------------------------------
|
|
799
|
+
def search(self, params, download=False):
|
|
800
|
+
"""
|
|
801
|
+
Retrieves metadata or data for entries in a specified dataset.
|
|
802
|
+
|
|
803
|
+
Parameters
|
|
804
|
+
----------
|
|
805
|
+
`params` : dict
|
|
806
|
+
Identifies the dataset and, optionally, a specific entry.
|
|
807
|
+
For example, {"database_id": 1} retrieves metadata for all entries
|
|
808
|
+
in the dataset, while {"database_id": 1, "entry_id": 1} retrieves
|
|
809
|
+
data for a specific entry (if supported).
|
|
810
|
+
|
|
811
|
+
`download` : bool, optional, default=False
|
|
812
|
+
If True, downloads specified data to a local directory.
|
|
813
|
+
If False, returns dataset's entry metadata when no entry is specified,
|
|
814
|
+
or references to a specified entry's data for separate download.
|
|
815
|
+
|
|
816
|
+
Returns
|
|
817
|
+
-------
|
|
818
|
+
pandas.DataFrame or list of pandas.DataFrame
|
|
819
|
+
Metadata for a dataset's entries or data references for a specified entry.
|
|
820
|
+
Returns a list of DataFrames when the metadata spans multiple tables.
|
|
821
|
+
|
|
822
|
+
None
|
|
823
|
+
If no metadata found or data directly downloaded with (download=True)
|
|
824
|
+
"""
|
|
825
|
+
raise NotImplementedError
|
|
826
|
+
|
|
799
827
|
def find(self, query_object, **kwargs):
|
|
800
828
|
"""Search for a value across table, column, and cell levels."""
|
|
801
829
|
if not self._loaded:
|
|
@@ -713,8 +713,36 @@ class OSTI(Webserver):
|
|
|
713
713
|
)
|
|
714
714
|
|
|
715
715
|
# ----------------------------------------------------------------------
|
|
716
|
-
# Find Methods
|
|
716
|
+
# Search/Find Methods
|
|
717
717
|
# ----------------------------------------------------------------------
|
|
718
|
+
def search(self, params, download=False):
|
|
719
|
+
"""
|
|
720
|
+
Retrieves metadata or data for entries in a specified dataset.
|
|
721
|
+
|
|
722
|
+
Parameters
|
|
723
|
+
----------
|
|
724
|
+
`params` : dict
|
|
725
|
+
Identifies the dataset and, optionally, a specific entry.
|
|
726
|
+
For example, {"database_id": 1} retrieves metadata for all entries
|
|
727
|
+
in the dataset, while {"database_id": 1, "entry_id": 1} retrieves
|
|
728
|
+
data for a specific entry (if supported).
|
|
729
|
+
|
|
730
|
+
`download` : bool, optional, default=False
|
|
731
|
+
If True, downloads specified data to a local directory.
|
|
732
|
+
If False, returns dataset's entry metadata when no entry is specified,
|
|
733
|
+
or references to a specified entry's data for separate download.
|
|
734
|
+
|
|
735
|
+
Returns
|
|
736
|
+
-------
|
|
737
|
+
pandas.DataFrame or list of pandas.DataFrame
|
|
738
|
+
Metadata for a dataset's entries or data references for a specified entry.
|
|
739
|
+
Returns a list of DataFrames when the metadata spans multiple tables.
|
|
740
|
+
|
|
741
|
+
None
|
|
742
|
+
If no metadata found or data directly downloaded with (download=True)
|
|
743
|
+
"""
|
|
744
|
+
raise NotImplementedError
|
|
745
|
+
|
|
718
746
|
def find(self, query_object, **kwargs):
|
|
719
747
|
"""
|
|
720
748
|
Searches for all instances of `query_object` across the table, column, and cell levels.
|
|
@@ -3,65 +3,68 @@ RCSBPDB Webserver Backend for DSI
|
|
|
3
3
|
|
|
4
4
|
Read-only metadata-first backend that retrieves rcsb pdb metadata
|
|
5
5
|
and exposes it as in-memory DSI tables.
|
|
6
|
-
"""
|
|
7
|
-
# Access modes
|
|
8
|
-
# ------------
|
|
9
|
-
# 1. Identifier-driven mode
|
|
10
|
-
# - DOI input, e.g. "10.2210/pdb1cbs/pdb"
|
|
11
|
-
# - PDB ID input, e.g. "1CBS"
|
|
12
|
-
|
|
13
|
-
# 2. Query-driven mode, closer to NDP
|
|
14
|
-
# - params={"keywords": "hemoglobin", "limit": 5}
|
|
15
|
-
# - find_relation({"keywords": "hemoglobin", "limit": 5})
|
|
16
|
-
# - find_relation("hemoglobin")
|
|
17
|
-
|
|
18
|
-
# DOI behavior
|
|
19
|
-
# ------------
|
|
20
|
-
# RCSB-style DOI input is supported through identifiers or params.
|
|
21
|
-
# Only DOIs of the form 10.2210/pdbXXXX/pdb are converted directly into PDB IDs.
|
|
22
|
-
# General publication DOI search is not currently supported.
|
|
23
|
-
|
|
24
|
-
# REST flow
|
|
25
|
-
# ---------
|
|
26
|
-
# RCSB Search API -> PDB IDs -> RCSB Data API -> normalized DSI tables
|
|
27
|
-
|
|
28
|
-
# Tables
|
|
29
|
-
# ------
|
|
30
|
-
# - datasets
|
|
31
|
-
# - resources
|
|
32
|
-
# - errors
|
|
33
|
-
|
|
34
|
-
# Tier mapping
|
|
35
|
-
# ------------
|
|
36
|
-
# self.tables["datasets"] = Tier 1 datasets
|
|
37
|
-
# self.tables["resources"] = Tier 2 normalized resources
|
|
38
|
-
# self.tables["errors"] = failed/skipped lookups
|
|
39
|
-
|
|
40
|
-
# Current scope
|
|
41
|
-
# -------------
|
|
42
|
-
# - Metadata-first
|
|
43
|
-
# - Read-only
|
|
44
|
-
# - REST APIs only
|
|
45
|
-
# - Exposes mmCIF download URLs
|
|
46
|
-
# - Does not parse raw mmCIF content yet
|
|
47
|
-
|
|
48
|
-
# identifiers
|
|
49
|
-
# → __init__()
|
|
50
|
-
# → _load_initial_data()
|
|
51
|
-
# → lookup_identifier()
|
|
52
|
-
# → lookup_rcsbpdb()
|
|
53
|
-
# → _request()
|
|
54
|
-
# → GET https://data.rcsb.org/rest/v1/core/entry/{pdb_id}
|
|
55
|
-
|
|
56
|
-
# params
|
|
57
|
-
# → __init__()
|
|
58
|
-
# → _load_from_params()
|
|
59
|
-
# → _search_rcsb()
|
|
60
|
-
# → _build_search_query()
|
|
61
|
-
# → _post_json()
|
|
62
|
-
# → POST https://search.rcsb.org/rcsbsearch/v2/query
|
|
63
6
|
|
|
64
7
|
|
|
8
|
+
Access modes
|
|
9
|
+
------------
|
|
10
|
+
1. Identifier-driven mode
|
|
11
|
+
- DOI input, e.g. "10.2210/pdb1cbs/pdb"
|
|
12
|
+
- PDB ID input, e.g. "1CBS"
|
|
13
|
+
|
|
14
|
+
2. Query-driven mode, closer to NDP
|
|
15
|
+
- params={"keywords": "hemoglobin", "limit": 5}
|
|
16
|
+
- find_relation({"keywords": "hemoglobin", "limit": 5})
|
|
17
|
+
- find_relation("hemoglobin")
|
|
18
|
+
|
|
19
|
+
DOI behavior
|
|
20
|
+
------------
|
|
21
|
+
RCSB-style DOI input is supported through identifiers or params.
|
|
22
|
+
Only DOIs of the form 10.2210/pdbXXXX/pdb are converted directly into PDB IDs.
|
|
23
|
+
General publication DOI search is not currently supported.
|
|
24
|
+
|
|
25
|
+
REST flow
|
|
26
|
+
---------
|
|
27
|
+
RCSB Search API -> PDB IDs -> RCSB Data API -> normalized DSI tables
|
|
28
|
+
|
|
29
|
+
Tables
|
|
30
|
+
------
|
|
31
|
+
- datasets
|
|
32
|
+
- resources
|
|
33
|
+
- errors
|
|
34
|
+
|
|
35
|
+
Tier mapping
|
|
36
|
+
------------
|
|
37
|
+
self.tables["datasets"] = Tier 1 datasets
|
|
38
|
+
self.tables["resources"] = Tier 2 normalized resources
|
|
39
|
+
self.tables["errors"] = failed/skipped lookups
|
|
40
|
+
|
|
41
|
+
Current scope
|
|
42
|
+
-------------
|
|
43
|
+
- Metadata-first
|
|
44
|
+
- Read-only
|
|
45
|
+
- REST APIs only
|
|
46
|
+
- Exposes mmCIF download URLs
|
|
47
|
+
- Does not parse raw mmCIF content yet
|
|
48
|
+
|
|
49
|
+
**identifiers**
|
|
50
|
+
|
|
51
|
+
- __init__()
|
|
52
|
+
- _load_initial_data()
|
|
53
|
+
- lookup_identifier()
|
|
54
|
+
- lookup_rcsbpdb()
|
|
55
|
+
- _request()
|
|
56
|
+
- GET https://data.rcsb.org/rest/v1/core/entry/{pdb_id}
|
|
57
|
+
|
|
58
|
+
**params**
|
|
59
|
+
|
|
60
|
+
- __init__()
|
|
61
|
+
- _load_from_params()
|
|
62
|
+
- _search_rcsb()
|
|
63
|
+
- _build_search_query()
|
|
64
|
+
- _post_json()
|
|
65
|
+
- POST https://search.rcsb.org/rcsbsearch/v2/query
|
|
66
|
+
"""
|
|
67
|
+
|
|
65
68
|
from __future__ import annotations
|
|
66
69
|
|
|
67
70
|
import builtins
|
|
@@ -1354,6 +1357,34 @@ class RCSBPDB(Webserver):
|
|
|
1354
1357
|
self._loaded = True
|
|
1355
1358
|
return self.tables
|
|
1356
1359
|
|
|
1360
|
+
def search(self, params, download=False):
|
|
1361
|
+
"""
|
|
1362
|
+
Retrieves metadata or data for entries in a specified dataset.
|
|
1363
|
+
|
|
1364
|
+
Parameters
|
|
1365
|
+
----------
|
|
1366
|
+
`params` : dict
|
|
1367
|
+
Identifies the dataset and, optionally, a specific entry.
|
|
1368
|
+
For example, {"database_id": 1} retrieves metadata for all entries
|
|
1369
|
+
in the dataset, while {"database_id": 1, "entry_id": 1} retrieves
|
|
1370
|
+
data for a specific entry (if supported).
|
|
1371
|
+
|
|
1372
|
+
`download` : bool, optional, default=False
|
|
1373
|
+
If True, downloads specified data to a local directory.
|
|
1374
|
+
If False, returns dataset's entry metadata when no entry is specified,
|
|
1375
|
+
or references to a specified entry's data for separate download.
|
|
1376
|
+
|
|
1377
|
+
Returns
|
|
1378
|
+
-------
|
|
1379
|
+
pandas.DataFrame or list of pandas.DataFrame
|
|
1380
|
+
Metadata for a dataset's entries or data references for a specified entry.
|
|
1381
|
+
Returns a list of DataFrames when the metadata spans multiple tables.
|
|
1382
|
+
|
|
1383
|
+
None
|
|
1384
|
+
If no metadata found or data directly downloaded with (download=True)
|
|
1385
|
+
"""
|
|
1386
|
+
raise NotImplementedError
|
|
1387
|
+
|
|
1357
1388
|
def find(self, query_object, **kwargs):
|
|
1358
1389
|
"""
|
|
1359
1390
|
Searches for all instances of query_object across all loaded tables.
|
|
@@ -323,15 +323,14 @@ class Sqlite(Filesystem):
|
|
|
323
323
|
self.cur.execute(create_query)
|
|
324
324
|
units_data = artifacts["dsi_units"]
|
|
325
325
|
for table_val, col_val, unit_val in zip(units_data["table_name"], units_data["column_name"], units_data["unit"]):
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
WHERE table_name = '{table_val}' AND column_name = '{col_val}';""").fetchone()
|
|
326
|
+
unit_result = self.cur.execute("""SELECT unit FROM dsi_units WHERE
|
|
327
|
+
table_name = ? AND column_name = ?;""", [table_val, col_val]).fetchone()
|
|
329
328
|
if unit_result and unit_result[0] != unit_val: #checks if unit for same table and col exists in db and if units match
|
|
330
329
|
self.con.rollback()
|
|
331
330
|
raise TypeError(f"Cannot ingest different units for the column {col_val} in {table_val}")
|
|
332
331
|
elif not unit_result:
|
|
333
332
|
try:
|
|
334
|
-
self.cur.execute(
|
|
333
|
+
self.cur.execute("INSERT INTO dsi_units VALUES (?, ?, ?)", [table_val, col_val, unit_val])
|
|
335
334
|
except sqlite3.Error as e:
|
|
336
335
|
self.con.rollback()
|
|
337
336
|
raise sqlite3.Error(e)
|
|
@@ -33,25 +33,27 @@ TEST_OSTI_ID = "3022783"
|
|
|
33
33
|
# =============================================================================
|
|
34
34
|
# Fixtures
|
|
35
35
|
# =============================================================================
|
|
36
|
-
|
|
37
36
|
@pytest.fixture(scope="session")
|
|
38
37
|
def backend(tmp_path_factory):
|
|
39
38
|
"""Create one live Oceans11 backend for the entire test session."""
|
|
40
39
|
workspace = tmp_path_factory.mktemp("oceans11")
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if instance._loaded:
|
|
53
|
-
instance.close()
|
|
41
|
+
try:
|
|
42
|
+
instance = Oceans11(
|
|
43
|
+
params=[
|
|
44
|
+
{"osti_id": TEST_OSTI_ID, "rows": 1},
|
|
45
|
+
{"osti_id": TEST_OSTI_ID, "rows": 1},
|
|
46
|
+
],
|
|
47
|
+
workspace=str(workspace),
|
|
48
|
+
)
|
|
49
|
+
except ConnectionError as e:
|
|
50
|
+
pytest.skip(f"Oceans11 is unavailable: {e}")
|
|
54
51
|
|
|
52
|
+
try:
|
|
53
|
+
yield instance
|
|
54
|
+
finally:
|
|
55
|
+
if instance._loaded:
|
|
56
|
+
instance.close()
|
|
55
57
|
|
|
56
58
|
@pytest.fixture(scope="session")
|
|
57
59
|
def record(backend):
|