pycode-kg 0.27.0__tar.gz → 0.28.0__tar.gz
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.
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/PKG-INFO +12 -12
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/README.md +6 -6
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/pyproject.toml +10 -28
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/__init__.py +1 -1
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_hooks.py +9 -2
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/mcp_server.py +19 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/LICENSE +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/.DS_Store +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/__main__.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/analysis/__init__.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/analysis/bridge.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/analysis/centrality.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/analysis/framework_detector.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/app.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/architecture.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/__init__.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_analyze.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_architecture.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_bridges.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_build.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_build_full.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_centrality.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_explain.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_framework_nodes.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_init.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_mcp.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_model.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_query.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_quilt.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_snapshot.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/cmd_viz.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/main.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/cli/options.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/config.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/explain.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/graph.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/graph_html.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/index.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/kg.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/layout3d.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/module/__init__.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/module/base.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/module/extractor.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/module/types.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/pycodekg.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/pycodekg_thorough_analysis.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/ranking/__init__.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/ranking/cli_rank.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/ranking/coderank.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/render.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/report.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/resolution.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/scene3d.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/snapshots.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/store.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/theme.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/utils.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/visitor.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/viz3d.py +0 -0
- {pycode_kg-0.27.0 → pycode_kg-0.28.0}/src/pycode_kg/viz3d_timeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycode-kg
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28.0
|
|
4
4
|
Summary: A tool to build a searchable knowledge graph from Python repositories
|
|
5
5
|
License-Expression: Elastic-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -21,11 +21,11 @@ Provides-Extra: viz3d
|
|
|
21
21
|
Requires-Dist: PyQt5 (>=5.15.0) ; extra == "all"
|
|
22
22
|
Requires-Dist: PyQt5 (>=5.15.0) ; extra == "viz3d"
|
|
23
23
|
Requires-Dist: click (>=8.1.0,<9)
|
|
24
|
-
Requires-Dist: kgmodule-utils[semantic,viz3d] (>=0.
|
|
25
|
-
Requires-Dist: kgmodule-utils[viz3d-qt,viz3d-render] (>=0.
|
|
24
|
+
Requires-Dist: kgmodule-utils[semantic,viz3d] (>=0.23.0)
|
|
25
|
+
Requires-Dist: kgmodule-utils[viz3d-qt,viz3d-render] (>=0.23.0) ; extra == "viz3d"
|
|
26
26
|
Requires-Dist: markdown (>=3.6) ; extra == "all"
|
|
27
27
|
Requires-Dist: markdown (>=3.6) ; extra == "viz3d"
|
|
28
|
-
Requires-Dist: mcp (>=1.
|
|
28
|
+
Requires-Dist: mcp (>=1.3.0,<2)
|
|
29
29
|
Requires-Dist: networkx (>=3.0)
|
|
30
30
|
Requires-Dist: numpy (>=1.24.0)
|
|
31
31
|
Requires-Dist: pandas (>=2.0.0)
|
|
@@ -38,8 +38,8 @@ Requires-Dist: pyvis (>=0.3.2) ; extra == "viz"
|
|
|
38
38
|
Requires-Dist: pyvista (>=0.44.0) ; extra == "all"
|
|
39
39
|
Requires-Dist: pyvistaqt (>=0.11.0) ; extra == "all"
|
|
40
40
|
Requires-Dist: pyvistaqt (>=0.11.0) ; extra == "viz3d"
|
|
41
|
-
Requires-Dist: quiltwright (>=0.
|
|
42
|
-
Requires-Dist: quiltwright (>=0.
|
|
41
|
+
Requires-Dist: quiltwright (>=0.15.0) ; extra == "all"
|
|
42
|
+
Requires-Dist: quiltwright (>=0.15.0) ; extra == "viz3d"
|
|
43
43
|
Requires-Dist: rich (>=14.3.3,<15)
|
|
44
44
|
Requires-Dist: sentence-transformers (>=5.4.1)
|
|
45
45
|
Requires-Dist: sqlite-vec (==0.1.9)
|
|
@@ -60,10 +60,10 @@ Description-Content-Type: text/markdown
|
|
|
60
60
|
|
|
61
61
|
[](https://www.python.org/)
|
|
62
62
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
63
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
64
64
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
65
65
|
[](https://python-poetry.org/)
|
|
66
|
-
[](https://doi.org/10.5281/zenodo.19737993)
|
|
67
67
|
|
|
68
68
|
# PyCodeKG — A Knowledge Graph for Python Codebases
|
|
69
69
|
|
|
@@ -255,7 +255,7 @@ src/pycode_kg/
|
|
|
255
255
|
└── viz3d_timeline.py # Metric history timeline
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
-
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.
|
|
258
|
+
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.28.0.md](docs/analysis_v0.28.0.md), produced (of course) by `pycodekg analyze` against this very repo.
|
|
259
259
|
|
|
260
260
|
---
|
|
261
261
|
|
|
@@ -280,15 +280,15 @@ The MCP server, the CLI, and the Streamlit app are thin wrappers over the same s
|
|
|
280
280
|
|
|
281
281
|
If you use PyCodeKG in your research or project, please cite it:
|
|
282
282
|
|
|
283
|
-
[](https://doi.org/10.5281/zenodo.19737993)
|
|
284
284
|
|
|
285
|
-
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.
|
|
285
|
+
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.28.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19737993
|
|
286
286
|
|
|
287
287
|
```bibtex
|
|
288
288
|
@software{suchanek_pycode_kg,
|
|
289
289
|
author = {Suchanek, Eric G.},
|
|
290
290
|
title = {{PyCodeKG}: A Knowledge Graph for Python Codebases},
|
|
291
|
-
version = {0.
|
|
291
|
+
version = {0.28.0},
|
|
292
292
|
year = {2026},
|
|
293
293
|
publisher = {Flux-Frontiers},
|
|
294
294
|
url = {https://github.com/Flux-Frontiers/pycode_kg},
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
[](https://www.python.org/)
|
|
7
7
|
[](https://www.elastic.co/licensing/elastic-license)
|
|
8
|
-
[](https://github.com/Flux-Frontiers/pycode_kg/releases)
|
|
9
9
|
[](https://github.com/Flux-Frontiers/pycode_kg/actions/workflows/ci.yml)
|
|
10
10
|
[](https://python-poetry.org/)
|
|
11
|
-
[](https://doi.org/10.5281/zenodo.19737993)
|
|
12
12
|
|
|
13
13
|
# PyCodeKG — A Knowledge Graph for Python Codebases
|
|
14
14
|
|
|
@@ -200,7 +200,7 @@ src/pycode_kg/
|
|
|
200
200
|
└── viz3d_timeline.py # Metric history timeline
|
|
201
201
|
```
|
|
202
202
|
|
|
203
|
-
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.
|
|
203
|
+
The MCP server, the CLI, and the Streamlit app are thin wrappers over the same store + index + ranking core — there is exactly one code path for each capability. The latest architectural deep-dive is in [docs/analysis_v0.28.0.md](docs/analysis_v0.28.0.md), produced (of course) by `pycodekg analyze` against this very repo.
|
|
204
204
|
|
|
205
205
|
---
|
|
206
206
|
|
|
@@ -225,15 +225,15 @@ The MCP server, the CLI, and the Streamlit app are thin wrappers over the same s
|
|
|
225
225
|
|
|
226
226
|
If you use PyCodeKG in your research or project, please cite it:
|
|
227
227
|
|
|
228
|
-
[](https://doi.org/10.5281/zenodo.19737993)
|
|
229
229
|
|
|
230
|
-
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.
|
|
230
|
+
> Suchanek, E. G. (2026). *PyCodeKG: A Knowledge Graph for Python Codebases* (Version 0.28.0) [Software]. Flux-Frontiers. https://doi.org/10.5281/zenodo.19737993
|
|
231
231
|
|
|
232
232
|
```bibtex
|
|
233
233
|
@software{suchanek_pycode_kg,
|
|
234
234
|
author = {Suchanek, Eric G.},
|
|
235
235
|
title = {{PyCodeKG}: A Knowledge Graph for Python Codebases},
|
|
236
|
-
version = {0.
|
|
236
|
+
version = {0.28.0},
|
|
237
237
|
year = {2026},
|
|
238
238
|
publisher = {Flux-Frontiers},
|
|
239
239
|
url = {https://github.com/Flux-Frontiers/pycode_kg},
|
|
@@ -70,7 +70,7 @@ torch = [
|
|
|
70
70
|
# ---------------------------------------------------------------------------
|
|
71
71
|
[project]
|
|
72
72
|
name = "pycode-kg"
|
|
73
|
-
version = "0.
|
|
73
|
+
version = "0.28.0"
|
|
74
74
|
description = "A tool to build a searchable knowledge graph from Python repositories"
|
|
75
75
|
readme = "README.md"
|
|
76
76
|
license = "Elastic-2.0"
|
|
@@ -96,7 +96,7 @@ dependencies = [
|
|
|
96
96
|
# FastMCP from mcp, so an unbounded floor lets a clean install pull 2.x and
|
|
97
97
|
# break `pycodekg-mcp` at import time. Lift this only alongside a port to
|
|
98
98
|
# the standalone fastmcp package.
|
|
99
|
-
"mcp>=1.
|
|
99
|
+
"mcp>=1.3.0,<2",
|
|
100
100
|
"networkx>=3.0",
|
|
101
101
|
"numpy>=1.24.0",
|
|
102
102
|
"pandas>=2.0.0",
|
|
@@ -169,7 +169,7 @@ dependencies = [
|
|
|
169
169
|
# and the _domain_metrics() hook, none of which exist before 0.20.0.
|
|
170
170
|
# Against 0.19.x the manager silently reports itself as "kg-utils" and
|
|
171
171
|
# drops module_node_counts entirely.
|
|
172
|
-
"kgmodule-utils[semantic,viz3d]>=0.
|
|
172
|
+
"kgmodule-utils[semantic,viz3d]>=0.23.0",
|
|
173
173
|
]
|
|
174
174
|
|
|
175
175
|
[project.optional-dependencies]
|
|
@@ -194,14 +194,17 @@ viz3d = [
|
|
|
194
194
|
# the four-step build/render/write/cast itself. It subsumes [viz3d-render]
|
|
195
195
|
# (it declares pyvista too), but both are named so the dependency reads as
|
|
196
196
|
# what it is rather than as a side effect.
|
|
197
|
-
"kgmodule-utils[viz3d-render,viz3d-qt]>=0.
|
|
197
|
+
"kgmodule-utils[viz3d-render,viz3d-qt]>=0.23.0",
|
|
198
198
|
"pyvistaqt>=0.11.0",
|
|
199
199
|
"trame-vtk>=2.0.0",
|
|
200
200
|
# Looking Glass quilts. 0.4.0 supplies depth_report() and widened
|
|
201
201
|
# requires-python to <3.14, which retires the old marker gate. 0.6.0 adds
|
|
202
202
|
# QuiltSpec.scaled(), which replaces the tile-grid rounding this repo used
|
|
203
203
|
# to open-code, and save_and_cast_quilt() underneath the SDK cast helper.
|
|
204
|
-
|
|
204
|
+
# 0.14.1 is what kgmodule-utils[viz3d-qt] >=0.22.0 needs transitively, for
|
|
205
|
+
# resolve_view_cone; declared here so this file states the real floor
|
|
206
|
+
# rather than leaving it to the resolver to discover.
|
|
207
|
+
"quiltwright>=0.15.0",
|
|
205
208
|
]
|
|
206
209
|
|
|
207
210
|
# Cross-KG sibling packages (doc-kg, pycode-kg, agent-kg, kg-rag) are NOT
|
|
@@ -226,7 +229,7 @@ all = [
|
|
|
226
229
|
"pyvis>=0.3.2",
|
|
227
230
|
"pyvista>=0.44.0",
|
|
228
231
|
"pyvistaqt>=0.11.0",
|
|
229
|
-
"quiltwright>=0.
|
|
232
|
+
"quiltwright>=0.15.0",
|
|
230
233
|
"streamlit>=1.56.0",
|
|
231
234
|
"trame-vtk>=2.0.0",
|
|
232
235
|
]
|
|
@@ -246,30 +249,9 @@ pdoc = ">=14.0.0"
|
|
|
246
249
|
pre-commit = ">=4.5.1"
|
|
247
250
|
pytest = ">=9.0.3"
|
|
248
251
|
pytest-cov = ">=5.0.0"
|
|
249
|
-
ruff = ">=0.
|
|
252
|
+
ruff = ">=0.15,<0.16"
|
|
250
253
|
ty = ">=0.0.41"
|
|
251
254
|
|
|
252
|
-
# Maintainer tooling, not a dependency of this package. `.mcp.json` serves a
|
|
253
|
-
# `dockg` MCP server from `.venv/bin/dockg`, so the CLI has to be in this repo's
|
|
254
|
-
# environment — but nothing under src/ imports doc_kg, and declaring it as a real
|
|
255
|
-
# dependency would put it in the published wheel for every consumer.
|
|
256
|
-
#
|
|
257
|
-
# A Poetry group is the right shape: it is locked and installable but never
|
|
258
|
-
# written into wheel metadata, so `pip install pycode-kg` is unaffected.
|
|
259
|
-
#
|
|
260
|
-
# poetry install --with kg # gets the dockg CLI into .venv/bin
|
|
261
|
-
# poetry install # default — the group is optional, skipped
|
|
262
|
-
#
|
|
263
|
-
# `kg` is the fleet-wide name for this group so there is one command to remember;
|
|
264
|
-
# contents are per-repo and minimal, covering only what that repo actually
|
|
265
|
-
# invokes. Safe to lock because doc-kg keeps its own pycode-kg in a group too, so
|
|
266
|
-
# the published metadata on either side has no cycle for the resolver to chase.
|
|
267
|
-
[tool.poetry.group.kg]
|
|
268
|
-
optional = true
|
|
269
|
-
|
|
270
|
-
[tool.poetry.group.kg.dependencies]
|
|
271
|
-
doc-kg = ">=0.22.0"
|
|
272
|
-
|
|
273
255
|
[project.urls]
|
|
274
256
|
Homepage = "https://github.com/Flux-Frontiers/pycode_kg"
|
|
275
257
|
Repository = "https://github.com/Flux-Frontiers/pycode_kg"
|
|
@@ -105,10 +105,17 @@ DEFAULT_BRANCH="${DEFAULT_BRANCH#origin/}"
|
|
|
105
105
|
[ "$BRANCH" != "${DEFAULT_BRANCH:-main}" ] && exit 0
|
|
106
106
|
|
|
107
107
|
# Rebuild the local index to keep it in sync with staged content.
|
|
108
|
-
|
|
108
|
+
# pycodekg is a tool this repo runs, not a dependency it declares: the fleet
|
|
109
|
+
# installs it once, globally (uv tool install pycode-kg), so PATH is the normal
|
|
110
|
+
# case. A .venv copy is honoured if present, for a checkout that still has one.
|
|
111
|
+
PYCODEKG="$(command -v pycodekg 2>/dev/null || true)"
|
|
112
|
+
[ -n "$PYCODEKG" ] || PYCODEKG="$REPO_ROOT/.venv/bin/pycodekg"
|
|
113
|
+
[ -x "$PYCODEKG" ] || { echo "[pycodekg] not found on PATH or in .venv; uv tool install pycode-kg" >&2; exit 1; }
|
|
114
|
+
|
|
115
|
+
"$PYCODEKG" build --repo "$REPO_ROOT" || exit 1
|
|
109
116
|
|
|
110
117
|
# Snapshot PyCodeKG (version auto-detected from installed package).
|
|
111
|
-
"$
|
|
118
|
+
"$PYCODEKG" snapshot save \\
|
|
112
119
|
--repo . \\
|
|
113
120
|
--tree-hash "$TREE_HASH" \\
|
|
114
121
|
--branch "$BRANCH" \\
|
|
@@ -142,6 +142,8 @@ from __future__ import annotations
|
|
|
142
142
|
import argparse
|
|
143
143
|
import json
|
|
144
144
|
import sys
|
|
145
|
+
from collections.abc import AsyncIterator
|
|
146
|
+
from contextlib import asynccontextmanager
|
|
145
147
|
from pathlib import Path
|
|
146
148
|
|
|
147
149
|
from mcp.server.fastmcp import FastMCP
|
|
@@ -266,6 +268,22 @@ def _snapshot_freshness(snapshot_total_nodes: int) -> dict:
|
|
|
266
268
|
# MCP server
|
|
267
269
|
# ---------------------------------------------------------------------------
|
|
268
270
|
|
|
271
|
+
|
|
272
|
+
@asynccontextmanager
|
|
273
|
+
async def _lifespan(_server: FastMCP) -> AsyncIterator[None]:
|
|
274
|
+
"""Close the graph's SQLite connection(s) when the server shuts down.
|
|
275
|
+
|
|
276
|
+
``main()`` sets the module-level ``_kg`` before ``mcp.run()`` calls into
|
|
277
|
+
this, and both the stdio and SSE transports route through the same
|
|
278
|
+
underlying ``Server.run()``, so this fires on either one.
|
|
279
|
+
"""
|
|
280
|
+
try:
|
|
281
|
+
yield
|
|
282
|
+
finally:
|
|
283
|
+
if _kg is not None:
|
|
284
|
+
_kg.close()
|
|
285
|
+
|
|
286
|
+
|
|
269
287
|
mcp = FastMCP(
|
|
270
288
|
"pycodekg",
|
|
271
289
|
instructions=(
|
|
@@ -396,6 +414,7 @@ mcp = FastMCP(
|
|
|
396
414
|
"- **Structure-aware query**: query_ranked(q='database connection', mode='hybrid')\n"
|
|
397
415
|
"- **PPR query**: query_ranked(q='...', mode='ppr') → explain_rank(node_id, q='...')"
|
|
398
416
|
),
|
|
417
|
+
lifespan=_lifespan,
|
|
399
418
|
)
|
|
400
419
|
|
|
401
420
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|