pycode-kg 0.16.0__tar.gz → 0.17.1__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.
Files changed (63) hide show
  1. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/PKG-INFO +2 -2
  2. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/pyproject.toml +16 -2
  3. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/__init__.py +1 -1
  4. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_init.py +7 -22
  5. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/index.py +47 -14
  6. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg.py +3 -7
  7. pycode_kg-0.17.1/src/pycode_kg/snapshots.py +504 -0
  8. pycode_kg-0.16.0/src/pycode_kg/snapshots.py +0 -612
  9. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/LICENSE +0 -0
  10. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/README.md +0 -0
  11. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/.DS_Store +0 -0
  12. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/__main__.py +0 -0
  13. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/analysis/__init__.py +0 -0
  14. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/analysis/bridge.py +0 -0
  15. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/analysis/centrality.py +0 -0
  16. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/analysis/framework_detector.py +0 -0
  17. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/analysis/hybrid_rank.py +0 -0
  18. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/app.py +0 -0
  19. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/architecture.py +0 -0
  20. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/build_pycodekg_lancedb.py +0 -0
  21. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/build_pycodekg_sqlite.py +0 -0
  22. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/__init__.py +0 -0
  23. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_analyze.py +0 -0
  24. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_architecture.py +0 -0
  25. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_bridges.py +0 -0
  26. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_build.py +0 -0
  27. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_build_full.py +0 -0
  28. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_centrality.py +0 -0
  29. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_explain.py +0 -0
  30. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_framework_nodes.py +0 -0
  31. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_hooks.py +0 -0
  32. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_mcp.py +0 -0
  33. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_model.py +0 -0
  34. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_query.py +0 -0
  35. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_snapshot.py +0 -0
  36. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/cmd_viz.py +0 -0
  37. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/main.py +0 -0
  38. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/cli/options.py +0 -0
  39. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/config.py +0 -0
  40. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/graph.py +0 -0
  41. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/kg.py +0 -0
  42. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/layout3d.py +0 -0
  43. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/mcp/bridge_tools.py +0 -0
  44. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/mcp/framework_tools.py +0 -0
  45. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/mcp_server.py +0 -0
  46. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/module/__init__.py +0 -0
  47. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/module/base.py +0 -0
  48. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/module/extractor.py +0 -0
  49. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/module/types.py +0 -0
  50. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg_query.py +0 -0
  51. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg_snippet_packer.py +0 -0
  52. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg_thorough_analysis.py +0 -0
  53. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg_viz.py +0 -0
  54. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/pycodekg_viz3d.py +0 -0
  55. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/ranking/__init__.py +0 -0
  56. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/ranking/cli_rank.py +0 -0
  57. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/ranking/coderank.py +0 -0
  58. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/sql/004_add_centrality_table.sql +0 -0
  59. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/store.py +0 -0
  60. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/utils.py +0 -0
  61. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/visitor.py +0 -0
  62. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/src/pycode_kg/viz3d.py +0 -0
  63. {pycode_kg-0.16.0 → pycode_kg-0.17.1}/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.16.0
3
+ Version: 0.17.1
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
@@ -27,7 +27,7 @@ Requires-Dist: detect-secrets (>=1.5.0) ; extra == "all"
27
27
  Requires-Dist: detect-secrets (>=1.5.0) ; extra == "dev"
28
28
  Requires-Dist: doc-kg (>=0.11.0) ; extra == "dev"
29
29
  Requires-Dist: doc-kg (>=0.11.0) ; extra == "kgdeps"
30
- Requires-Dist: kg-snapshot (>=0.3.0)
30
+ Requires-Dist: kgmodule-utils (>=0.2.1)
31
31
  Requires-Dist: lancedb (>=0.29.0)
32
32
  Requires-Dist: markdown (>=3.6) ; extra == "all"
33
33
  Requires-Dist: markdown (>=3.6) ; extra == "viz3d"
@@ -51,12 +51,22 @@ priority = "supplemental"
51
51
  [tool.poetry]
52
52
  packages = [{ include = "pycode_kg", from = "src" }]
53
53
 
54
+ [tool.poetry.group.dev.dependencies]
55
+ detect-secrets = ">=1.5.0"
56
+ mypy = ">=1.10.0"
57
+ pdoc = ">=14.0.0"
58
+ pre-commit = ">=4.5.1"
59
+ pylint = ">=4.0.5"
60
+ pytest = ">=8.0.0"
61
+ pytest-cov = ">=5.0.0"
62
+ ruff = ">=0.4.0"
63
+
54
64
  # ---------------------------------------------------------------------------
55
65
  # PEP 621 project metadata
56
66
  # ---------------------------------------------------------------------------
57
67
  [project]
58
68
  name = "pycode-kg"
59
- version = "0.16.0"
69
+ version = "0.17.1"
60
70
  description = "A tool to build a searchable knowledge graph from Python repositories"
61
71
  readme = "README.md"
62
72
  license = "Elastic-2.0"
