dsi-workflow 1.2.2__tar.gz → 1.2.4__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 (69) hide show
  1. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/PKG-INFO +2 -2
  2. dsi_workflow-1.2.4/dsi/_version.py +1 -0
  3. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/backend.py +0 -8
  4. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/duckdb.py +36 -18
  5. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/filesystem.py +0 -8
  6. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/gufi.py +2 -4
  7. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/hpss.py +2 -2
  8. dsi_workflow-1.2.4/dsi/backends/ndp.py +1637 -0
  9. dsi_workflow-1.2.4/dsi/backends/oceans11.py +1336 -0
  10. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/osti.py +469 -111
  11. dsi_workflow-1.2.4/dsi/backends/rcsbpdb.py +1717 -0
  12. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/sqlalchemy.py +0 -3
  13. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/sqlite.py +32 -14
  14. dsi_workflow-1.2.4/dsi/backends/tests/test_ndp.py +352 -0
  15. dsi_workflow-1.2.4/dsi/backends/tests/test_oceans11.py +668 -0
  16. dsi_workflow-1.2.4/dsi/backends/tests/test_osti.py +403 -0
  17. dsi_workflow-1.2.4/dsi/backends/tests/test_rcsbpdb.py +914 -0
  18. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/tests/test_sqlalchemy.py +1 -1
  19. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/webserver.py +0 -8
  20. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/cli.py +0 -1
  21. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/core.py +224 -163
  22. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/dsi.py +63 -29
  23. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/dashboard.py +4 -4
  24. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/env.py +2 -4
  25. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/file_reader.py +4 -5
  26. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/file_writer.py +2 -3
  27. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/tests/test_env.py +1 -1
  28. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/tests/test_file_reader.py +7 -8
  29. dsi_workflow-1.2.4/dsi/plugins/vtk_reader.py +345 -0
  30. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/sync.py +109 -69
  31. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/tests/test_core.py +172 -378
  32. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/tests/test_dsi.py +207 -33
  33. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/dsi_utils.py +2 -2
  34. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/federated/federate_datasets.py +7 -3
  35. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/s3_utils.py +19 -10
  36. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/PKG-INFO +2 -2
  37. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/SOURCES.txt +5 -0
  38. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/requires.txt +1 -1
  39. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/requirements.txt +1 -1
  40. dsi_workflow-1.2.2/dsi/_version.py +0 -1
  41. dsi_workflow-1.2.2/dsi/backends/ndp.py +0 -1001
  42. dsi_workflow-1.2.2/dsi/backends/oceans11.py +0 -1277
  43. dsi_workflow-1.2.2/dsi/backends/tests/test_ndp.py +0 -495
  44. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/README.rst +0 -0
  45. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/__init__.py +0 -0
  46. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/tests/test_duckdb.py +0 -0
  47. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/tests/test_gufi.py +0 -0
  48. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/tests/test_hpss.py +0 -0
  49. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/backends/tests/test_sqlite.py +0 -0
  50. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/dsifederated.py +0 -0
  51. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/collection_reader.py +0 -0
  52. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/metadata.py +0 -0
  53. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/ml_emulator.py +0 -0
  54. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/plugin.py +0 -0
  55. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/plugin_models.py +0 -0
  56. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/tests/test_collection_reader.py +0 -0
  57. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/plugins/tests/test_file_writer.py +0 -0
  58. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/__init__.py +0 -0
  59. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/federated/__init__.py +0 -0
  60. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/federation_utils.py +0 -0
  61. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/git_utils.py +0 -0
  62. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/hpc_kerberos.py +0 -0
  63. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/rsync_utils.py +0 -0
  64. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi/utils/web_utils.py +0 -0
  65. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/dependency_links.txt +0 -0
  66. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/entry_points.txt +0 -0
  67. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/dsi_workflow.egg-info/top_level.txt +0 -0
  68. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/pyproject.toml +0 -0
  69. {dsi_workflow-1.2.2 → dsi_workflow-1.2.4}/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.4
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
@@ -12,7 +12,7 @@ Requires-Dist: pydantic>=2.1.1
12
12
  Requires-Dist: nbconvert>=7.13.0
