A graph-based data structure designed for querying CSV files in Joern format in Python
Project description
cpg2py
Python graph query engine for Code Property Graphs from Joern CSV exports. Directed multi-graph with generic ABCs for custom node/edge/graph types.
Features: Load from nodes.csv + rels.csv; query/update nodes and edges (get_property, set_property, set_properties); traverse succ/prev/children/parent/flow_to/flow_from; JSON persistence (save_json, load_json, storage_from_json). Concrete types: CpgGraph, CpgNode, CpgEdge.
Installation
pip install cpg2py
From source (e.g. with uv):
git clone https://github.com/samhsu-dev/cpg2py.git && cd cpg2py
uv sync --dev
uv run pytest tests/
Input format
- nodes.csv: tab-delimited; must include node id (e.g.
id:intorid). Other columns become node properties. - rels.csv: tab-delimited; columns
start,end,type(orstart:str,end:str,type:str).
Usage
Load from CSV
from pathlib import Path
from cpg2py import cpg_graph, CpgGraph, CpgNode, CpgEdge
graph: CpgGraph = cpg_graph(Path("nodes.csv"), Path("rels.csv"))
Nodes and edges (edge identified by (from_id, to_id, edge_type); edge_type is string)
node: CpgNode = graph.node("2")
node.name
node.set_property("name", "x")
node.set_properties({"k": "v"})
edge: CpgEdge = graph.edge("2", "3", "ENTRY")
edge.from_nid, edge.to_nid, edge.type
edge.set_property("weight", 0.5)
Traversal
graph.succ(node) # successors
graph.prev(node) # predecessors
graph.children(node)
graph.parent(node)
graph.flow_to(node)
graph.flow_from(node)
graph.topfile_node("5") # top-level file node for given node ID
Filtered iteration (optional predicate)
graph.nodes(lambda n: n.type == "Function")
graph.edges(lambda e: e.edge_type == "FLOWS_TO")
graph.succ(node, who_satisifies=lambda e: e.edge_type == "PARENT_OF")
graph.descendants(node, condition=...)
graph.ancestors(node, condition=...)
JSON persistence
graph.storage.save_json("graph.json")
storage = Storage()
storage.load_json("graph.json")
graph2 = CpgGraph(storage)
# or
storage = storage_from_json(Path("graph.json"))
JSON schema: {"nodes": { "<id>": { "<key>": <value>, ... }, ... }, "edges": [ {"from": str, "to": str, "type": str, "props": {...} }, ... ]}. See design.md.
Extending (ABCs)
Implement AbcGraphQuerier[MyNode, MyEdge], AbcNodeQuerier, AbcEdgeQuerier; inject Storage. Full interface and contracts: docs/design.md.
Minimal custom graph:
from cpg2py import AbcGraphQuerier, AbcNodeQuerier, AbcEdgeQuerier, Storage
from typing import Optional
class MyNode(AbcNodeQuerier): pass
class MyEdge(AbcEdgeQuerier): pass
class MyGraph(AbcGraphQuerier[MyNode, MyEdge]):
def node(self, whose_id_is: str) -> Optional[MyNode]:
return MyNode(self.storage, whose_id_is)
def edge(self, fid: str, tid: str, eid: str) -> Optional[MyEdge]:
return MyEdge(self.storage, fid, tid, eid)
g = MyGraph(Storage())
Interface specifications (classes, methods, signatures, validation): docs/design.md.
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cpg2py-1.2.1.tar.gz.
File metadata
- Download URL: cpg2py-1.2.1.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1333d46bb1a9d19588a6f711838cf34356948b1901a49416f41059b43bb7febb
|
|
| MD5 |
653c5ac5a8bf35bf3eb2a4f41f6d3d23
|
|
| BLAKE2b-256 |
36a950863126c306abf2561fe41d0863beade42ba3a176c75752f8aa8a60f655
|
File details
Details for the file cpg2py-1.2.1-py3-none-any.whl.
File metadata
- Download URL: cpg2py-1.2.1-py3-none-any.whl
- Upload date:
- Size: 16.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa844089cb5826c51bfc853043717804d7c451b9015684c1476e9cbce35f53d2
|
|
| MD5 |
677e27760189c0d23710de6017dccc00
|
|
| BLAKE2b-256 |
3120a1d038594f8743f829b71de0ce3de7d2a8bd706114a05ee0c0933d58f217
|