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.
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 -145
  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 +47 -65
  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.dev7.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 +156 -19
  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.dev7.dist-info/RECORD +0 -98
  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.dev7.dist-info → napistu-0.3.1.dist-info}/WHEEL +0 -0
  104. {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/entry_points.txt +0 -0
  105. {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/licenses/LICENSE +0 -0
  106. {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dist-info}/top_level.txt +0 -0
  107. /tests/{test_obo.py → test_ingestion_obo.py} +0 -0
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from napistu import source
4
- from napistu.network import net_utils
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 = net_utils.get_minimal_sources_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
+ ]