napistu 0.3.4__py3-none-any.whl → 0.3.6__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 +18 -18
- napistu/consensus.py +3 -2
- napistu/constants.py +5 -5
- napistu/context/filtering.py +2 -1
- napistu/identifiers.py +3 -6
- napistu/ingestion/bigg.py +6 -6
- napistu/ingestion/string.py +2 -1
- napistu/ingestion/yeast.py +2 -1
- napistu/matching/interactions.py +4 -4
- napistu/modify/uncompartmentalize.py +1 -1
- napistu/network/ig_utils.py +35 -0
- napistu/network/net_create.py +1 -1
- napistu/network/paths.py +1 -1
- napistu/network/precompute.py +2 -1
- napistu/ontologies/dogma.py +2 -1
- napistu/sbml_dfs_core.py +1330 -2016
- napistu/sbml_dfs_utils.py +1082 -143
- napistu/source.py +1 -1
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/METADATA +2 -2
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/RECORD +32 -32
- tests/conftest.py +43 -0
- tests/test_consensus.py +88 -0
- tests/test_context_filtering.py +2 -2
- tests/test_network_ig_utils.py +36 -0
- tests/test_ontologies_genodexito.py +3 -0
- tests/test_ontologies_mygene.py +3 -0
- tests/test_sbml_dfs_core.py +221 -191
- tests/test_sbml_dfs_utils.py +194 -36
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/WHEEL +0 -0
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/entry_points.txt +0 -0
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.3.4.dist-info → napistu-0.3.6.dist-info}/top_level.txt +0 -0
napistu/source.py
CHANGED
@@ -223,7 +223,7 @@ def greedy_set_coverge_of_sources(
|
|
223
223
|
Greedy Set Coverage of Sources
|
224
224
|
|
225
225
|
Apply the greedy set coverge algorithm to find the minimal set of
|
226
|
-
|
226
|
+
sources which cover all entries
|
227
227
|
|
228
228
|
Parameters:
|
229
229
|
source_df: pd.DataFrame
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: napistu
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.6
|
4
4
|
Summary: Connecting high-dimensional data to curated pathways
|
5
5
|
Home-page: https://github.com/napistu/napistu-py
|
6
6
|
Author: Sean Hackett
|
@@ -43,7 +43,7 @@ Requires-Dist: pytest-cov; extra == "dev"
|
|
43
43
|
Requires-Dist: ruff; extra == "dev"
|
44
44
|
Requires-Dist: testcontainers; extra == "dev"
|
45
45
|
Provides-Extra: mcp
|
46
|
-
Requires-Dist: fastmcp<
|
46
|
+
Requires-Dist: fastmcp<2.9.0,>=2.0.0; extra == "mcp"
|
47
47
|
Requires-Dist: mcp<2.0.0,>=1.0.0; extra == "mcp"
|
48
48
|
Requires-Dist: httpx>=0.24.0; extra == "mcp"
|
49
49
|
Requires-Dist: beautifulsoup4<5.0.0,>=4.11.0; extra == "mcp"
|
@@ -1,22 +1,22 @@
|
|
1
1
|
napistu/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
2
|
-
napistu/__main__.py,sha256=
|
3
|
-
napistu/consensus.py,sha256=
|
4
|
-
napistu/constants.py,sha256=
|
5
|
-
napistu/identifiers.py,sha256=
|
2
|
+
napistu/__main__.py,sha256=JnPRdK9Revwpi0pouC7ZIZAMEunh9NIFuaq91RlPaR0,28648
|
3
|
+
napistu/consensus.py,sha256=jsWpoXOzmNklFKasgOa5NEqbhoZvsgY0rLMFQddi6Vo,69945
|
4
|
+
napistu/constants.py,sha256=IhjZZgP0Yb3pPn5mV5SeTWiimRSG2hH02UX_Y6c_aOo,12388
|
5
|
+
napistu/identifiers.py,sha256=e2-nTVzr5AINa0y1ER9218bKXyF2kAeJ9At22S4Z00o,33914
|
6
6
|
napistu/indices.py,sha256=E_djN1XWc6l1lrFw_QnQXfZTKYTaUv8-jFPP7cHkY5A,9780
|
7
|
-
napistu/sbml_dfs_core.py,sha256=
|
8
|
-
napistu/sbml_dfs_utils.py,sha256=
|
9
|
-
napistu/source.py,sha256=
|
7
|
+
napistu/sbml_dfs_core.py,sha256=ntZfuKrjf42MV1EXhKUro298a1aSd6t6M-tt141x634,71129
|
8
|
+
napistu/sbml_dfs_utils.py,sha256=aXbQIlx7Yv7TH_7YxSuHZLsf6w2UXd_iOzpALKzg608,43506
|
9
|
+
napistu/source.py,sha256=UGpN70bqbC9gnKmM0ivSdQYim9hfzgABeXoQKzRr9oU,13646
|
10
10
|
napistu/utils.py,sha256=TcholWrFbRSu_sn9ODMA8y2YyAhekEKZjwf4S0WQNzI,33241
|
11
11
|
napistu/context/__init__.py,sha256=LQBEqipcHKK0E5UlDEg1ct-ymCs93IlUrUaH8BCevf0,242
|
12
12
|
napistu/context/discretize.py,sha256=Qq7zg46F_I-PvQIT2_pEDQV7YEtUQCxKoRvT5Gu9QsE,15052
|
13
|
-
napistu/context/filtering.py,sha256=
|
13
|
+
napistu/context/filtering.py,sha256=l1oq-43ysSGqU9VmhTOO_pYT4DSMf20yxvktPC1MI0I,13696
|
14
14
|
napistu/gcs/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
15
15
|
napistu/gcs/constants.py,sha256=g6PaU99GY5XvaRHx4BGmWHUpcJ36-Zh_GzeNVOeHviM,2856
|
16
16
|
napistu/gcs/downloads.py,sha256=SvGv9WYr_Vt3guzyz1QiAuBndeKPTBtWSFLj1-QbLf4,6348
|
17
17
|
napistu/gcs/utils.py,sha256=eLSsvewWJdCguyj2k0ozUGP5BTemaE1PZg41Z3aY5kM,571
|
18
18
|
napistu/ingestion/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
19
|
-
napistu/ingestion/bigg.py,sha256=
|
19
|
+
napistu/ingestion/bigg.py,sha256=f65--8ARe248eYCUJpFMF284Wz53sLyFyBuwelxHmJA,4340
|
20
20
|
napistu/ingestion/constants.py,sha256=9UP47VImZ11q0kz17N3EJg2155USqLewwNWyKpA-cbA,8089
|
21
21
|
napistu/ingestion/gtex.py,sha256=X0hSC1yrpf4xSJWFhpeNcnHwJzKDII2MvjfUqYA0JN8,3720
|
22
22
|
napistu/ingestion/hpa.py,sha256=R27ExrryKQ4Crxv9ATXmBJCa-yd01TMOrDjkeBhIQac,5054
|
@@ -26,12 +26,12 @@ napistu/ingestion/obo.py,sha256=AQkIPWbjA464Lma0tx91JucWkIwLjC7Jgv5VHGRTDkE,9601
|
|
26
26
|
napistu/ingestion/psi_mi.py,sha256=5eJjm7XWogL9oTyGqR52kntHClLwLsTePKqCvUGyi-w,10111
|
27
27
|
napistu/ingestion/reactome.py,sha256=Hn9X-vDp4o_HK-OtaQvel3vJeZ8_TC1-4N2rruK9Oks,7099
|
28
28
|
napistu/ingestion/sbml.py,sha256=N7neMwjTEF7OMhAcNvQJ29V_d3PqMLjLOZqvJTlK9q0,24743
|
29
|
-
napistu/ingestion/string.py,sha256=
|
29
|
+
napistu/ingestion/string.py,sha256=eLboW-dkaaiypwW6DxM3P1mGVweM3wqGsJPYKyImMAI,11713
|
30
30
|
napistu/ingestion/trrust.py,sha256=ccjZc_eF3PdxxurnukiEo_e0-aKc_3z22NYbaJBtHdY,9774
|
31
|
-
napistu/ingestion/yeast.py,sha256=
|
31
|
+
napistu/ingestion/yeast.py,sha256=7XwdkmgOnG1MYauKSk9nSK6fHemDrtXEPcS4ebs1_so,5268
|
32
32
|
napistu/matching/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
33
33
|
napistu/matching/constants.py,sha256=j4XSOE9Bpma9F6apVJ1LijKOUPgRk8Geo_u_rvNtpSU,610
|
34
|
-
napistu/matching/interactions.py,sha256=
|
34
|
+
napistu/matching/interactions.py,sha256=XrzZvH1zgeaZLq3qhpsV0tx4BFgvNvkjM47l8ZUEOH4,18798
|
35
35
|
napistu/matching/mount.py,sha256=8JEtiDIy7qdjWyDAs0vuVwEQkpwRf5ah4xMLZ4jKHag,19428
|
36
36
|
napistu/matching/species.py,sha256=5-hmH8_UrvDmGfeJ1283trkCtPOC3BEmtYPcMHuZyNY,18893
|
37
37
|
napistu/mcp/__init__.py,sha256=EmtcdtYyfhXdxxPB5cY_pshXnFv6XZ5CtRU0JMHn3aQ,2074
|
@@ -56,21 +56,21 @@ napistu/modify/constants.py,sha256=H6K6twzPlxt0yp6QLAxIx0Tp8YzYhtKKXPdmXi5V_QQ,3
|
|
56
56
|
napistu/modify/curation.py,sha256=sQeSO53ZLdn14ww2GSKkoP0vJnDpAoSWb-YDjUf5hDQ,21743
|
57
57
|
napistu/modify/gaps.py,sha256=qprylC2BbSk_vPWayYPVT8lwURXDMOlW5zNLV_wMFZ4,26755
|
58
58
|
napistu/modify/pathwayannot.py,sha256=xuBSMDFWbg_d6-Gzv0Td3Q5nnFTa-Qzic48g1b1AZtQ,48081
|
59
|
-
napistu/modify/uncompartmentalize.py,sha256=
|
59
|
+
napistu/modify/uncompartmentalize.py,sha256=y5LkXn5x6u80dB_McfAIh88BxZGIAVFLujkP7sPNRh0,9690
|
60
60
|
napistu/network/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
61
61
|
napistu/network/constants.py,sha256=fC1njZDu6in1JiaZ1-T1_fhmmkcc2HKSUUomDVyQ7Dw,5789
|
62
62
|
napistu/network/data_handling.py,sha256=mxplWwyXNrjZRN-jjWWUI9IZOqX69k8qSMDIrL9h0Og,14736
|
63
|
-
napistu/network/ig_utils.py,sha256=
|
63
|
+
napistu/network/ig_utils.py,sha256=JSlf_sZtw3DiiSIiYJ2YqJFEP4hVJMwNRox2qYTA4zY,11470
|
64
64
|
napistu/network/napistu_graph_core.py,sha256=2NbjiLcDcFWFyX1MuN17pobPDgoQFtcYWOwuPSFTT4g,10429
|
65
65
|
napistu/network/neighborhoods.py,sha256=Q9HWUvf_J4a_4RQDKd7ywEy4cp3Wq2OPOfVsotDbEe0,56098
|
66
|
-
napistu/network/net_create.py,sha256=
|
66
|
+
napistu/network/net_create.py,sha256=aAw6kfHREpkMEcwQFgwU5CHg--b8YLO559surQLRXZI,69408
|
67
67
|
napistu/network/net_propagation.py,sha256=89ZR4p2mGpkCCIemofZ53XbUjQsuNABxIc6UmF8A5n8,4935
|
68
68
|
napistu/network/ng_utils.py,sha256=ijWDa5MTuULJpdV6dcVFGmLmtB_xy87jaUG7F5nvC_k,15240
|
69
|
-
napistu/network/paths.py,sha256
|
70
|
-
napistu/network/precompute.py,sha256=
|
69
|
+
napistu/network/paths.py,sha256=-dxRtaBRDYwuMw9DByGSn5OXFC3umDeO2zvVvD0TdWE,17452
|
70
|
+
napistu/network/precompute.py,sha256=pIXCCE6Mf6HY8o-fiwUaOxvQ_9_mevK0vaC8fND4RZk,9141
|
71
71
|
napistu/ontologies/__init__.py,sha256=dFXAhIqlTLJMwowS4BUDT08-Vy3Q0u1L0CMCErSZT1Y,239
|
72
72
|
napistu/ontologies/constants.py,sha256=GyOFvezSxDK1VigATcruTKtNhjcYaid1ggulEf_HEtQ,4345
|
73
|
-
napistu/ontologies/dogma.py,sha256=
|
73
|
+
napistu/ontologies/dogma.py,sha256=VVj6NKBgNym4SdOSu8g22OohALj7cbObhIJmdY2Sfy0,8860
|
74
74
|
napistu/ontologies/genodexito.py,sha256=5_gtdVtKHp5z-jtPXkHlZRiTsuHdZeA3TVI9u4SXqrQ,24725
|
75
75
|
napistu/ontologies/mygene.py,sha256=RMFQTWsLkeYxmsOPxxmeIya2phdcUMcF5V2abaS8MVg,11109
|
76
76
|
napistu/ontologies/renaming.py,sha256=bL15T0CswjM81NFVIVp-3CEsa1kxIIk2xJ2kE5eTeeg,6817
|
@@ -81,13 +81,13 @@ napistu/rpy2/rids.py,sha256=AfXLTfTdonfspgAHYO0Ph7jSUWv8YuyT8x3fyLfAqc8,3413
|
|
81
81
|
napistu/scverse/__init__.py,sha256=Lgxr3iMQAkTzXE9BNz93CndNP5djzerLvmHM-D0PU3I,357
|
82
82
|
napistu/scverse/constants.py,sha256=0iAkhyJUIeFGHdLLU3fCaEU1O3Oix4qAsxr3CxGTjVs,653
|
83
83
|
napistu/scverse/loading.py,sha256=jqiE71XB-wdV50GyZrauFNY0Lai4bX9Fm2Gv80VR8t8,27016
|
84
|
-
napistu-0.3.
|
84
|
+
napistu-0.3.6.dist-info/licenses/LICENSE,sha256=kW8wVT__JWoHjl2BbbJDAZInWa9AxzJeR_uv6-i5x1g,1063
|
85
85
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
86
|
-
tests/conftest.py,sha256=
|
87
|
-
tests/test_consensus.py,sha256=
|
86
|
+
tests/conftest.py,sha256=v8ZxJKqglEPlQ5ew3hM5eJQW2N0YhX9dOAaOQqdjyIc,4325
|
87
|
+
tests/test_consensus.py,sha256=qnf6Ntc3q7oCji1aisH9Ziy6KbnQCf1REizinR8ier8,12454
|
88
88
|
tests/test_constants.py,sha256=gJLDv7QMeeBiiupyMazj6mumk20KWvGMgm2myHMKKfc,531
|
89
89
|
tests/test_context_discretize.py,sha256=5Mr9WqwHGYMO37M1TnMmSfC64UZ73mnoCiEM2IQHVDY,1667
|
90
|
-
tests/test_context_filtering.py,sha256=
|
90
|
+
tests/test_context_filtering.py,sha256=5dwC2d-99CpLdnzzTf2NvEzsRuwiIj-YU8NFqwtWp0g,9485
|
91
91
|
tests/test_curation.py,sha256=-Q2J0D7qs9PGjHZX-rM4NxRLLdwxoapytSo_98q9ItY,3864
|
92
92
|
tests/test_gaps.py,sha256=mGGeyx1vUnmEOF__bsqfCYq9Y8a1P-9mefqna4Qgc_k,4062
|
93
93
|
tests/test_gcs.py,sha256=p_uQWuY2TcGj3zV3qFC-GXBqj4St8YENR_XRpQ6UH5g,570
|
@@ -102,22 +102,22 @@ tests/test_mcp_config.py,sha256=GTu9vywqAHTYkolywdYS_BEIW3gBzs4A4qcneMSPpRk,7007
|
|
102
102
|
tests/test_mcp_documentation_utils.py,sha256=OW0N2N_2IOktbYTcCWhhWz4bANi8IB60l1q3DJi8Ra4,810
|
103
103
|
tests/test_mcp_server.py,sha256=bP3PWVQsEfX6-lAgXKP32njdg__o65n2WuLvkxTTHkQ,11215
|
104
104
|
tests/test_network_data_handling.py,sha256=oBSZuB3IRG9bwmD6n8FY-UZLe2UqGzXpNSxVtkHRSvE,12605
|
105
|
-
tests/test_network_ig_utils.py,sha256=
|
105
|
+
tests/test_network_ig_utils.py,sha256=Buoh570mNm5pcac3Hf6f3pevCjWfBwPfKuD8IkDLg58,2120
|
106
106
|
tests/test_network_neighborhoods.py,sha256=8BV17m5X1OUd5FwasTTYUOkNYUHDPUkxOKH_VZCsyBE,631
|
107
107
|
tests/test_network_net_create.py,sha256=VNFZTwQawAZQPDnVk_qFevgZErx5KyQZ24bMoZF4T4w,16462
|
108
108
|
tests/test_network_net_propagation.py,sha256=9pKkUdduWejH4iKNCJXKFzAkdNpCfrMbiUWySgI_LH4,3244
|
109
109
|
tests/test_network_ng_utils.py,sha256=CwDw4MKTPhVZXz2HA2XU2QjjBv8CXc1_yQ0drvkBkFw,724
|
110
110
|
tests/test_network_paths.py,sha256=TWZnxY5bF3m6gahcxcYJGrBIawh2-_vUcec1LyPmXV8,1686
|
111
111
|
tests/test_network_precompute.py,sha256=xMGmZI9DxcWhJxuP7GCZEqtmcOvDRNK2LSia0x94v0U,9018
|
112
|
-
tests/test_ontologies_genodexito.py,sha256=
|
113
|
-
tests/test_ontologies_mygene.py,sha256=
|
112
|
+
tests/test_ontologies_genodexito.py,sha256=6fINyUiubHZqu7qxye09DQfJXw28ZMAJc3clPb-cCoY,2298
|
113
|
+
tests/test_ontologies_mygene.py,sha256=VkdRcKIWmcG6V-2dpfvsBiOJN5dO-j0RqZNxtJRcyBU,1583
|
114
114
|
tests/test_ontologies_renaming.py,sha256=k7bQzP24zG7W3fpULwk1me2sOWEWlxylr4Mhx1_gJJY,3740
|
115
115
|
tests/test_pathwayannot.py,sha256=bceosccNy9tgxQei_7j7ATBSSvBSxOngJvK-mAzR_K0,3312
|
116
116
|
tests/test_rpy2_callr.py,sha256=UVzXMvYN3wcc-ikDIjH2sA4BqkbwiNbMm561BcbnbD4,2936
|
117
117
|
tests/test_rpy2_init.py,sha256=APrNt9GEQV9va3vU5k250TxFplAoWFc-FJRFhM2GcDk,5927
|
118
118
|
tests/test_sbml.py,sha256=f25zj1NogYrmLluvBDboLameTuCiQ309433Qn3iPvhg,1483
|
119
|
-
tests/test_sbml_dfs_core.py,sha256=
|
120
|
-
tests/test_sbml_dfs_utils.py,sha256
|
119
|
+
tests/test_sbml_dfs_core.py,sha256=Gef-wf0AI7adwS_CBUokiJCw7yyGzInwAUnAj7IRE-E,20311
|
120
|
+
tests/test_sbml_dfs_utils.py,sha256=-EAW6N_elEOSQdsdRhnEdDhnZQH_weCGpnVOd2Xaepc,6963
|
121
121
|
tests/test_sbo.py,sha256=x_PENFaXYsrZIzOZu9cj_Wrej7i7SNGxgBYYvcigLs0,308
|
122
122
|
tests/test_scverse_loading.py,sha256=bnU1lQSYYWhOAs0IIBoi4ZohqPokDQJ0n_rtkAfEyMU,29948
|
123
123
|
tests/test_set_coverage.py,sha256=J-6m6LuOjcQa9pxRuWglSfJk4Ltm7kt_eOrn_Q-7P6Q,1604
|
@@ -126,8 +126,8 @@ tests/test_uncompartmentalize.py,sha256=nAk5kfAVLU9a2VWe2x2HYVcKqj-EnwmwddERIPRa
|
|
126
126
|
tests/test_utils.py,sha256=JRJFmjDNZpjG59a-73JkTyGqa_a7Z8d0fE2cZt0CRII,22580
|
127
127
|
tests/utils.py,sha256=SoWQ_5roJteFGcMaOeEiQ5ucwq3Z2Fa3AAs9iXHTsJY,749
|
128
128
|
tests/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
129
|
-
napistu-0.3.
|
130
|
-
napistu-0.3.
|
131
|
-
napistu-0.3.
|
132
|
-
napistu-0.3.
|
133
|
-
napistu-0.3.
|
129
|
+
napistu-0.3.6.dist-info/METADATA,sha256=vJqqDnZ9MU1mmU_qTFgGnBgaYx4zt-yqg26H6VDkqz0,3414
|
130
|
+
napistu-0.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
131
|
+
napistu-0.3.6.dist-info/entry_points.txt,sha256=_QnaPOvJNA3IltxmZgWIiBoen-L1bPYX18YQfC7oJgQ,41
|
132
|
+
napistu-0.3.6.dist-info/top_level.txt,sha256=Gpvk0a_PjrtqhYcQ9IDr3zR5LqpZ-uIHidQMIpjlvhY,14
|
133
|
+
napistu-0.3.6.dist-info/RECORD,,
|
tests/conftest.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import functools
|
3
4
|
import os
|
4
5
|
import sys
|
6
|
+
import threading
|
5
7
|
|
8
|
+
import pytest
|
6
9
|
|
7
10
|
from napistu import consensus
|
8
11
|
from napistu import indices
|
@@ -109,3 +112,43 @@ def pytest_runtest_setup(item):
|
|
109
112
|
# Skip tests that should run only on Unix
|
110
113
|
if not is_unix and any(mark.name == "unix_only" for mark in item.iter_markers()):
|
111
114
|
skip("Test runs only on Unix systems")
|
115
|
+
|
116
|
+
|
117
|
+
def skip_on_timeout(timeout_seconds):
|
118
|
+
"""Cross-platform decorator that skips a test if it takes longer than timeout_seconds"""
|
119
|
+
|
120
|
+
def decorator(func):
|
121
|
+
@functools.wraps(func)
|
122
|
+
def wrapper(*args, **kwargs):
|
123
|
+
result = [None]
|
124
|
+
exception = [None]
|
125
|
+
finished = [False]
|
126
|
+
|
127
|
+
def target():
|
128
|
+
try:
|
129
|
+
result[0] = func(*args, **kwargs)
|
130
|
+
finished[0] = True
|
131
|
+
except Exception as e:
|
132
|
+
exception[0] = e
|
133
|
+
finished[0] = True
|
134
|
+
|
135
|
+
thread = threading.Thread(target=target)
|
136
|
+
thread.daemon = True
|
137
|
+
thread.start()
|
138
|
+
thread.join(timeout_seconds)
|
139
|
+
|
140
|
+
if not finished[0]:
|
141
|
+
# Thread is still running, timeout occurred
|
142
|
+
pytest.skip(f"Test skipped due to timeout ({timeout_seconds}s)")
|
143
|
+
|
144
|
+
if exception[0]:
|
145
|
+
raise exception[0]
|
146
|
+
|
147
|
+
return result[0]
|
148
|
+
|
149
|
+
return wrapper
|
150
|
+
|
151
|
+
return decorator
|
152
|
+
|
153
|
+
|
154
|
+
pytest.skip_on_timeout = skip_on_timeout
|
tests/test_consensus.py
CHANGED
@@ -7,8 +7,10 @@ import pytest
|
|
7
7
|
from napistu import consensus
|
8
8
|
from napistu import indices
|
9
9
|
from napistu import source
|
10
|
+
from napistu import sbml_dfs_core
|
10
11
|
from napistu.ingestion import sbml
|
11
12
|
from napistu.modify import pathwayannot
|
13
|
+
from napistu.constants import SBML_DFS, SBML_DFS_SCHEMA
|
12
14
|
|
13
15
|
test_path = os.path.abspath(os.path.join(__file__, os.pardir))
|
14
16
|
test_data = os.path.join(test_path, "test_data")
|
@@ -246,6 +248,91 @@ def test_consensus_ontology_check():
|
|
246
248
|
assert post_shared_onto_sp_set == {"chebi", "reactome", "uniprot"}
|
247
249
|
|
248
250
|
|
251
|
+
def test_report_consensus_merges_reactions(tmp_path):
|
252
|
+
# Create two minimal SBML_dfs objects with a single reaction each, same r_id
|
253
|
+
r_id = "R00000001"
|
254
|
+
reactions = pd.DataFrame(
|
255
|
+
{
|
256
|
+
SBML_DFS.R_NAME: ["rxn1"],
|
257
|
+
SBML_DFS.R_IDENTIFIERS: [None],
|
258
|
+
SBML_DFS.R_SOURCE: [None],
|
259
|
+
SBML_DFS.R_ISREVERSIBLE: [False],
|
260
|
+
},
|
261
|
+
index=[r_id],
|
262
|
+
)
|
263
|
+
reactions.index.name = SBML_DFS.R_ID
|
264
|
+
reaction_species = pd.DataFrame(
|
265
|
+
{
|
266
|
+
SBML_DFS.R_ID: [r_id],
|
267
|
+
SBML_DFS.SC_ID: ["SC0001"],
|
268
|
+
SBML_DFS.STOICHIOMETRY: [1],
|
269
|
+
SBML_DFS.SBO_TERM: ["SBO:0000459"],
|
270
|
+
},
|
271
|
+
index=["RSC0001"],
|
272
|
+
)
|
273
|
+
reaction_species.index.name = SBML_DFS.RSC_ID
|
274
|
+
compartmentalized_species = pd.DataFrame(
|
275
|
+
{
|
276
|
+
SBML_DFS.SC_NAME: ["A [cytosol]"],
|
277
|
+
SBML_DFS.S_ID: ["S0001"],
|
278
|
+
SBML_DFS.C_ID: ["C0001"],
|
279
|
+
SBML_DFS.SC_SOURCE: [None],
|
280
|
+
},
|
281
|
+
index=["SC0001"],
|
282
|
+
)
|
283
|
+
compartmentalized_species.index.name = SBML_DFS.SC_ID
|
284
|
+
species = pd.DataFrame(
|
285
|
+
{
|
286
|
+
SBML_DFS.S_NAME: ["A"],
|
287
|
+
SBML_DFS.S_IDENTIFIERS: [None],
|
288
|
+
SBML_DFS.S_SOURCE: [None],
|
289
|
+
},
|
290
|
+
index=["S0001"],
|
291
|
+
)
|
292
|
+
species.index.name = SBML_DFS.S_ID
|
293
|
+
compartments = pd.DataFrame(
|
294
|
+
{
|
295
|
+
SBML_DFS.C_NAME: ["cytosol"],
|
296
|
+
SBML_DFS.C_IDENTIFIERS: [None],
|
297
|
+
SBML_DFS.C_SOURCE: [None],
|
298
|
+
},
|
299
|
+
index=["C0001"],
|
300
|
+
)
|
301
|
+
compartments.index.name = SBML_DFS.C_ID
|
302
|
+
sbml_dict = {
|
303
|
+
SBML_DFS.COMPARTMENTS: compartments,
|
304
|
+
SBML_DFS.SPECIES: species,
|
305
|
+
SBML_DFS.COMPARTMENTALIZED_SPECIES: compartmentalized_species,
|
306
|
+
SBML_DFS.REACTIONS: reactions,
|
307
|
+
SBML_DFS.REACTION_SPECIES: reaction_species,
|
308
|
+
}
|
309
|
+
sbml1 = sbml_dfs_core.SBML_dfs(sbml_dict, validate=False, resolve=False)
|
310
|
+
sbml2 = sbml_dfs_core.SBML_dfs(sbml_dict, validate=False, resolve=False)
|
311
|
+
sbml_dfs_dict = {"mod1": sbml1, "mod2": sbml2}
|
312
|
+
|
313
|
+
# Create a lookup_table that merges both reactions into a new_id
|
314
|
+
lookup_table = pd.DataFrame(
|
315
|
+
{
|
316
|
+
"model": ["mod1", "mod2"],
|
317
|
+
"r_id": [r_id, r_id],
|
318
|
+
"new_id": ["merged_rid", "merged_rid"],
|
319
|
+
}
|
320
|
+
)
|
321
|
+
# Use the reactions schema
|
322
|
+
table_schema = SBML_DFS_SCHEMA.SCHEMA[SBML_DFS.REACTIONS]
|
323
|
+
|
324
|
+
# Call the function and check that it runs and the merge_labels are as expected
|
325
|
+
consensus.report_consensus_merges(
|
326
|
+
lookup_table.set_index(["model", "r_id"])[
|
327
|
+
"new_id"
|
328
|
+
], # this is a Series with name 'new_id'
|
329
|
+
table_schema,
|
330
|
+
sbml_dfs_dict=sbml_dfs_dict,
|
331
|
+
n_example_merges=1,
|
332
|
+
)
|
333
|
+
# No assertion: this is a smoke test to ensure the Series output is handled without error
|
334
|
+
|
335
|
+
|
249
336
|
################################################
|
250
337
|
# __main__
|
251
338
|
################################################
|
@@ -256,3 +343,4 @@ if __name__ == "__main__":
|
|
256
343
|
test_source_tracking()
|
257
344
|
test_passing_entity_data()
|
258
345
|
test_consensus_ontology_check()
|
346
|
+
test_report_consensus_merges_reactions()
|
tests/test_context_filtering.py
CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
import copy
|
4
4
|
import pytest
|
5
5
|
import pandas as pd
|
6
|
-
from napistu import
|
6
|
+
from napistu import sbml_dfs_utils
|
7
7
|
from napistu.constants import SBML_DFS
|
8
8
|
from napistu.context.filtering import (
|
9
9
|
filter_species_by_attribute,
|
@@ -208,7 +208,7 @@ def test_filter_reactions_with_disconnected_cspecies(sbml_dfs):
|
|
208
208
|
first_reactions = list(sbml_dfs.reactions.index[:5])
|
209
209
|
|
210
210
|
# 2. Find defining species in these reactions
|
211
|
-
reaction_species =
|
211
|
+
reaction_species = sbml_dfs_utils.add_sbo_role(sbml_dfs.reaction_species)
|
212
212
|
defining_species = (
|
213
213
|
reaction_species[reaction_species[SBML_DFS.R_ID].isin(first_reactions)]
|
214
214
|
.query("sbo_role == 'DEFINING'")
|
tests/test_network_ig_utils.py
CHANGED
@@ -6,6 +6,15 @@ from napistu.network import ig_utils
|
|
6
6
|
from napistu.network import net_create
|
7
7
|
|
8
8
|
|
9
|
+
@pytest.fixture
|
10
|
+
def multi_component_graph() -> ig_utils.ig.Graph:
|
11
|
+
"""Creates a graph with multiple disconnected components of different sizes."""
|
12
|
+
g1 = ig_utils.ig.Graph.Ring(5) # 5 vertices, 5 edges
|
13
|
+
g2 = ig_utils.ig.Graph.Tree(3, 2) # 3 vertices, 2 edges
|
14
|
+
g3 = ig_utils.ig.Graph.Full(2) # 2 vertices, 1 edge
|
15
|
+
return ig_utils.ig.disjoint_union([g1, g2, g3])
|
16
|
+
|
17
|
+
|
9
18
|
def test_validate_graph_attributes(sbml_dfs):
|
10
19
|
|
11
20
|
napistu_graph = net_create.process_napistu_graph(
|
@@ -21,3 +30,30 @@ def test_validate_graph_attributes(sbml_dfs):
|
|
21
30
|
assert ig_utils.validate_vertex_attributes(napistu_graph, "node_type") is None
|
22
31
|
with pytest.raises(ValueError):
|
23
32
|
ig_utils.validate_vertex_attributes(napistu_graph, "baz")
|
33
|
+
|
34
|
+
|
35
|
+
def test_filter_to_largest_subgraph(multi_component_graph):
|
36
|
+
"""Tests that the function returns only the single largest component."""
|
37
|
+
largest = ig_utils.filter_to_largest_subgraph(multi_component_graph)
|
38
|
+
assert isinstance(largest, ig_utils.ig.Graph)
|
39
|
+
assert largest.vcount() == 5
|
40
|
+
assert largest.ecount() == 5
|
41
|
+
|
42
|
+
|
43
|
+
def test_filter_to_largest_subgraphs(multi_component_graph):
|
44
|
+
"""Tests that the function returns the top K largest components."""
|
45
|
+
# Test getting the top 2
|
46
|
+
top_2 = ig_utils.filter_to_largest_subgraphs(multi_component_graph, top_k=2)
|
47
|
+
assert isinstance(top_2, list)
|
48
|
+
assert len(top_2) == 2
|
49
|
+
assert all(isinstance(g, ig_utils.ig.Graph) for g in top_2)
|
50
|
+
assert [g.vcount() for g in top_2] == [5, 3]
|
51
|
+
|
52
|
+
# Test getting more than the total number of components
|
53
|
+
top_5 = ig_utils.filter_to_largest_subgraphs(multi_component_graph, top_k=5)
|
54
|
+
assert len(top_5) == 3
|
55
|
+
assert [g.vcount() for g in top_5] == [5, 3, 2]
|
56
|
+
|
57
|
+
# Test invalid top_k
|
58
|
+
with pytest.raises(ValueError):
|
59
|
+
ig_utils.filter_to_largest_subgraphs(multi_component_graph, top_k=0)
|
@@ -1,4 +1,6 @@
|
|
1
1
|
import pandas as pd
|
2
|
+
import pytest
|
3
|
+
|
2
4
|
from napistu.ontologies.genodexito import Genodexito
|
3
5
|
from napistu.ontologies.constants import (
|
4
6
|
GENODEXITO_DEFS,
|
@@ -7,6 +9,7 @@ from napistu.ontologies.constants import (
|
|
7
9
|
)
|
8
10
|
|
9
11
|
|
12
|
+
@pytest.skip_on_timeout(5)
|
10
13
|
def test_genodexito_mapping_operations():
|
11
14
|
"""Test Genodexito mapping table creation and operations."""
|
12
15
|
# Initialize with test mode and Python method to avoid R dependencies
|
tests/test_ontologies_mygene.py
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
import pytest
|
2
|
+
|
1
3
|
from napistu.ontologies.mygene import create_python_mapping_tables
|
2
4
|
from napistu.ontologies.constants import INTERCONVERTIBLE_GENIC_ONTOLOGIES
|
3
5
|
|
4
6
|
|
7
|
+
@pytest.skip_on_timeout(5)
|
5
8
|
def test_create_python_mapping_tables_yeast():
|
6
9
|
"""Test create_python_mapping_tables with yeast species."""
|
7
10
|
# Test with a subset of mappings to keep test runtime reasonable
|