napistu 0.2.5.dev6__py3-none-any.whl → 0.3.1__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 (107) hide show
  1. napistu/__main__.py +126 -96
  2. napistu/constants.py +35 -41
  3. napistu/context/__init__.py +10 -0
  4. napistu/context/discretize.py +462 -0
  5. napistu/context/filtering.py +387 -0
  6. napistu/gcs/__init__.py +1 -1
  7. napistu/identifiers.py +74 -15
  8. napistu/indices.py +68 -0
  9. napistu/ingestion/__init__.py +1 -1
  10. napistu/ingestion/bigg.py +47 -62
  11. napistu/ingestion/constants.py +18 -133
  12. napistu/ingestion/gtex.py +113 -0
  13. napistu/ingestion/hpa.py +147 -0
  14. napistu/ingestion/sbml.py +0 -97
  15. napistu/ingestion/string.py +2 -2
  16. napistu/matching/__init__.py +10 -0
  17. napistu/matching/constants.py +18 -0
  18. napistu/matching/interactions.py +518 -0
  19. napistu/matching/mount.py +529 -0
  20. napistu/matching/species.py +510 -0
  21. napistu/mcp/__init__.py +7 -4
  22. napistu/mcp/__main__.py +128 -72
  23. napistu/mcp/client.py +16 -25
  24. napistu/mcp/codebase.py +201 -153
  25. napistu/mcp/component_base.py +170 -0
  26. napistu/mcp/config.py +223 -0
  27. napistu/mcp/constants.py +45 -2
  28. napistu/mcp/documentation.py +253 -136
  29. napistu/mcp/documentation_utils.py +13 -48
  30. napistu/mcp/execution.py +372 -305
  31. napistu/mcp/health.py +49 -67
  32. napistu/mcp/profiles.py +10 -6
  33. napistu/mcp/server.py +161 -80
  34. napistu/mcp/tutorials.py +139 -87
  35. napistu/modify/__init__.py +1 -1
  36. napistu/modify/gaps.py +1 -1
  37. napistu/network/__init__.py +1 -1
  38. napistu/network/constants.py +101 -34
  39. napistu/network/data_handling.py +388 -0
  40. napistu/network/ig_utils.py +351 -0
  41. napistu/network/napistu_graph_core.py +354 -0
  42. napistu/network/neighborhoods.py +40 -40
  43. napistu/network/net_create.py +373 -309
  44. napistu/network/net_propagation.py +47 -19
  45. napistu/network/{net_utils.py → ng_utils.py} +124 -272
  46. napistu/network/paths.py +67 -51
  47. napistu/network/precompute.py +11 -11
  48. napistu/ontologies/__init__.py +10 -0
  49. napistu/ontologies/constants.py +129 -0
  50. napistu/ontologies/dogma.py +243 -0
  51. napistu/ontologies/genodexito.py +649 -0
  52. napistu/ontologies/mygene.py +369 -0
  53. napistu/ontologies/renaming.py +198 -0
  54. napistu/rpy2/__init__.py +229 -86
  55. napistu/rpy2/callr.py +47 -77
  56. napistu/rpy2/constants.py +24 -23
  57. napistu/rpy2/rids.py +61 -648
  58. napistu/sbml_dfs_core.py +587 -222
  59. napistu/scverse/__init__.py +15 -0
  60. napistu/scverse/constants.py +28 -0
  61. napistu/scverse/loading.py +727 -0
  62. napistu/utils.py +118 -10
  63. {napistu-0.2.5.dev6.dist-info → napistu-0.3.1.dist-info}/METADATA +8 -3
  64. napistu-0.3.1.dist-info/RECORD +133 -0
  65. tests/conftest.py +22 -0
  66. tests/test_context_discretize.py +56 -0
  67. tests/test_context_filtering.py +267 -0
  68. tests/test_identifiers.py +100 -0
  69. tests/test_indices.py +65 -0
  70. tests/{test_edgelist.py → test_ingestion_napistu_edgelist.py} +2 -2
  71. tests/test_matching_interactions.py +108 -0
  72. tests/test_matching_mount.py +305 -0
  73. tests/test_matching_species.py +394 -0
  74. tests/test_mcp_config.py +193 -0
  75. tests/test_mcp_documentation_utils.py +12 -3
  76. tests/test_mcp_server.py +356 -0
  77. tests/test_network_data_handling.py +397 -0
  78. tests/test_network_ig_utils.py +23 -0
  79. tests/test_network_neighborhoods.py +19 -0
  80. tests/test_network_net_create.py +459 -0
  81. tests/test_network_ng_utils.py +30 -0
  82. tests/test_network_paths.py +56 -0
  83. tests/{test_precomputed_distances.py → test_network_precompute.py} +8 -6
  84. tests/test_ontologies_genodexito.py +58 -0
  85. tests/test_ontologies_mygene.py +39 -0
  86. tests/test_ontologies_renaming.py +110 -0
  87. tests/test_rpy2_callr.py +79 -0
  88. tests/test_rpy2_init.py +151 -0
  89. tests/test_sbml.py +0 -31
  90. tests/test_sbml_dfs_core.py +134 -10
  91. tests/test_scverse_loading.py +778 -0
  92. tests/test_set_coverage.py +2 -2
  93. tests/test_utils.py +121 -1
  94. napistu/mechanism_matching.py +0 -1353
  95. napistu/rpy2/netcontextr.py +0 -467
  96. napistu-0.2.5.dev6.dist-info/RECORD +0 -97
  97. tests/test_igraph.py +0 -367
  98. tests/test_mechanism_matching.py +0 -784
  99. tests/test_net_utils.py +0 -149
  100. tests/test_netcontextr.py +0 -105
  101. tests/test_rpy2.py +0 -61
  102. /napistu/ingestion/{cpr_edgelist.py → napistu_edgelist.py} +0 -0
  103. {napistu-0.2.5.dev6.dist-info → napistu-0.3.1.dist-info}/WHEEL +0 -0
  104. {napistu-0.2.5.dev6.dist-info → napistu-0.3.1.dist-info}/entry_points.txt +0 -0
  105. {napistu-0.2.5.dev6.dist-info → napistu-0.3.1.dist-info}/licenses/LICENSE +0 -0
  106. {napistu-0.2.5.dev6.dist-info → napistu-0.3.1.dist-info}/top_level.txt +0 -0
  107. /tests/{test_obo.py → test_ingestion_obo.py} +0 -0
