napistu 0.1.0__py3-none-any.whl → 0.2.4.dev2__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.
Files changed (59) hide show
  1. napistu/__init__.py +1 -1
  2. napistu/consensus.py +1010 -513
  3. napistu/constants.py +24 -0
  4. napistu/gcs/constants.py +2 -2
  5. napistu/gcs/downloads.py +57 -25
  6. napistu/gcs/utils.py +21 -0
  7. napistu/identifiers.py +105 -6
  8. napistu/ingestion/constants.py +0 -1
  9. napistu/ingestion/obo.py +24 -8
  10. napistu/ingestion/psi_mi.py +20 -5
  11. napistu/ingestion/reactome.py +8 -32
  12. napistu/mcp/__init__.py +69 -0
  13. napistu/mcp/__main__.py +180 -0
  14. napistu/mcp/codebase.py +182 -0
  15. napistu/mcp/codebase_utils.py +298 -0
  16. napistu/mcp/constants.py +72 -0
  17. napistu/mcp/documentation.py +166 -0
  18. napistu/mcp/documentation_utils.py +235 -0
  19. napistu/mcp/execution.py +382 -0
  20. napistu/mcp/profiles.py +73 -0
  21. napistu/mcp/server.py +86 -0
  22. napistu/mcp/tutorials.py +124 -0
  23. napistu/mcp/tutorials_utils.py +230 -0
  24. napistu/mcp/utils.py +47 -0
  25. napistu/mechanism_matching.py +782 -26
  26. napistu/modify/constants.py +41 -0
  27. napistu/modify/curation.py +4 -1
  28. napistu/modify/gaps.py +243 -156
  29. napistu/modify/pathwayannot.py +26 -8
  30. napistu/network/neighborhoods.py +16 -7
  31. napistu/network/net_create.py +209 -54
  32. napistu/network/net_propagation.py +118 -0
  33. napistu/network/net_utils.py +1 -32
  34. napistu/rpy2/netcontextr.py +10 -7
  35. napistu/rpy2/rids.py +7 -5
  36. napistu/sbml_dfs_core.py +46 -29
  37. napistu/sbml_dfs_utils.py +37 -1
  38. napistu/source.py +8 -2
  39. napistu/utils.py +67 -8
  40. napistu-0.2.4.dev2.dist-info/METADATA +84 -0
  41. napistu-0.2.4.dev2.dist-info/RECORD +95 -0
  42. {napistu-0.1.0.dist-info → napistu-0.2.4.dev2.dist-info}/WHEEL +1 -1
  43. tests/conftest.py +11 -5
  44. tests/test_consensus.py +4 -1
  45. tests/test_gaps.py +127 -0
  46. tests/test_gcs.py +3 -2
  47. tests/test_igraph.py +14 -0
  48. tests/test_mcp_documentation_utils.py +13 -0
  49. tests/test_mechanism_matching.py +658 -0
  50. tests/test_net_propagation.py +89 -0
  51. tests/test_net_utils.py +83 -0
  52. tests/test_sbml.py +2 -0
  53. tests/{test_sbml_dfs_create.py → test_sbml_dfs_core.py} +68 -4
  54. tests/test_utils.py +81 -0
  55. napistu-0.1.0.dist-info/METADATA +0 -56
  56. napistu-0.1.0.dist-info/RECORD +0 -77
  57. {napistu-0.1.0.dist-info → napistu-0.2.4.dev2.dist-info}/entry_points.txt +0 -0
  58. {napistu-0.1.0.dist-info → napistu-0.2.4.dev2.dist-info}/licenses/LICENSE +0 -0
  59. {napistu-0.1.0.dist-info → napistu-0.2.4.dev2.dist-info}/top_level.txt +0 -0
tests/conftest.py CHANGED
@@ -61,23 +61,29 @@ def sbml_dfs_glucose_metabolism():
61
61
  def pytest_configure(config):
62
62
  config.addinivalue_line("markers", "skip_on_windows: mark test to skip on Windows")
63
63
  config.addinivalue_line("markers", "skip_on_macos: mark test to skip on macOS")
64
- config.addinivalue_line("markers", "unix_only: mark test to run only on Unix/Linux systems")
64
+ config.addinivalue_line(
65
+ "markers", "unix_only: mark test to run only on Unix/Linux systems"
66
+ )
67
+
65
68
 
66
69
  # Define platform conditions
67
70
  is_windows = sys.platform == "win32"
68
71
  is_macos = sys.platform == "darwin"
69
72
  is_unix = not (is_windows or is_macos)
70
73
 
74
+
71
75
  # Apply skipping based on platform
72
76
  def pytest_runtest_setup(item):
73
77
  # Skip tests marked to be skipped on Windows
74
- if is_windows and any(mark.name == "skip_on_windows" for mark in item.iter_markers()):
78
+ if is_windows and any(
79
+ mark.name == "skip_on_windows" for mark in item.iter_markers()
80
+ ):
75
81
  skip("Test skipped on Windows")
76
-
82
+
77
83
  # Skip tests marked to be skipped on macOS
