napistu 0.2.5.dev7__py3-none-any.whl → 0.3.1.dev1__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/__init__.py +1 -3
- 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.dev1.dist-info}/METADATA +8 -3
- napistu-0.3.1.dev1.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.dev1.dist-info}/WHEEL +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/entry_points.txt +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/licenses/LICENSE +0 -0
- {napistu-0.2.5.dev7.dist-info → napistu-0.3.1.dev1.dist-info}/top_level.txt +0 -0
- /tests/{test_obo.py → test_ingestion_obo.py} +0 -0
napistu/mcp/config.py
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
from pydantic import BaseModel, Field, computed_field, validator
|
2
|
+
from typing import Optional
|
3
|
+
import click
|
4
|
+
from napistu.mcp.constants import MCP_DEFAULTS, MCP_PRODUCTION_URL
|
5
|
+
|
6
|
+
|
7
|
+
class MCPServerConfig(BaseModel):
|
8
|
+
"""Server-side MCP configuration with validation."""
|
9
|
+
|
10
|
+
host: str = Field(description="Host to bind server to")
|
11
|
+
port: int = Field(ge=1, le=65535, description="Port to bind server to")
|
12
|
+
server_name: str = Field(description="Server name")
|
13
|
+
|
14
|
+
@validator("host")
|
15
|
+
def validate_host(cls, v):
|
16
|
+
"""Basic host validation."""
|
17
|
+
if not v or v.isspace():
|
18
|
+
raise ValueError("Host cannot be empty")
|
19
|
+
return v.strip()
|
20
|
+
|
21
|
+
@computed_field
|
22
|
+
@property
|
23
|
+
def bind_address(self) -> str:
|
24
|
+
"""Full address for server binding."""
|
25
|
+
return f"{self.host}:{self.port}"
|
26
|
+
|
27
|
+
|
28
|
+
class MCPClientConfig(BaseModel):
|
29
|
+
"""Client-side MCP configuration with validation."""
|
30
|
+
|
31
|
+
host: str = Field(description="Target server host")
|
32
|
+
port: int = Field(ge=1, le=65535, description="Target server port")
|
33
|
+
use_https: bool = Field(description="Use HTTPS instead of HTTP")
|
34
|
+
|
35
|
+
@computed_field
|
36
|
+
@property
|
37
|
+
def base_url(self) -> str:
|
38
|
+
"""Base URL for HTTP requests."""
|
39
|
+
protocol = "https" if self.use_https else "http"
|
40
|
+
return f"{protocol}://{self.host}:{self.port}"
|
41
|
+
|
42
|
+
@computed_field
|
43
|
+
@property
|
44
|
+
def mcp_url(self) -> str:
|
45
|
+
"""Full MCP endpoint URL."""
|
46
|
+
return f"{self.base_url}{MCP_DEFAULTS.MCP_PATH}"
|
47
|
+
|
48
|
+
|
49
|
+
# Preset configurations - no overrides needed
|
50
|
+
def local_server_config() -> MCPServerConfig:
|
51
|
+
"""Local development server configuration."""
|
52
|
+
return MCPServerConfig(
|
53
|
+
host=MCP_DEFAULTS.LOCAL_HOST,
|
54
|
+
port=MCP_DEFAULTS.LOCAL_PORT,
|
55
|
+
server_name=MCP_DEFAULTS.LOCAL_SERVER_NAME,
|
56
|
+
)
|
57
|
+
|
58
|
+
|
59
|
+
def production_server_config() -> MCPServerConfig:
|
60
|
+
"""Production server configuration."""
|
61
|
+
return MCPServerConfig(
|
62
|
+
host=MCP_DEFAULTS.PRODUCTION_HOST,
|
63
|
+
port=MCP_DEFAULTS.PRODUCTION_PORT,
|
64
|
+
server_name=MCP_DEFAULTS.PRODUCTION_SERVER_NAME,
|
65
|
+
)
|
66
|
+
|
67
|
+
|
68
|
+
def local_client_config() -> MCPClientConfig:
|
69
|
+
"""Local development client configuration."""
|
70
|
+
return MCPClientConfig(
|
71
|
+
host=MCP_DEFAULTS.LOCAL_HOST, port=MCP_DEFAULTS.LOCAL_PORT, use_https=False
|
72
|
+
)
|
73
|
+
|
74
|
+
|
75
|
+
def production_client_config() -> MCPClientConfig:
|
76
|
+
"""Production client configuration."""
|
77
|
+
# Parse production URL to extract host
|
78
|
+
production_host = MCP_PRODUCTION_URL.replace("https://", "").split("/")[0]
|
79
|
+
return MCPClientConfig(
|
80
|
+
host=production_host, port=MCP_DEFAULTS.HTTPS_PORT, use_https=True
|
81
|
+
)
|
82
|
+
|
83
|
+
|
84
|
+
# Utility functions for CLI validation
|
85
|
+
def validate_server_config_flags(
|
86
|
+
local: bool,
|
87
|
+
production: bool,
|
88
|
+
host: Optional[str],
|
89
|
+
port: Optional[int],
|
90
|
+
server_name: Optional[str],
|
91
|
+
) -> MCPServerConfig:
|
92
|
+
"""
|
93
|
+
Validate server configuration flags and return appropriate config.
|
94
|
+
|
95
|
+
Raises click.BadParameter if incompatible flags are used.
|
96
|
+
"""
|
97
|
+
# Check for mutually exclusive presets
|
98
|
+
if local and production:
|
99
|
+
raise click.BadParameter("Cannot use both --local and --production flags")
|
100
|
+
|
101
|
+
# Check for preset + manual config conflicts
|
102
|
+
preset_used = local or production
|
103
|
+
manual_config_used = any(
|
104
|
+
[host is not None, port is not None, server_name is not None]
|
105
|
+
)
|
106
|
+
|
107
|
+
if preset_used and manual_config_used:
|
108
|
+
preset_name = "local" if local else "production"
|
109
|
+
raise click.BadParameter(
|
110
|
+
f"Cannot use --{preset_name} with manual host/port/server-name configuration. "
|
111
|
+
f"Use either preset flags OR manual configuration, not both."
|
112
|
+
)
|
113
|
+
|
114
|
+
# Return appropriate config
|
115
|
+
if local:
|
116
|
+
return local_server_config()
|
117
|
+
elif production:
|
118
|
+
return production_server_config()
|
119
|
+
else:
|
120
|
+
# Manual configuration - all required
|
121
|
+
if not all([host, port, server_name]):
|
122
|
+
raise click.BadParameter(
|
123
|
+
"Manual configuration requires --host, --port, and --server-name"
|
124
|
+
)
|
125
|
+
return MCPServerConfig(host=host, port=port, server_name=server_name)
|
126
|
+
|
127
|
+
|
128
|
+
def validate_client_config_flags(
|
129
|
+
local: bool,
|
130
|
+
production: bool,
|
131
|
+
host: Optional[str],
|
132
|
+
port: Optional[int],
|
133
|
+
use_https: Optional[bool],
|
134
|
+
) -> MCPClientConfig:
|
135
|
+
"""
|
136
|
+
Validate client configuration flags and return appropriate config.
|
137
|
+
|
138
|
+
Raises click.BadParameter if incompatible flags are used.
|
139
|
+
"""
|
140
|
+
# Check for mutually exclusive presets
|
141
|
+
if local and production:
|
142
|
+
raise click.BadParameter("Cannot use both --local and --production flags")
|
143
|
+
|
144
|
+
# Check for preset + manual config conflicts
|
145
|
+
preset_used = local or production
|
146
|
+
manual_config_used = any(
|
147
|
+
[host is not None, port is not None, use_https is not None]
|
148
|
+
)
|
149
|
+
|
150
|
+
if preset_used and manual_config_used:
|
151
|
+
preset_name = "local" if local else "production"
|
152
|
+
raise click.BadParameter(
|
153
|
+
f"Cannot use --{preset_name} with manual host/port/https configuration. "
|
154
|
+
f"Use either preset flags OR manual configuration, not both."
|
155
|
+
)
|
156
|
+
|
157
|
+
# Return appropriate config
|
158
|
+
if local:
|
159
|
+
return local_client_config()
|
160
|
+
elif production:
|
161
|
+
return production_client_config()
|
162
|
+
else:
|
163
|
+
# Manual configuration - all required
|
164
|
+
if not all([host is not None, port is not None, use_https is not None]):
|
165
|
+
raise click.BadParameter(
|
166
|
+
"Manual configuration requires --host, --port, and --https"
|
167
|
+
)
|
168
|
+
return MCPClientConfig(host=host, port=port, use_https=use_https)
|
169
|
+
|
170
|
+
|
171
|
+
# Click option decorators for reuse
|
172
|
+
def server_config_options(f):
|
173
|
+
"""Decorator to add server configuration options to click commands."""
|
174
|
+
f = click.option(
|
175
|
+
"--production", is_flag=True, help="Use production server configuration"
|
176
|
+
)(f)
|
177
|
+
f = click.option(
|
178
|
+
"--local", is_flag=True, help="Use local development server configuration"
|
179
|
+
)(f)
|
180
|
+
f = click.option(
|
181
|
+
"--host",
|
182
|
+
type=str,
|
183
|
+
help="Host to bind server to (requires --port and --server-name)",
|
184
|
+
)(f)
|
185
|
+
f = click.option(
|
186
|
+
"--port",
|
187
|
+
type=int,
|
188
|
+
help="Port to bind server to (requires --host and --server-name)",
|
189
|
+
)(f)
|
190
|
+
f = click.option(
|
191
|
+
"--server-name", type=str, help="Server name (requires --host and --port)"
|
192
|
+
)(f)
|
193
|
+
return f
|
194
|
+
|
195
|
+
|
196
|
+
def client_config_options(f):
|
197
|
+
"""Decorator to add client configuration options to click commands."""
|
198
|
+
f = click.option("--production", is_flag=True, help="Connect to production server")(
|
199
|
+
f
|
200
|
+
)
|
201
|
+
f = click.option(
|
202
|
+
"--local", is_flag=True, help="Connect to local development server"
|
203
|
+
)(f)
|
204
|
+
f = click.option(
|
205
|
+
"--host",
|
206
|
+
type=str,
|
207
|
+
default=None,
|
208
|
+
help="Server host (requires --port and --https)",
|
209
|
+
)(f)
|
210
|
+
f = click.option(
|
211
|
+
"--port",
|
212
|
+
type=int,
|
213
|
+
default=None,
|
214
|
+
help="Server port (requires --host and --https)",
|
215
|
+
)(f)
|
216
|
+
f = click.option(
|
217
|
+
"--https",
|
218
|
+
is_flag=True,
|
219
|
+
default=None,
|
220
|
+
flag_value=True,
|
221
|
+
help="Use HTTPS (requires --host and --port)",
|
222
|
+
)(f)
|
223
|
+
return f
|
napistu/mcp/constants.py
CHANGED
@@ -31,6 +31,36 @@ TOOL_VARS = SimpleNamespace(
|
|
31
31
|
SNIPPET="snippet",
|
32
32
|
)
|
33
33
|
|
34
|
+
# MCP Server Configuration Constants
|
35
|
+
MCP_DEFAULTS = SimpleNamespace(
|
36
|
+
# Local development defaults
|
37
|
+
LOCAL_HOST="127.0.0.1",
|
38
|
+
LOCAL_PORT=8765,
|
39
|
+
# Production defaults
|
40
|
+
PRODUCTION_HOST="0.0.0.0",
|
41
|
+
PRODUCTION_PORT=8080,
|
42
|
+
# Server names
|
43
|
+
LOCAL_SERVER_NAME="napistu-local",
|
44
|
+
PRODUCTION_SERVER_NAME="napistu-production",
|
45
|
+
FULL_SERVER_NAME="napistu-full",
|
46
|
+
# Transport configuration
|
47
|
+
TRANSPORT="streamable-http",
|
48
|
+
MCP_PATH="/mcp",
|
49
|
+
# Standard protocol ports
|
50
|
+
HTTP_PORT=80,
|
51
|
+
HTTPS_PORT=443,
|
52
|
+
)
|
53
|
+
|
54
|
+
# Production server URL
|
55
|
+
MCP_PRODUCTION_URL = "https://napistu-mcp-server-844820030839.us-west1.run.app"
|
56
|
+
|
57
|
+
# Profile names (component configurations)
|
58
|
+
MCP_PROFILES = SimpleNamespace(
|
59
|
+
EXECUTION="execution", # execution only
|
60
|
+
DOCS="docs", # docs + codebase + tutorials
|
61
|
+
FULL="full", # all components
|
62
|
+
)
|
63
|
+
|
34
64
|
READMES = {
|
35
65
|
"napistu": "https://raw.githubusercontent.com/napistu/napistu/main/README.md",
|
36
66
|
"napistu-py": "https://raw.githubusercontent.com/napistu/napistu-py/main/README.md",
|
@@ -38,7 +68,20 @@ READMES = {
|
|
38
68
|
"napistu/tutorials": "https://raw.githubusercontent.com/napistu/napistu/main/tutorials/README.md",
|
39
69
|
}
|
40
70
|
|
41
|
-
|
71
|
+
WIKI_PAGES = {
|
72
|
+
"Consensus",
|
73
|
+
"Data-Sources",
|
74
|
+
"Napistu-Graphs",
|
75
|
+
"Dev-Zone",
|
76
|
+
"Environment-Setup",
|
77
|
+
"Exploring-Molecular-Relationships-as-Networks",
|
78
|
+
"GitHub-Actions-napistu‐py",
|
79
|
+
"History",
|
80
|
+
"Model-Context-Protocol-(MCP)-server",
|
81
|
+
"Precomputed-distances",
|
82
|
+
"SBML",
|
83
|
+
"SBML-DFs",
|
84
|
+
}
|
42
85
|
|
43
86
|
NAPISTU_PY_READTHEDOCS = "https://napistu.readthedocs.io/en/latest"
|
44
87
|
NAPISTU_PY_READTHEDOCS_API = NAPISTU_PY_READTHEDOCS + "/api.html"
|
@@ -61,7 +104,7 @@ REPOS_WITH_WIKI = [PACKAGE_DEFS.GITHUB_PROJECT_REPO]
|
|
61
104
|
TUTORIAL_URLS = {
|
62
105
|
"adding_data_to_graphs": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/adding_data_to_graphs.ipynb",
|
63
106
|
"downloading_pathway_data": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/downloading_pathway_data.ipynb",
|
64
|
-
"
|
107
|
+
"creating_a_napistu_graph": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/creating_a_napistu_graph.ipynb",
|
65
108
|
"merging_models_into_a_consensus": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/merging_models_into_a_consensus.ipynb",
|
66
109
|
"r_based_network_visualization": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/r_based_network_visualization.ipynb",
|
67
110
|
"suggesting_mechanisms_with_networks": "https://raw.githubusercontent.com/napistu/napistu/refs/heads/main/tutorials/suggesting_mechanisms_with_networks.ipynb",
|