@@ -85,7 +95,7 @@ dependencies = [
85
95
  "sentence-transformers>=5.4.1",
86
96
  "torch>=2.5.1",
87
97
  "transformers>=4.57.6",
88
- "kg-snapshot>=0.3.0",
98
+ "kgmodule-utils>=0.2.1",
89
99
  ]
90
100
 
91
101
  [project.optional-dependencies]
@@ -183,6 +193,10 @@ explicit_package_bases = true
183
193
  [tool.pytest.ini_options]
184
194
  testpaths = ["tests"]
185
195
  addopts = "-v --tb=short"
196
+ markers = [
197
+ "slow: marks tests as slow (deselect with '-m not slow')",
198
+ "integration: marks tests that exercise real external dependencies (model, LanceDB)",
199
+ ]
186
200
 
187
201
  [tool.pylint.messages_control]
188
202
  disable = ["all"]
@@ -32,7 +32,7 @@ KGModule SDK (build new domain KGs)::
32
32
  from pycode_kg import KGModule, KGExtractor, PyCodeKGExtractor, NodeSpec, EdgeSpec
33
33
  """
34
34
 
35
- __version__ = "0.16.0"
35
+ __version__ = "0.17.1"
36
36
  __author__ = "Eric G. Suchanek, PhD"
37
37
 
38
38
  # Low-level primitives (locked v0 contract)
@@ -10,6 +10,7 @@ CLI command for initializing PyCodeKG in a repository:
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import importlib.metadata
13
14
  import stat
14
15
  import subprocess
15
16
  import time
@@ -18,6 +19,8 @@ from pathlib import Path
18
19
 
19
20
  import click
20
21
 
22
+ from pycode_kg.cli.cmd_build_full import _run_pipeline
23
+ from pycode_kg.cli.cmd_hooks import _PRE_COMMIT_HOOK
21
24
  from pycode_kg.cli.main import cli
22
25
  from pycode_kg.cli.options import (
23
26
  exclude_option,
@@ -26,6 +29,10 @@ from pycode_kg.cli.options import (
26
29
  repo_option,
27
30
  )
28
31
  from pycode_kg.index import _local_model_path
32
+ from pycode_kg.kg import PyCodeKG
33
+ from pycode_kg.pycodekg_thorough_analysis import PyCodeKGAnalyzer
34
+ from pycode_kg.snapshots import SnapshotManager
35
+ from pycode_kg.store import GraphStore
29
36
 
30
37
 
31
38
  def _has_pycodekg_config(repo_root: Path) -> bool:
@@ -109,13 +116,6 @@ def init(
109
116
 
110
117
  pycodekg init --repo .
111
118
  """
112
- from pycode_kg.cli.cmd_build_full import (
113
- _run_pipeline, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
114
- )
115
- from pycode_kg.cli.cmd_hooks import (
116
- _PRE_COMMIT_HOOK, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
117
- )
118
-
119
119
  repo_root = Path(repo).resolve()
120
120
  t_total = time.monotonic()
121
121
 