78
84
  if is_macos and any(mark.name == "skip_on_macos" for mark in item.iter_markers()):
79
85
  skip("Test skipped on macOS")
80
-
86
+
81
87
  # Skip tests that should run only on Unix
82
88
  if not is_unix and any(mark.name == "unix_only" for mark in item.iter_markers()):
83
- skip("Test runs only on Unix systems")
89
+ skip("Test runs only on Unix systems")
tests/test_consensus.py CHANGED
@@ -140,6 +140,7 @@ def test_source_tracking():
140
140
 
141
141
 
142
142
  def test_passing_entity_data():
143
+
143
144
  pw_index = indices.PWIndex(os.path.join(test_data, "pw_index.tsv"))
144
145
  sbml_dfs_dict = consensus.construct_sbml_dfs_dict(pw_index)
145
146
 
@@ -187,7 +188,9 @@ def test_passing_entity_data():
187
188
  # in different models has a different value for its reactions_data
188
189
  minimal_pw_index = pw_index
189
190
  minimal_pw_index.index = minimal_pw_index.index.iloc[0:2]
190
- minimal_pw_index.index["file"].loc[1] = minimal_pw_index.index["file"][0]
191
+
192
+ # Since we're working with a DataFrame, we can use loc to update the file value directly
193
+ minimal_pw_index.index.loc[1, "file"] = minimal_pw_index.index.loc[0, "file"]
191
194
 
192
195
  duplicated_sbml_dfs_dict = consensus.construct_sbml_dfs_dict(minimal_pw_index)
193
196
  # explicitely define the order we'll loop through models so that
tests/test_gaps.py ADDED
@@ -0,0 +1,127 @@
1
+ import pandas as pd
2
+ import numpy as np
3
+ import warnings
4
+
5
+ from napistu.sbml_dfs_core import SBML_dfs
6
+ from napistu.constants import SBML_DFS
7
+ from napistu.constants import MINI_SBO_FROM_NAME
8
+ from napistu.identifiers import Identifiers
9
+
10
+ from napistu.modify import gaps
11
+
12
+
13
+ # Minimal compartments table
14
+ def _create_sbml_dfs_missing_transport_rxns():
15
+
16
+ compartments = pd.DataFrame(
17
+ {
18
+ SBML_DFS.C_NAME: ["mitochondria", "nucleus", "cytosol"],
19
+ SBML_DFS.C_IDENTIFIERS: [None],
20
+ SBML_DFS.C_SOURCE: [None],
21
+ },
22
+ index=["c_mito", "c_nucl", "c_cytosol"],
23
+ ).rename_axis(SBML_DFS.C_ID)
24
+
25
+ # Minimal species table
26
+ species = pd.DataFrame(
27
+ {
28
+ SBML_DFS.S_NAME: ["A"],
29
+ SBML_DFS.S_IDENTIFIERS: [
30
+ Identifiers(
31
+ [
32
+ {
33
+ "ontology": "uniprot",
34
+ "identifier": "PFAKE1",
35
+ "bqb": "BQB_IS",
36
+ "url": None,
37
+ }
38
+ ]
39
+ )
40
+ ],
41
+ SBML_DFS.S_SOURCE: [None],
42
+ },
43
+ index=["s_A"],
44
+ ).rename_axis(SBML_DFS.S_ID)
45
+
46
+ # Minimal compartmentalized_species table
47
+ compartmentalized_species = pd.DataFrame(
48
+ {
49
+ SBML_DFS.SC_NAME: ["A [mitochondria]", "A [nucleus]"],
50
+ SBML_DFS.S_ID: ["s_A", "s_A"],
51
+ SBML_DFS.C_ID: ["c_mito", "c_nucl"],
52
+ SBML_DFS.SC_SOURCE: [None],
53
+ },
54
+ index=["sc_A_mito", "sc_A_nucl"],
55
+ ).rename_axis(SBML_DFS.SC_ID)
56
+
57
+ # Minimal reactions table
58
+ reactions = pd.DataFrame(
59
+ {
60
+ SBML_DFS.R_NAME: ["A [mito] -> A [mito]", "A [nucl] -> A [nucl]"],
61
+ SBML_DFS.R_IDENTIFIERS: [None],
62
+ SBML_DFS.R_SOURCE: [None],
63
+ SBML_DFS.R_ISREVERSIBLE: [True, True],
64
+ },
65
+ index=["r_A_mito", "r_A_nucl"],
66
+ ).rename_axis(SBML_DFS.R_ID)
67
+
68
+ # Minimal reaction_species table
69
+ reaction_species = pd.DataFrame(
70
+ {
71
+ SBML_DFS.R_ID: ["r_A_mito", "r_A_mito", "r_A_nucl", "r_A_nucl"],
72
+ SBML_DFS.SC_ID: ["sc_A_mito", "sc_A_mito", "sc_A_nucl", "sc_A_nucl"],
73
+ SBML_DFS.STOICHIOMETRY: [-1, 1, -1, 1],
74
+ SBML_DFS.SBO_TERM: [
75
+ MINI_SBO_FROM_NAME["reactant"],
76
+ MINI_SBO_FROM_NAME["product"],
77
+ MINI_SBO_FROM_NAME["reactant"],
78
+ MINI_SBO_FROM_NAME["product"],
79
+ ],
80
+ },
81
+ index=[
82
+ "rsc_A_mito_sub",
83
+ "rsc_A_mito_prod",
84
+ "rsc_A_nucl_sub",
85
+ "rsc_A_nucl_prod",
86
+ ],
87
+ ).rename_axis(SBML_DFS.RSC_ID)
88
+
89
+ # Assemble the dict
90
+ sbml_dict = {
91
+ SBML_DFS.COMPARTMENTS: compartments,
92
+ SBML_DFS.SPECIES: species,
93
+ SBML_DFS.COMPARTMENTALIZED_SPECIES: compartmentalized_species,
94
+ SBML_DFS.REACTIONS: reactions,
95
+ SBML_DFS.REACTION_SPECIES: reaction_species,
96
+ }
97
+
98
+ # Create the SBML_dfs object
99
+ sbml_dfs = SBML_dfs(sbml_dict)
100
+
101
+ return sbml_dfs
102
+
103
+
104
+ def test_add_transportation_reactions():
105
+
106
+ sbml_dfs = _create_sbml_dfs_missing_transport_rxns()
107
+ sbml_dfs_w_transport = gaps.update_sbml_df_with_exchange(
108
+ np.array(["s_A"]), sbml_dfs, exchange_compartment="cytosol"
109
+ )
110
+ assert sbml_dfs_w_transport.reactions.shape[0] == 4, "Should add 2 reactions"
111
+ assert sbml_dfs_w_transport.reactions[
112
+ SBML_DFS.R_ISREVERSIBLE
113
+ ].all(), "Should be reversible"
114
+
115
+
116
+ def test_identify_species_needing_transport_reactions(sbml_dfs):
117
+ result = gaps._identify_species_needing_transport_reactions(sbml_dfs)
118
+ assert isinstance(result, np.ndarray)
119
+ assert result.size == 0
120
+
121
+ sbml_dfs = _create_sbml_dfs_missing_transport_rxns()
122
+ with warnings.catch_warnings():
123
+ warnings.simplefilter("ignore", RuntimeWarning)
124
+ result = gaps._identify_species_needing_transport_reactions(sbml_dfs)
125
+ assert isinstance(result, np.ndarray)
126
+ assert result.size == 1
127
+ assert result[0] == "s_A"
tests/test_gcs.py CHANGED
@@ -4,12 +4,13 @@ import os
4
4
  import pytest
5
5
  import shutil
6
6
 
7
- from napistu.gcs.downloads import load_public_cpr_asset
7
+ from napistu.gcs.downloads import load_public_napistu_asset
8
+
8
9
 
9
10
  @pytest.mark.skip_on_windows
10
11
  def test_download_and_load_gcs_asset():
11
12
 
12
- local_path = load_public_cpr_asset(
13
+ local_path = load_public_napistu_asset(
13
14
  asset="test_pathway", subasset="sbml_dfs", data_dir="/tmp"
14
15
  )
15
16
 
tests/test_igraph.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import os
4
+ import pytest
4
5
 
5
6
  import pandas as pd
6
7
  from napistu import sbml_dfs_core
@@ -109,10 +110,23 @@ def test_create_cpr_graph():
109
110
  _ = net_create.create_cpr_graph(sbml_dfs, graph_type="surrogate")
110
111
 
111
112
 
113
+ def test_create_cpr_graph_none_attrs():
114
+ # Should not raise when reaction_graph_attrs is None
115
+ _ = net_create.create_cpr_graph(
116
+ sbml_dfs, reaction_graph_attrs=None, graph_type="bipartite"
117
+ )
118
+
119
+
112
120
  def test_igraph_construction():
113
121
  _ = net_create.process_cpr_graph(sbml_dfs)
114
122
 
115
123
 
124
+ def test_process_cpr_graph_none_attrs():
125
+ # Should not raise when reaction_graph_attrs is None
126
+ _ = net_create.process_cpr_graph(sbml_dfs, reaction_graph_attrs=None)
127
+
128
+
129
+ @pytest.mark.skip_on_windows
116
130
  def test_igraph_loading():
117
131
  # test read/write of an igraph network
118
132
  directeds = [True, False]
@@ -0,0 +1,13 @@
1
+ import pytest
2
+ from napistu.mcp.documentation_utils import load_readme_content
3
+ from napistu.mcp.constants import READMES
4
+
5
+
6
+ @pytest.mark.asyncio
7
+ @pytest.mark.parametrize("name,url", READMES.items())
8
+ async def test_load_readme_content(name, url):
9
+ content = await load_readme_content(url)
10
+ assert isinstance(content, str)
11
+ assert len(content) > 0
12
+ # Optionally, check for a keyword in the content
13
+ assert "napistu" in content.lower() or "Napistu" in content