graphrag-codeproperty-graph 0.5.2__tar.gz → 0.5.3__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.
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/CHANGELOG.md +16 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/PKG-INFO +1 -1
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/pyproject.toml +1 -1
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/graph_loader.py +36 -2
- graphrag_codeproperty_graph-0.5.3/tests/test_graph_loader_neptune_safe_props.py +75 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/.github/workflows/publish.yml +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/.gitignore +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/CONTRIBUTING.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/LICENSE +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/NOTICE +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/README.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/ARCHITECTURE.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/Defining the Master Evidence Graph: A Formal Model for Stateful Software Verdicts.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/HYBRID-GRAPH.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/NOTICE.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/Toward a Master Evidence Graph for Software Verdicts.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/graphrag_com_redrawn_architecture.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/graphrag_phased_architecture.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/neptune_vs_neptune_analytics_cpg_rag_architecture copy.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/neptune_vs_neptune_analytics_cpg_rag_architecture.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/examples/README.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/examples/notebooks/01-CPG-Models-and-GraphDiff.ipynb +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/examples/notebooks/02-Delta-Ingestion-Pipeline.ipynb +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/examples/notebooks/data/sample_edges.json +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/examples/notebooks/data/sample_nodes.json +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/sbom/AWS-SERVICES.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/sbom/SBOM.md +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/sbom/codeproperty-graph.cdx.json +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/__init__.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/artifact_reader.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/artifact_validator.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/code_slice_store.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/cpg_service.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/delta_ingestor.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/graph_diff.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/graphson_converter.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/manifest_manager.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/models.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/schema.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/summary_overlay.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/tenant_ops.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/src/codeproperty_graph/vector_loader.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/tests/__init__.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/tests/test_codeproperty_graph.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/tests/test_cpg_service.py +0 -0
- {graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/tests/test_delta_ingestor_embedding_property.py +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.5.3] - 2026-09-16
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **`GraphLoader` now coerces all node/edge properties to Neptune-safe scalar
|
|
9
|
+
literals before writing.** Neptune Database openCypher rejects list/dict/tuple/set
|
|
10
|
+
property values ("Property value must be a simple literal"). Joern's raw node/edge
|
|
11
|
+
`properties` (merged verbatim in `_node_to_write_dict` / `_edge_to_write_dict`) can
|
|
12
|
+
contain collection values — e.g. Java `modifiers`, `annotations`, `parameterTypes`,
|
|
13
|
+
edge `argIndexList` — which would fail the primary node/edge write the same way the
|
|
14
|
+
0.5.2 embedding write did. A new `_neptune_safe_properties` helper JSON-serializes
|
|
15
|
+
collection values to compact strings (preserving the data as a queryable scalar,
|
|
16
|
+
since these Joern properties have no other store) and drops `None`. Applied at the
|
|
17
|
+
single write boundary so every node and edge is Neptune-safe regardless of what the
|
|
18
|
+
Joern export contains. Covered by `tests/test_graph_loader_neptune_safe_props.py`.
|
|
19
|
+
(PSAPI-66782.)
|
|
20
|
+
|
|
5
21
|
## [0.5.2] - 2026-09-16
|
|
6
22
|
|
|
7
23
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: graphrag-codeproperty-graph
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Summary: Code Property Graphs — Joern/Semgrep extraction, AI vulnerability enrichment, risk scoring
|
|
5
5
|
Project-URL: Repository, https://github.com/kanjani-ai-research/codeproperty-graph
|
|
6
6
|
Author-email: Evan Erwee <evan@erwee.com>
|
|
@@ -7,7 +7,7 @@ packages = ["src/codeproperty_graph"]
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "graphrag-codeproperty-graph"
|
|
10
|
-
version = "0.5.
|
|
10
|
+
version = "0.5.3"
|
|
11
11
|
description = "Code Property Graphs — Joern/Semgrep extraction, AI vulnerability enrichment, risk scoring"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.11"
|
|
@@ -7,6 +7,7 @@ Converts raw artifact dicts (from nodes.jsonl / edges.jsonl) into typed CPG
|
|
|
7
7
|
models and writes them in batches to a graph store, applying tenant isolation.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
import json
|
|
10
11
|
import logging
|
|
11
12
|
from typing import Any, Protocol, runtime_checkable
|
|
12
13
|
|
|
@@ -15,6 +16,35 @@ from .models import CPGNode, CPGEdge
|
|
|
15
16
|
logger = logging.getLogger(__name__)
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
def _neptune_safe_properties(properties: dict) -> dict:
|
|
20
|
+
"""Coerce a property dict to Neptune-Database-safe SCALAR values.
|
|
21
|
+
|
|
22
|
+
Neptune Database openCypher only accepts simple-literal property values —
|
|
23
|
+
it rejects list/dict/tuple/set with "Property value must be a simple
|
|
24
|
+
literal". Joern's raw node/edge properties can contain collection values
|
|
25
|
+
(e.g. Java `modifiers`, `annotations`, `parameterTypes`), which would fail
|
|
26
|
+
the write. Unlike the embedding vector (which lives in the vector store),
|
|
27
|
+
these Joern properties have no other home, so we PRESERVE them as a compact
|
|
28
|
+
JSON string rather than dropping them — keeping the data queryable as a
|
|
29
|
+
scalar. `None` values are dropped (Neptune stores nothing for them).
|
|
30
|
+
"""
|
|
31
|
+
safe = {}
|
|
32
|
+
for key, value in (properties or {}).items():
|
|
33
|
+
if value is None:
|
|
34
|
+
continue
|
|
35
|
+
if isinstance(value, (list, tuple, set, dict)):
|
|
36
|
+
try:
|
|
37
|
+
safe[key] = json.dumps(
|
|
38
|
+
list(value) if isinstance(value, (tuple, set)) else value,
|
|
39
|
+
ensure_ascii=False, default=str,
|
|
40
|
+
)
|
|
41
|
+
except (TypeError, ValueError):
|
|
42
|
+
safe[key] = str(value)
|
|
43
|
+
else:
|
|
44
|
+
safe[key] = value
|
|
45
|
+
return safe
|
|
46
|
+
|
|
47
|
+
|
|
18
48
|
@runtime_checkable
|
|
19
49
|
class GraphStoreProtocol(Protocol):
|
|
20
50
|
"""Protocol for graph store backends (e.g., Neptune)."""
|
|
@@ -220,7 +250,9 @@ class GraphLoader:
|
|
|
220
250
|
return {
|
|
221
251
|
"id": node.id,
|
|
222
252
|
"label": f"{self._tenant_id}__{node.node_type}",
|
|
223
|
-
|
|
253
|
+
# Neptune Database rejects non-scalar property values; coerce
|
|
254
|
+
# collection-valued Joern properties to JSON strings.
|
|
255
|
+
"properties": _neptune_safe_properties(properties),
|
|
224
256
|
}
|
|
225
257
|
|
|
226
258
|
def _edge_to_write_dict(self, edge: CPGEdge) -> dict:
|
|
@@ -244,5 +276,7 @@ class GraphLoader:
|
|
|
244
276
|
"source_id": edge.source_id,
|
|
245
277
|
"target_id": edge.target_id,
|
|
246
278
|
"edge_type": edge.edge_type,
|
|
247
|
-
|
|
279
|
+
# Neptune Database rejects non-scalar property values; coerce
|
|
280
|
+
# collection-valued Joern edge properties to JSON strings.
|
|
281
|
+
"properties": _neptune_safe_properties(properties),
|
|
248
282
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""GraphLoader must coerce node/edge properties to Neptune-safe scalars.
|
|
2
|
+
|
|
3
|
+
Neptune Database openCypher rejects list/dict/tuple/set property values
|
|
4
|
+
("Property value must be a simple literal"). Joern's raw node/edge properties
|
|
5
|
+
can contain collection values (Java modifiers, annotations, parameterTypes, ...),
|
|
6
|
+
so GraphLoader serializes them to JSON strings at the write boundary — preserving
|
|
7
|
+
the data as a queryable scalar rather than failing the write.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from codeproperty_graph.graph_loader import _neptune_safe_properties, GraphLoader
|
|
14
|
+
from codeproperty_graph.models import CPGNode, CPGEdge
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_sanitizer_json_encodes_collections_and_keeps_scalars():
|
|
18
|
+
props = {
|
|
19
|
+
"name": "ProductController", # str scalar → kept
|
|
20
|
+
"line_number": 42, # int scalar → kept
|
|
21
|
+
"is_external": False, # bool scalar → kept
|
|
22
|
+
"modifiers": ["public", "final"], # list → JSON string
|
|
23
|
+
"annotations": {"RestController": {}}, # dict → JSON string
|
|
24
|
+
"parameterTypes": ("int", "String"), # tuple → JSON string
|
|
25
|
+
"tags": {"a", "b"}, # set → JSON string
|
|
26
|
+
"nothing": None, # None → dropped
|
|
27
|
+
}
|
|
28
|
+
out = _neptune_safe_properties(props)
|
|
29
|
+
|
|
30
|
+
# scalars unchanged
|
|
31
|
+
assert out["name"] == "ProductController"
|
|
32
|
+
assert out["line_number"] == 42
|
|
33
|
+
assert out["is_external"] is False
|
|
34
|
+
# None dropped
|
|
35
|
+
assert "nothing" not in out
|
|
36
|
+
# collections became strings, round-trippable
|
|
37
|
+
assert isinstance(out["modifiers"], str)
|
|
38
|
+
assert json.loads(out["modifiers"]) == ["public", "final"]
|
|
39
|
+
assert isinstance(out["annotations"], str)
|
|
40
|
+
assert json.loads(out["annotations"]) == {"RestController": {}}
|
|
41
|
+
assert isinstance(out["parameterTypes"], str)
|
|
42
|
+
assert json.loads(out["parameterTypes"]) == ["int", "String"]
|
|
43
|
+
assert isinstance(out["tags"], str) # set serialized (order not asserted)
|
|
44
|
+
# EVERY value is now a Neptune-safe scalar literal
|
|
45
|
+
for k, v in out.items():
|
|
46
|
+
assert not isinstance(v, (list, dict, tuple, set)), k
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_node_write_dict_has_only_scalar_properties():
|
|
50
|
+
loader = GraphLoader.__new__(GraphLoader)
|
|
51
|
+
loader._tenant_id = "apm1"
|
|
52
|
+
node = CPGNode.from_artifact({
|
|
53
|
+
"cpg_node_id": "n1",
|
|
54
|
+
"node_type": "METHOD",
|
|
55
|
+
"full_name": "com.app.A.m",
|
|
56
|
+
"properties": {"modifiers": ["public"], "annotations": ["@Override"]},
|
|
57
|
+
})
|
|
58
|
+
wd = loader._node_to_write_dict(node)
|
|
59
|
+
for k, v in wd["properties"].items():
|
|
60
|
+
assert not isinstance(v, (list, dict, tuple, set)), (k, type(v))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_edge_write_dict_has_only_scalar_properties():
|
|
64
|
+
loader = GraphLoader.__new__(GraphLoader)
|
|
65
|
+
loader._tenant_id = "apm1"
|
|
66
|
+
edge = CPGEdge.from_artifact({
|
|
67
|
+
"edge_id": "e1",
|
|
68
|
+
"source_cpg_node_id": "n1",
|
|
69
|
+
"target_cpg_node_id": "n2",
|
|
70
|
+
"edge_type": "CALL",
|
|
71
|
+
"properties": {"argIndexList": [0, 1, 2]},
|
|
72
|
+
})
|
|
73
|
+
wd = loader._edge_to_write_dict(edge)
|
|
74
|
+
for k, v in wd["properties"].items():
|
|
75
|
+
assert not isinstance(v, (list, dict, tuple, set)), (k, type(v))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/ARCHITECTURE.md
RENAMED
|
File without changes
|
|
File without changes
|
{graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/docs/HYBRID-GRAPH.md
RENAMED
|
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
|
{graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/sbom/AWS-SERVICES.md
RENAMED
|
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
|
{graphrag_codeproperty_graph-0.5.2 → graphrag_codeproperty_graph-0.5.3}/tests/test_cpg_service.py
RENAMED
|
File without changes
|