napistu 0.2.5.dev7__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.
- napistu/__main__.py +126 -96
- napistu/constants.py +35 -41
- napistu/context/__init__.py +10 -0
- napistu/context/discretize.py +462 -0
- napistu/context/filtering.py +387 -0
- napistu/gcs/__init__.py +1 -1
- napistu/identifiers.py +74 -15
- napistu/indices.py +68 -0
- napistu/ingestion/__init__.py +1 -1
- napistu/ingestion/bigg.py +47 -62
- napistu/ingestion/constants.py +18 -133
- napistu/ingestion/gtex.py +113 -0
- napistu/ingestion/hpa.py +147 -0
- napistu/ingestion/sbml.py +0 -97
- napistu/ingestion/string.py +2 -2
- napistu/matching/__init__.py +10 -0
- napistu/matching/constants.py +18 -0
- napistu/matching/interactions.py +518 -0
- napistu/matching/mount.py +529 -0
- napistu/matching/species.py +510 -0
- napistu/mcp/__init__.py +7 -4
- napistu/mcp/__main__.py +128 -72
- napistu/mcp/client.py +16 -25
- napistu/mcp/codebase.py +201 -145
- napistu/mcp/component_base.py +170 -0
- napistu/mcp/config.py +223 -0
- napistu/mcp/constants.py +45 -2
- napistu/mcp/documentation.py +253 -136
- napistu/mcp/documentation_utils.py +13 -48
- napistu/mcp/execution.py +372 -305
- napistu/mcp/health.py +47 -65
- napistu/mcp/profiles.py +10 -6
- napistu/mcp/server.py +161 -80
- napistu/mcp/tutorials.py +139 -87
- napistu/modify/__init__.py +1 -1
- napistu/modify/gaps.py +1 -1
- napistu/network/__init__.py +1 -1
- napistu/network/constants.py +101 -34
- napistu/network/data_handling.py +388 -0
- napistu/network/ig_utils.py +351 -0
- napistu/network/napistu_graph_core.py +354 -0
- napistu/network/neighborhoods.py +40 -40
- napistu/network/net_create.py +373 -309
- napistu/network/net_propagation.py +47 -19
- napistu/network/{net_utils.py → ng_utils.py} +124 -272
- napistu/network/paths.py +67 -51
- napistu/network/precompute.py +11 -11
- napistu/ontologies/__init__.py +10 -0
- napistu/ontologies/constants.py +129 -0
- napistu/ontologies/dogma.py +243 -0
- napistu/ontologies/genodexito.py +649 -0
- napistu/ontologies/mygene.py +369 -0
- napistu/ontologies/renaming.py +198 -0
- napistu/rpy2/__init__.py +229 -86
- napistu/rpy2/callr.py +47 -77
- napistu/rpy2/constants.py +24 -23
- napistu/rpy2/rids.py +61 -648
- napistu/sbml_dfs_core.py +587 -222
- napistu/scverse/__init__.py +15 -0
- napistu/scverse/constants.py +28 -0
- napistu/scverse/loading.py +727 -0
- napistu/utils.py +118 -10
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/METADATA +8 -3
- napistu-0.3.1.dist-info/RECORD +133 -0
- tests/conftest.py +22 -0
- tests/test_context_discretize.py +56 -0
- tests/test_context_filtering.py +267 -0
- tests/test_identifiers.py +100 -0
- tests/test_indices.py +65 -0
- tests/{test_edgelist.py → test_ingestion_napistu_edgelist.py} +2 -2
- tests/test_matching_interactions.py +108 -0
- tests/test_matching_mount.py +305 -0
- tests/test_matching_species.py +394 -0
- tests/test_mcp_config.py +193 -0
- tests/test_mcp_documentation_utils.py +12 -3
- tests/test_mcp_server.py +156 -19
- tests/test_network_data_handling.py +397 -0
- tests/test_network_ig_utils.py +23 -0
- tests/test_network_neighborhoods.py +19 -0
- tests/test_network_net_create.py +459 -0
- tests/test_network_ng_utils.py +30 -0
- tests/test_network_paths.py +56 -0
- tests/{test_precomputed_distances.py → test_network_precompute.py} +8 -6
- tests/test_ontologies_genodexito.py +58 -0
- tests/test_ontologies_mygene.py +39 -0
- tests/test_ontologies_renaming.py +110 -0
- tests/test_rpy2_callr.py +79 -0
- tests/test_rpy2_init.py +151 -0
- tests/test_sbml.py +0 -31
- tests/test_sbml_dfs_core.py +134 -10
- tests/test_scverse_loading.py +778 -0
- tests/test_set_coverage.py +2 -2
- tests/test_utils.py +121 -1
- napistu/mechanism_matching.py +0 -1353
- napistu/rpy2/netcontextr.py +0 -467
- napistu-0.2.5.dev7.dist-info/RECORD +0 -98
- tests/test_igraph.py +0 -367
- tests/test_mechanism_matching.py +0 -784
- tests/test_net_utils.py +0 -149
- tests/test_netcontextr.py +0 -105
- tests/test_rpy2.py +0 -61
- /napistu/ingestion/{cpr_edgelist.py → napistu_edgelist.py} +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/WHEEL +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/entry_points.txt +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/top_level.txt +0 -0
- /tests/{test_obo.py → test_ingestion_obo.py} +0 -0
tests/test_set_coverage.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from napistu import source
|
4
|
-
from napistu.network import
|
4
|
+
from napistu.network import ng_utils
|
5
5
|
|
6
6
|
|
7
7
|
def test_get_minimal_source_edges(sbml_dfs_metabolism):
|
@@ -9,7 +9,7 @@ def test_get_minimal_source_edges(sbml_dfs_metabolism):
|
|
9
9
|
columns={"r_id": "node"}
|
10
10
|
)
|
11
11
|
|
12
|
-
minimal_source_edges =
|
12
|
+
minimal_source_edges = ng_utils.get_minimal_sources_edges(
|
13
13
|
vertices, sbml_dfs_metabolism
|
14
14
|
)
|
15
15
|
# print(minimal_source_edges.shape)
|
tests/test_utils.py
CHANGED
@@ -9,13 +9,13 @@ from unittest.mock import patch
|
|
9
9
|
import numpy as np
|
10
10
|
import pandas as pd
|
11
11
|
import pytest
|
12
|
-
from napistu import utils
|
13
12
|
from fs.tarfs import TarFS
|
14
13
|
from fs.zipfs import ZipFS
|
15
14
|
from google.cloud import storage
|
16
15
|
from pytest import fixture
|
17
16
|
from testcontainers.core.container import DockerContainer
|
18
17
|
|
18
|
+
from napistu import utils
|
19
19
|
from napistu.utils import drop_extra_cols
|
20
20
|
|
21
21
|
|
@@ -556,6 +556,7 @@ def test_drop_extra_cols():
|
|
556
556
|
{"col1": [1, 2, 3], "col3": [7, 8, 9], "col4": [10, 11, 12]}
|
557
557
|
)
|
558
558
|
result_subset = drop_extra_cols(df_in, df_out_subset)
|
559
|
+
|
559
560
|
assert list(result_subset.columns) == ["col1", "col3"]
|
560
561
|
pd.testing.assert_frame_equal(result_subset, df_out_subset[["col1", "col3"]])
|
561
562
|
|
@@ -566,3 +567,122 @@ def test_drop_extra_cols():
|
|
566
567
|
pd.testing.assert_frame_equal(
|
567
568
|
result_subset_with_include, df_out_subset[["col1", "col3", "col4"]]
|
568
569
|
)
|
570
|
+
|
571
|
+
|
572
|
+
def test_merge_and_log_overwrites(caplog):
|
573
|
+
"""Test merge_and_log_overwrites function."""
|
574
|
+
|
575
|
+
# Test basic merge with no conflicts
|
576
|
+
df1 = pd.DataFrame({"id": [1, 2], "value1": ["a", "b"]})
|
577
|
+
df2 = pd.DataFrame({"id": [1, 2], "value2": ["c", "d"]})
|
578
|
+
result = utils._merge_and_log_overwrites(df1, df2, "test", on="id")
|
579
|
+
assert set(result.columns) == {"id", "value1", "value2"}
|
580
|
+
assert len(caplog.records) == 0
|
581
|
+
|
582
|
+
# Test merge with column conflict
|
583
|
+
df1 = pd.DataFrame({"id": [1, 2], "name": ["a", "b"], "value": [10, 20]})
|
584
|
+
df2 = pd.DataFrame({"id": [1, 2], "name": ["c", "d"]})
|
585
|
+
result = utils._merge_and_log_overwrites(df1, df2, "test", on="id")
|
586
|
+
|
587
|
+
# Check that the right columns exist
|
588
|
+
assert set(result.columns) == {"id", "name", "value"}
|
589
|
+
# Check that we got df2's values for the overlapping column
|
590
|
+
assert list(result["name"]) == ["c", "d"]
|
591
|
+
# Check that we kept df1's non-overlapping column
|
592
|
+
assert list(result["value"]) == [10, 20]
|
593
|
+
# Check that the warning was logged
|
594
|
+
assert len(caplog.records) == 1
|
595
|
+
assert "test merge" in caplog.records[0].message
|
596
|
+
assert "name" in caplog.records[0].message
|
597
|
+
|
598
|
+
# Test merge with multiple column conflicts
|
599
|
+
caplog.clear()
|
600
|
+
df1 = pd.DataFrame(
|
601
|
+
{"id": [1, 2], "name": ["a", "b"], "value": [10, 20], "status": ["ok", "ok"]}
|
602
|
+
)
|
603
|
+
df2 = pd.DataFrame(
|
604
|
+
{"id": [1, 2], "name": ["c", "d"], "status": ["pending", "done"]}
|
605
|
+
)
|
606
|
+
result = utils._merge_and_log_overwrites(df1, df2, "test", on="id")
|
607
|
+
|
608
|
+
# Check that the right columns exist
|
609
|
+
assert set(result.columns) == {"id", "name", "value", "status"}
|
610
|
+
# Check that we got df2's values for the overlapping columns
|
611
|
+
assert list(result["name"]) == ["c", "d"]
|
612
|
+
assert list(result["status"]) == ["pending", "done"]
|
613
|
+
# Check that we kept df1's non-overlapping column
|
614
|
+
assert list(result["value"]) == [10, 20]
|
615
|
+
# Check that the warning was logged with both column names
|
616
|
+
assert len(caplog.records) == 1
|
617
|
+
assert "test merge" in caplog.records[0].message
|
618
|
+
assert "name" in caplog.records[0].message
|
619
|
+
assert "status" in caplog.records[0].message
|
620
|
+
|
621
|
+
# Test merge with index
|
622
|
+
caplog.clear()
|
623
|
+
df1 = pd.DataFrame({"name": ["a", "b"], "value": [10, 20]}, index=[1, 2])
|
624
|
+
df2 = pd.DataFrame({"name": ["c", "d"]}, index=[1, 2])
|
625
|
+
result = utils._merge_and_log_overwrites(
|
626
|
+
df1, df2, "test", left_index=True, right_index=True
|
627
|
+
)
|
628
|
+
|
629
|
+
# Check that the right columns exist
|
630
|
+
assert set(result.columns) == {"name", "value"}
|
631
|
+
# Check that we got df2's values for the overlapping column
|
632
|
+
assert list(result["name"]) == ["c", "d"]
|
633
|
+
# Check that we kept df1's non-overlapping column
|
634
|
+
assert list(result["value"]) == [10, 20]
|
635
|
+
# Check that the warning was logged
|
636
|
+
assert len(caplog.records) == 1
|
637
|
+
assert "test merge" in caplog.records[0].message
|
638
|
+
assert "name" in caplog.records[0].message
|
639
|
+
|
640
|
+
|
641
|
+
def test_matrix_to_edgelist():
|
642
|
+
# Test case 1: Basic functionality with numeric indices
|
643
|
+
matrix = np.array([[1, 2, np.nan], [np.nan, 3, 4], [5, np.nan, 6]])
|
644
|
+
expected_edgelist = pd.DataFrame(
|
645
|
+
{
|
646
|
+
"row": [0, 0, 1, 1, 2, 2],
|
647
|
+
"column": [0, 1, 1, 2, 0, 2],
|
648
|
+
"value": np.array([1, 2, 3, 4, 5, 6], dtype=np.float64),
|
649
|
+
}
|
650
|
+
)
|
651
|
+
result = utils.matrix_to_edgelist(matrix)
|
652
|
+
pd.testing.assert_frame_equal(result, expected_edgelist)
|
653
|
+
|
654
|
+
# Test case 2: With row and column labels
|
655
|
+
row_labels = ["A", "B", "C"]
|
656
|
+
col_labels = ["X", "Y", "Z"]
|
657
|
+
expected_labeled_edgelist = pd.DataFrame(
|
658
|
+
{
|
659
|
+
"row": ["A", "A", "B", "B", "C", "C"],
|
660
|
+
"column": ["X", "Y", "Y", "Z", "X", "Z"],
|
661
|
+
"value": np.array([1, 2, 3, 4, 5, 6], dtype=np.float64),
|
662
|
+
}
|
663
|
+
)
|
664
|
+
result_labeled = utils.matrix_to_edgelist(
|
665
|
+
matrix, row_labels=row_labels, col_labels=col_labels
|
666
|
+
)
|
667
|
+
pd.testing.assert_frame_equal(result_labeled, expected_labeled_edgelist)
|
668
|
+
|
669
|
+
# Test case 3: Empty matrix (all NaN)
|
670
|
+
empty_matrix = np.full((2, 2), np.nan)
|
671
|
+
empty_result = utils.matrix_to_edgelist(empty_matrix)
|
672
|
+
assert empty_result.empty
|
673
|
+
|
674
|
+
# Test case 4: Single value matrix
|
675
|
+
single_matrix = np.array([[1]])
|
676
|
+
expected_single = pd.DataFrame(
|
677
|
+
{"row": [0], "column": [0], "value": np.array([1], dtype=np.int64)}
|
678
|
+
)
|
679
|
+
result_single = utils.matrix_to_edgelist(single_matrix)
|
680
|
+
pd.testing.assert_frame_equal(result_single, expected_single)
|
681
|
+
|
682
|
+
|
683
|
+
def test_safe_fill():
|
684
|
+
safe_fill_test = ["a_very_long stringggg", ""]
|
685
|
+
assert [utils.safe_fill(x) for x in safe_fill_test] == [
|
686
|
+
"a_very_long\nstringggg",
|
687
|
+
"",
|
688
|
+
]
|