13
13
  Requires-Dist: matplotlib>=3.6.0
14
14
  Requires-Dist: pyyaml>=6.0
15
- Requires-Dist: requests>=2.31.0
15
+ Requires-Dist: requests>=2.32.0
16
16
  Requires-Dist: pyreadline3; platform_system == "Windows"
17
17
 
18
18
  ===============
@@ -0,0 +1 @@
1
+ __version__ = "1.2.4"
@@ -18,14 +18,6 @@ class Backend(ABC):
18
18
  def get_table(self, table_name, **kwargs):
19
19
  pass
20
20
 
21
- @abstractmethod
22
- def get_table_names(self,query):
23
- pass
24
-
25
- @abstractmethod
26
- def notebook(self, **kwargs):
27
- pass
28
-
29
21
  @abstractmethod
30
22
  def process_artifacts(self, **kwargs):
31
23
  pass
@@ -329,8 +329,8 @@ class DuckDB(Filesystem):
329
329
 
330
330
  self.ingest_table_helper(types, foreign_query)
331
331
 
332
- # TODO: move this check to schema reader by allowing users to just create table without data
333
- if not all(v == [""] for v in tableData.values()): # if table is just one row of empty strings, don't insert
332
+ # skip insert if table is empty
333
+ if not all(v in ([], [""], [None]) for v in tableData.values()):
334
334
  col_names = ', '.join(types.properties.keys())
335
335
  placeholders = ', '.join('?' * len(types.properties))
336
336
 
@@ -438,16 +438,19 @@ class DuckDB(Filesystem):
438
438
  raise
439
439
  else:
440
440
  raise RuntimeError("Can only run SELECT, PRAGMA, UPDATE, or ALTER queries on the data")
441
-
441
+
442
+ primary_table = self.get_sql_query_table_name(query)
443
+ if primary_table is None:
444
+ raise ValueError("Query must reference at least one table")
445
+
442
446
  if dict_return:
443
- tables = self.get_table_names(query)
444
- if len(tables) > 1:
445
- raise RuntimeError("Can only return ordered dictionary if querying one table")
446
-
447
447
  return OrderedDict(data.to_dict(orient='list'))
448
448
  else:
449
+ data.attrs["table_name"] = primary_table
449
450
  return data
450
-
451
+
452
+
453
+
451
454
  def get_table(self, table_name, dict_return = False):
452
455
  """
453
456
  Retrieves all data from a specified table without requiring knowledge of SQL.
@@ -466,8 +469,10 @@ class DuckDB(Filesystem):
466
469
  - If `dict_return` is True: returns an OrderedDict
467
470
  """
468
471
  return self.query_artifacts(query=f"SELECT * FROM {table_name}", dict_return=dict_return)
469
-
470
- def get_table_names(self, query):
472
+
473
+
474
+
475
+ def get_sql_query_table_name(self, query):
471
476
  """
472
477
  Extracts all table names from a SQL query. Helper function for `query_artifacts()` that users do not need to call
473
478
 
@@ -477,10 +482,20 @@ class DuckDB(Filesystem):
477
482
  Return: list of str
478
483
  List of table names referenced in the query.
479
484
  """
480
- all_names = re.findall(r'FROM\s+["\']?([\w\-]+)["\']?|JOIN\s+["\']?([\w\-]+)["\']?', query, re.IGNORECASE)
481
- tables = [table for from_tbl, join_tbl in all_names if (table := from_tbl or join_tbl)]
482
- return tables
483
-
485
+ try:
486
+ from sqlglot import parse_one, exp
487
+ tree = parse_one(query, dialect="duckdb")
488
+ cte_names = {cte.alias_or_name for cte in tree.find_all(exp.CTE)}
489
+ query_tables = [table.name for table in tree.find_all(exp.Table) if table.name not in cte_names]
490
+
491
+ except ModuleNotFoundError:
492
+ all_names = re.findall(r'FROM\s+["\']?([\w\-]+)["\']?|JOIN\s+["\']?([\w\-]+)["\']?', query, re.IGNORECASE)
493
+ query_tables = [table for from_tbl, join_tbl in all_names if (table := from_tbl or join_tbl)]
494
+
495
+ return query_tables[0] if query_tables else None
496
+
497
+
498
+
484
499
  def get_schema(self):