tests/test_net_utils.py DELETED
@@ -1,149 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import pytest
4
-
5
- import igraph as ig
6
- import numpy as np
7
- import pandas as pd
8
- from napistu.network import net_utils
9
- from napistu.network import net_create
10
-
11
-
12
- def test_safe_fill():
13
- safe_fill_test = ["a_very_long stringggg", ""]
14
- assert [net_utils.safe_fill(x) for x in safe_fill_test] == [
15
- "a_very_long\nstringggg",
16
- "",
17
- ]
18
-
19
-
20
- def test_cpr_graph_to_pandas_dfs():
21
- graph_data = [
22
- (0, 1),
23
- (0, 2),
24
- (2, 3),
25
- (3, 4),
26
- (4, 2),
27
- (2, 5),
28
- (5, 0),
29
- (6, 3),
30
- (5, 6),
31
- ]
32
-
33
- g = ig.Graph(graph_data, directed=True)
34
- vs, es = net_utils.cpr_graph_to_pandas_dfs(g)
35
-
36
- assert all(vs["index"] == list(range(0, 7)))
37
- assert (
38
- pd.DataFrame(graph_data)
39
- .rename({0: "source", 1: "target"}, axis=1)
40
- .sort_values(["source", "target"])
41
- .equals(es.sort_values(["source", "target"]))
42
- )
43
-
44
-
45
- def test_validate_graph_attributes(sbml_dfs):
46
-
47
- cpr_graph = net_create.process_cpr_graph(
48
- sbml_dfs, directed=True, weighting_strategy="topology"
49
- )
50
-
51
- assert (
52
- net_utils._validate_edge_attributes(cpr_graph, ["weights", "upstream_weights"])
53
- is None
54
- )
55
- assert net_utils._validate_vertex_attributes(cpr_graph, "node_type") is None
56
- with pytest.raises(ValueError):
57
- net_utils._validate_vertex_attributes(cpr_graph, "baz")
58
-
59
-
60
- def test_pluck_entity_data_species_identity(sbml_dfs):
61
- # Take first 10 species IDs
62
- species_ids = sbml_dfs.species.index[:10]
63
- # Create mock data with explicit dtype to ensure cross-platform consistency
64
- # Fix for issue-42: Use explicit dtypes to avoid platform-specific dtype differences
65
- # between Windows (int32) and macOS/Linux (int64)
66
- mock_df = pd.DataFrame(
67
- {
68
- "string_col": [f"str_{i}" for i in range(10)],
69
- "mixed_col": np.arange(-5, 5, dtype=np.int64), # Explicitly use int64
70
- "ones_col": np.ones(10, dtype=np.float64), # Explicitly use float64
71
- "squared_col": np.arange(10, dtype=np.int64), # Explicitly use int64
72
- },
73
- index=species_ids,
74
- )
75
- # Assign to species_data
76
- sbml_dfs.species_data["mock_table"] = mock_df
77
-
78
- # Custom transformation: square
79
- def square(x):
80
- return x**2
81
-
82
- custom_transformations = {"square": square}
83
- # Create graph_attrs for species
84
- graph_attrs = {
85
- "species": {
86
- "string_col": {
87
- "table": "mock_table",
88
- "variable": "string_col",
89
- "trans": "identity",
90
- },
91
- "mixed_col": {
92
- "table": "mock_table",
93
- "variable": "mixed_col",
94
- "trans": "identity",
95
- },
96
- "ones_col": {
97
- "table": "mock_table",
98
- "variable": "ones_col",
99
- "trans": "identity",
100
- },
101
- "squared_col": {
102
- "table": "mock_table",
103
- "variable": "squared_col",
104
- "trans": "square",
105
- },
106
- }
107
- }
108
- # Call pluck_entity_data with custom transformation
109
- result = net_create.pluck_entity_data(
110
- sbml_dfs, graph_attrs, "species", custom_transformations=custom_transformations
111
- )
112
- # Check output
113
- assert isinstance(result, pd.DataFrame)
114
- assert set(result.columns) == {"string_col", "mixed_col", "ones_col", "squared_col"}
115
- assert list(result.index) == list(species_ids)
116
- # Check values
117
- pd.testing.assert_series_equal(result["string_col"], mock_df["string_col"])
118
- pd.testing.assert_series_equal(result["mixed_col"], mock_df["mixed_col"])
119
- pd.testing.assert_series_equal(result["ones_col"], mock_df["ones_col"])
120
- pd.testing.assert_series_equal(
121
- result["squared_col"], mock_df["squared_col"].apply(square)
122
- )
123
-
124
-
125
- def test_pluck_entity_data_missing_species_key(sbml_dfs):
126
- # graph_attrs does not contain 'species' key
127
- graph_attrs = {}
128
- result = net_create.pluck_entity_data(sbml_dfs, graph_attrs, "species")
129
- assert result is None
130
-
131
-
132
- def test_pluck_entity_data_empty_species_dict(sbml_dfs):
133
- # graph_attrs contains 'species' key but value is empty dict
134
- graph_attrs = {"species": {}}
135
- result = net_create.pluck_entity_data(sbml_dfs, graph_attrs, "species")
136
- assert result is None
137
-
138
-
139
- ################################################
140
- # __main__
141
- ################################################
142
-
143
- if __name__ == "__main__":
144
- test_safe_fill()
145
- test_cpr_graph_to_pandas_dfs()
146
- test_validate_graph_attributes()
147
- test_pluck_entity_data_species_identity()
148
- test_pluck_entity_data_missing_species_key()
149
- test_pluck_entity_data_empty_species_dict()
tests/test_netcontextr.py DELETED
@@ -1,105 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import pandas as pd
4
- import pytest
5
- from napistu import sbml_dfs_core
6
- from napistu.identifiers import Identifiers
7
- from napistu.rpy2 import netcontextr
8
- from napistu.source import Source
9
-
10
-
11
- @pytest.fixture
12
- def sbml_dfs_one_reaction():
13
- """An sbml_dfs with one reaction and one annotated reactant"""
14
- interaction_edgelist = pd.DataFrame(
15
- {
16
- "upstream_name": ["a"],
17
- "downstream_name": ["b"],
18
- "upstream_compartment": ["nucleoplasm"],
19
- "downstream_compartment": ["nucleoplasm"],
20
- "r_name": ["a b of a"],
21
- "sbo_term": ["SBO:0000010"],
22
- "r_Identifiers": Identifiers([]),
23
- "r_isreversible": False,
24
- }
25
- )
26
- species = pd.DataFrame(
27
- {
28
- "s_name": ["a", "b"],
29
- "s_Identifiers": [
30
- Identifiers([{"ontology": "ensembl_gene", "identifier": "test"}]),
31
- Identifiers([]),
32
- ],
33
- }
34
- )
35
- compartments = pd.DataFrame(
36
- {"c_name": ["nucleoplasm"], "c_Identifiers": Identifiers([])}
37
- )
38
- interaction_source = Source(init=True)
39
- sbml_dfs = sbml_dfs_core.sbml_dfs_from_edgelist(
40
- interaction_edgelist, species, compartments, interaction_source
41
- )
42
- return sbml_dfs
43
-
44
-
45
- @pytest.fixture
46
- def sbml_dfs_one_reaction_duplicated_identifiers():
47
- """
48
- An sbml_dfs with one reactions and one annotated reactant
49
- that has two identifiers
50
- """
51
- interaction_edgelist = pd.DataFrame(
52
- {
53
- "upstream_name": ["a"],
54
- "downstream_name": ["b"],
55
- "upstream_compartment": ["nucleoplasm"],
56
- "downstream_compartment": ["nucleoplasm"],
57
- "r_name": ["a b of a"],
58
- "sbo_term": ["SBO:0000010"],
59
- "r_Identifiers": Identifiers([]),
60
- "r_isreversible": False,
61
- }
62
- )
63
- species = pd.DataFrame(
64
- {
65
- "s_name": ["a", "b"],
66
- "s_Identifiers": [
67
- Identifiers(
68
- [
69
- {"ontology": "ensembl_gene", "identifier": "test"},
70
- {"ontology": "ensembl_gene", "identifier": "test2"},
71
- ]
72
- ),
73
- Identifiers([]),
74
- ],
75
- }
76
- )
77
- compartments = pd.DataFrame(
78
- {"c_name": ["nucleoplasm"], "c_Identifiers": Identifiers([])}
79
- )
80
- interaction_source = Source(init=True)
81
- sbml_dfs = sbml_dfs_core.sbml_dfs_from_edgelist(
82
- interaction_edgelist, species, compartments, interaction_source
83
- )
84
- return sbml_dfs
85
-
86
-
87
- def test_get_reactions_one_reaction(sbml_dfs_one_reaction):
88
- reactions = netcontextr._get_reactions(sbml_dfs_one_reaction)
89
- assert not reactions[netcontextr.COL_GENE].isna().any()
90
- assert reactions.shape[0] == 1
91
-
92
-
93
- def test_get_reactions_outcols(sbml_dfs_one_reaction):
94
- reactions = netcontextr._get_reactions(sbml_dfs_one_reaction)
95
- assert netcontextr.COL_GENE in reactions.columns
96
- assert netcontextr.COL_REACTION_ID in reactions.columns
97
- assert netcontextr.COL_ROLE in reactions.columns
98
-
99
-
100
- def test_get_reactions_one_reaction_duplicated_ids(
101
- sbml_dfs_one_reaction_duplicated_identifiers,
102
- ):
103
- reactions = netcontextr._get_reactions(sbml_dfs_one_reaction_duplicated_identifiers)
104
- assert not reactions[netcontextr.COL_GENE].isna().any()
105
- assert reactions.shape[0] == 2
tests/test_rpy2.py DELETED
@@ -1,61 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from importlib import reload
5
- from unittest.mock import Mock
6
- from unittest.mock import patch
7
-
8
- import pytest
9
-
10
-
11
- # Patch rpy2_arrow.arrow to avoid ImportError
12
- # if the R env is not properly set up during testing
13
- sys.modules["rpy2_arrow.arrow"] = Mock()
14
- import napistu.rpy2.callr # noqa: E402
15
- import napistu.rpy2.rids # noqa: E402
16
-
17
-
18
- def test_rpy2_has_rpy2_false():
19
- with patch.dict("sys.modules", {"rpy2": None}):
20
- reload(napistu.rpy2)
21
- assert napistu.rpy2.has_rpy2 is False
22
- # Test if other napistu.rpy2 modules can be
23
- # loaded without rpy2 installed
24
- reload(napistu.rpy2.callr)
25
- reload(napistu.rpy2.rids)
26
-
27
-
28
- # def test_rpy2_has_rpy2_true():
29
- # with patch.dict("sys.modules", {"rpy2": "pytest"}):
30
- # reload(napistu.rpy2)
31
- # assert napistu.rpy2.has_rpy2 is True
32
-
33
-
34
- @patch("napistu.rpy2.has_rpy2", False)
35
- def test_warn_if_no_rpy2_false():
36
- @napistu.rpy2.warn_if_no_rpy2
37
- def test_func():
38
- pass
39
-
40
- with pytest.raises(ImportError):
41
- test_func()
42
-
43
-
44
- @patch("napistu.rpy2.has_rpy2", True)
45
- def test_warn_if_no_rpy2_true():
46
- @napistu.rpy2.warn_if_no_rpy2
47
- def test_func():
48
- pass
49
-
50
- test_func()
51
-
52
-
53
- ################################################
54
- # __main__
55
- ################################################
56
-
57
- if __name__ == "__main__":
58
- test_rpy2_has_rpy2_false()
59
- # test_rpy2_has_rpy2_true()
60
- test_warn_if_no_rpy2_false()
61
- test_warn_if_no_rpy2_true()
File without changes