@@ -229,21 +229,6 @@ def init(
229
229
  branch = "unknown"
230
230
 
231
231
  try:
232
- import importlib.metadata # noqa: PLC0415 # pylint: disable=import-outside-toplevel
233
-
234
- from pycode_kg.kg import (
235
- PyCodeKG, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
236
- )
237
- from pycode_kg.pycodekg_thorough_analysis import (
238
- PyCodeKGAnalyzer, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
239
- )
240
- from pycode_kg.snapshots import (
241
- SnapshotManager, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
242
- )
243
- from pycode_kg.store import (
244
- GraphStore, # noqa: PLC0415 # pylint: disable=import-outside-toplevel
245
- )
246
-
247
232
  db_path = repo_root / ".pycodekg" / "graph.sqlite"
248
233
  snapshots_path = repo_root / ".pycodekg" / "snapshots"
249
234
  lancedb_dir = repo_root / ".pycodekg" / "lancedb"
@@ -23,7 +23,47 @@ from typing import TYPE_CHECKING
23
23
 
24
24
  import numpy as np
25
25
 
26
- from pycode_kg.pycodekg import DEFAULT_MODEL
26
+ # ---------------------------------------------------------------------------
27
+ # Vendored from kg_utils.embed (pure stdlib — no PyPI package available yet)
28
+ # ---------------------------------------------------------------------------
29
+
30
+ DEFAULT_MODEL: str = "BAAI/bge-small-en-v1.5"
31
+
32
+ _KNOWN_MODELS: dict[str, str] = {
33
+ "default": "BAAI/bge-small-en-v1.5",
34
+ "bge-small": "BAAI/bge-small-en-v1.5",
35
+ "bge-small-en-v1.5": "BAAI/bge-small-en-v1.5",
36
+ "bge-large": "BAAI/bge-large-en-v1.5",
37
+ "bge-large-en-v1.5": "BAAI/bge-large-en-v1.5",
38
+ "all-MiniLM-L6-v2": "sentence-transformers/all-MiniLM-L6-v2",
39
+ "all-mpnet-base-v2": "sentence-transformers/all-mpnet-base-v2",
40
+ "nomic": "nomic-ai/nomic-embed-text-v1.5",
41
+ "nomic-v1.5": "nomic-ai/nomic-embed-text-v1.5",
42
+ }
43
+
44
+
45
+ def _kg_model_cache_dir() -> Path:
46
+ env = os.environ.get("KGRAG_MODEL_DIR")
47
+ if env:
48
+ return Path(env).resolve()
49
+ return Path.home() / ".kgrag" / "models"
50
+
51
+
52
+ def resolve_model_path(model_name: str, local_fallback: Path | None = None) -> Path:
53
+ """Return the local cache path for *model_name*.
54
+
55
+ Checks ``KGRAG_MODEL_DIR`` first (system-wide override), then
56
+ *local_fallback* if provided, otherwise ``~/.kgrag/models/``.
57
+
58
+ :param model_name: HuggingFace model identifier or short alias.
59
+ :param local_fallback: Per-module fallback when no env var is set.
60
+ :return: Absolute :class:`~pathlib.Path` to the model directory.
61
+ """
62
+ resolved = _KNOWN_MODELS.get(model_name, model_name)
63
+ if os.environ.get("KGRAG_MODEL_DIR") or local_fallback is None:
64
+ return _kg_model_cache_dir() / resolved.replace("/", os.sep)
65
+ return local_fallback / resolved.replace("/", "--")
66
+
27
67
 
28
68
  # ---------------------------------------------------------------------------
29
69
  # Local model cache
@@ -33,22 +73,13 @@ from pycode_kg.pycodekg import DEFAULT_MODEL
33
73
  def _local_model_path(model_name: str) -> Path:
34
74
  """Return the local cache path for *model_name*.
35
75
 
36
- Defaults to ``.pycodekg/models/<model>`` under the current working directory
37
- so the cache lives alongside the rest of the PyCodeKG artefacts.
38
- Override via the ``PYCODEKG_MODEL_DIR`` environment variable.
39
-
40
- Slashes in the model name (e.g. ``org/model``) are replaced with ``--``
41
- so the path is always a single directory level under the cache root.
76
+ Checks ``KGRAG_MODEL_DIR`` first (system-wide override), then falls back
77
+ to ``.pycodekg/models/`` under the current working directory.
42
78
 
43
- :param model_name: HuggingFace model identifier or short name.
79
+ :param model_name: HuggingFace model identifier or short alias.
44
80
  :return: Absolute :class:`~pathlib.Path` to the cached model directory.
45
81
  """
46
- import os # pylint: disable=import-outside-toplevel
47
-
48
- default = str(Path.cwd() / ".pycodekg" / "models")
49
- cache_root = Path(os.environ.get("PYCODEKG_MODEL_DIR", default))
50
- safe_name = model_name.replace("/", "--")
51
- return cache_root / safe_name
82
+ return resolve_model_path(model_name, local_fallback=Path.cwd() / ".pycodekg" / "models")
52
83
 
53
84
 
54
85
  if TYPE_CHECKING:
@@ -79,6 +110,7 @@ def suppress_ingestion_logging() -> None:
79
110
  import transformers # pylint: disable=import-outside-toplevel
80
111
 
81
112
  transformers.logging.set_verbosity_error()
113
+ transformers.logging.disable_progress_bar()
82
114
  except (ImportError, AttributeError):
83
115
  pass
84
116
 
@@ -145,6 +177,7 @@ class SentenceTransformerEmbedder(Embedder):
145
177
  from transformers import logging as hf_logging # pylint: disable=import-outside-toplevel
146
178
 
147
179
  hf_logging.set_verbosity_error()
180
+ hf_logging.disable_progress_bar()
148
181
 
149
182
  local_path = _local_model_path(model_name)
150
183
  _prev_tqdm = os.environ.get("TQDM_DISABLE")
@@ -34,16 +34,12 @@ from collections.abc import Iterable
34
34
  from dataclasses import dataclass
35
35
  from pathlib import Path
36
36
 
37
- from pycode_kg.utils import node_id, rel_module_path
38
- from pycode_kg.visitor import PyCodeKGVisitor
39
-
40
37
  # ============================================================================
41
38
  # Configuration
42
39
  # ============================================================================
43
-
44
- #: Default sentence-transformer model. Override via the ``PYCODEKG_MODEL``
45
- #: environment variable, e.g. ``export PYCODEKG_MODEL=BAAI/bge-small-en-v1.5``.
46
- DEFAULT_MODEL: str = os.environ.get("PYCODEKG_MODEL", "BAAI/bge-small-en-v1.5")
40
+ from pycode_kg.index import DEFAULT_MODEL as DEFAULT_MODEL # noqa: F401 — re-exported
41
+ from pycode_kg.utils import node_id, rel_module_path
42
+ from pycode_kg.visitor import PyCodeKGVisitor
47
43
 
48
44
  # ============================================================================
49
45
  # Graph primitives (LOCKED v0 CONTRACT)