485
500
  """
486
501
  Returns the structural schema of this database in the form of CREATE TABLE statements.
@@ -490,12 +505,15 @@ class DuckDB(Filesystem):
490
505
  """
491
506
  schema_stmts = self.query_artifacts(query="SELECT sql FROM duckdb_tables where sql NOT NULL ")
492
507
  return schema_stmts["sql"].str.cat(sep="\n")
493
-
494
-
508
+
509
+
510
+
495
511
  def notebook(self, interactive=False):
496
- pass
512
+ """Notebook generation is not supported for DuckDB backend"""
513
+ raise NotImplementedError("Notebook generation not supported for DuckDB backend")
514
+
515
+
497
516
 
498
-
499
517
  def process_artifacts(self, only_units_relations = False):
500
518
  """
501
519
  Reads data from the DuckDB database into a nested OrderedDict.
@@ -19,14 +19,6 @@ class Filesystem(Backend, ABC):
19
19
  def get_table(self, table_name, **kwargs):
20
20
  pass
21
21
 
22
- @abstractmethod
23
- def get_table_names(self,query):
24
- pass
25
-
26
- @abstractmethod
27
- def notebook(self, **kwargs):
28
- pass
29
-
30
22
  @abstractmethod
31
23
  def process_artifacts(self, **kwargs):
32
24
  pass
@@ -91,8 +91,8 @@ class Gufi(Filesystem):
91
91
  con.enable_load_extension(False)
92
92
 
93
93
  dsi_column_names = ",".join(self.dsi_columns)
94
- gufi_column_names = ",".join((["rpath(sname, sroll, name) AS fullpath"] + self.gufi_columns[1:]
95
- if self.gufi_columns[0] == "fullpath" else self.gufi_columns))
94
+ gufi_column_names = ",".join(["rpath(sname, sroll, name) AS fullpath"] + self.gufi_columns[1:]
95
+ if self.gufi_columns[0] == "fullpath" else self.gufi_columns)
96
96
  query=f"""
97
97
  CREATE VIRTUAL TABLE uview USING gufi_vt(
98
98
  threads=64,
@@ -144,8 +144,6 @@ class Gufi(Filesystem):
144
144
  pass
145
145
  def get_table(self):
146
146
  raise NotImplementedError("Cannot get table data with the GUFI backend")
147
- def get_table_names(self):
148
- raise NotImplementedError("Cannot get table names with the GUFI backend")
149
147
  def list(self):
150
148
  raise NotImplementedError("Cannot list tables with the GUFI backend")
151
149
  def notebook(self):
@@ -50,7 +50,7 @@ class HPSS(Backend):
50
50
  os.chdir(new_dir)
51
51
  file_to_put = local_file.split('/')[-1]
52
52
 
53
- stdout, stderr, returncode = self.run_hsi("put", [file_to_put])
53
+ _, _, returncode = self.run_hsi("put", [file_to_put])
54
54
  if new_dir is not None:
55
55
  os.chdir(cwd)
56
56
 
@@ -71,7 +71,7 @@ class HPSS(Backend):
71
71
  print("Error changing to temp dir: %s" % tmp_dir)
72
72
  return False
73
73
 
74
- stdout, stderr, returncode = self.run_hsi("get", hpss_file)
74
+ _, _, returncode = self.run_hsi("get", hpss_file)
75
75
  try:
76
76
  os.chdir(cwd)
77
77
  except Exception: