### Run Jupyter Notebook Server Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Start a Jupyter Notebook or Jupyter Lab server. This requires development dependencies to be installed. ```bash jupyter notebook ``` ```bash jupyter lab ``` -------------------------------- ### Install cwe-tree Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Install the library for production use or development. Development installs include extra tools like linters and type checkers. ```bash pip install cwe-tree ``` ```bash pip install -e ".[dev]" ``` ```bash git clone https://github.com/samhsu-dev/cwe-tree.git cd cwe-tree uv sync --dev ``` -------------------------------- ### Install cwe-tree Package Source: https://github.com/samhsu-dev/cwe-tree/blob/main/README.md Standard installation command for the cwe-tree package. Includes an option for installing development tools. ```bash pip install cwe-tree # With dev tools (linters, type checker, jupyter) pip install -e ".[dev]" # or uv sync --dev ``` -------------------------------- ### Install Package with Development Tools using pip Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Install the package in editable mode with development tools using pip. This is an alternative to using uv for dependency management. ```bash pip install -e '.[dev]' ``` ```bash pip install -e '.' ``` -------------------------------- ### Clone Repository and Sync Dependencies with uv Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Clone the CWE-Tree repository and install development dependencies using uv. Ensure you have Python 3.12+ and uv installed. ```bash git clone https://github.com/samhsu-dev/cwe-tree.git cd cwe-tree uv sync --dev ``` ```bash uv sync ``` -------------------------------- ### Low-level Graph Traversal with query.succ and query.prev Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Use `succ` to get outgoing neighbors (children) and `prev` to get incoming neighbors (parents). These methods can be filtered by edge type using a predicate. ```python from cwe_tree import query node = query.get_cwe("CWE-284") # Raw successors (children via outgoing PARENT_OF edges) children_raw = list(query.succ(node)) # Raw predecessors (parents via incoming PARENT_OF edges) parents_raw = list(query.prev(node)) # With predicate — filter by edge type filtered_children = list(query.succ(node, lambda e: e.edge_type == "PARENT_OF")) print(f"Children: {[n.cwe_id for n in children_raw]}") print(f"Parents: {[n.cwe_id for n in parents_raw]}") ``` -------------------------------- ### Update uv to the Latest Version Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Update the uv package installer to the latest version using a curl script. This is necessary for PEP 735 support. ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` -------------------------------- ### Get Predecessor Nodes Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use the `prev()` method to retrieve all direct predecessor nodes (parents) of a given node. This is helpful for understanding upward relationships in the CWE hierarchy. ```python # Use prev() directly node = query.get_cwe("CWE-77") predecessors = list(query.prev(node)) print(f"Predecessors of {node.cwe_id}:") for pred in predecessors: print(f" - {pred.cwe_id}: {pred.name}") ``` -------------------------------- ### Get All Ancestors Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb The `ancestors()` method performs a breadth-first traversal to find all nodes from which the source node is reachable. Use this to get all parent nodes at any depth. ```python # Get all ancestors node = query.get_cwe("CWE-77") all_ancestors = list(query.ancestors(node)) print(f"All ancestors of {node.cwe_id}: {len(all_ancestors)}") for anc in all_ancestors: print(f" - {anc.cwe_id}: {anc.name}") ``` -------------------------------- ### Get Immediate Child Nodes Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Fetch a set of direct child `CweNode` instances for a specified CWE ID using `query.get_children()`. Useful for exploring the hierarchy downwards. ```python from cwe_tree import query children = query.get_children("CWE-74") print(f"CWE-74 has {len(children)} direct children:") for child in sorted(children, key=lambda n: n.cwe_id): print(f" {child.cwe_id}: {child.name}") # Example output: # CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') # CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') # CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') # ... ``` -------------------------------- ### Get Successors with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Retrieve all successor nodes from a given node, or filter them by edge type using a predicate function. ```python from cwe_tree import query node = query.node("CWE-284") # Get all successors all_successors = list(query.succ(node)) # Get successors filtered by edge type child_successors = list(query.succ(node, lambda e: e.edge_type == "PARENT_OF")) ``` -------------------------------- ### Iterate All Nodes with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Iterate over all nodes in the forest, with an optional predicate function to filter the results. Useful for getting all nodes or specific subsets. ```python from cwe_tree import query # Get all nodes all_nodes = list(query.nodes()) # Get nodes filtered by predicate class_nodes = list(query.nodes(lambda n: n.abstract == "Class")) # Count total nodes total = len(list(query.nodes())) ``` -------------------------------- ### Get Predecessors with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Retrieve all predecessor nodes to a given node, or filter them by edge type using a predicate function. ```python from cwe_tree import query node = query.node("CWE-284") # Get all predecessors all_predecessors = list(query.prev(node)) # Get predecessors filtered by edge type parent_predecessors = list(query.prev(node, lambda e: e.edge_type == "PARENT_OF")) ``` -------------------------------- ### Get Successor Nodes Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use the `succ()` method to retrieve all direct successor nodes (children) of a given node. This is useful for exploring downward relationships in the CWE hierarchy. ```python # Use succ() directly node = query.get_cwe("CWE-77") successors = list(query.succ(node))[:5] # Get first 5 print(f"First 5 successors of {node.cwe_id}:") for succ in successors: print(f" - {succ.cwe_id}: {succ.name}") ``` -------------------------------- ### Get All Descendants Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb The `descendants()` method performs a breadth-first traversal to find all nodes reachable from a source node. Use this to get all child nodes at any depth. ```python # Get all descendants root = query.get_root_nodes()[0] all_descendants = list(query.descendants(root)) print(f"Total descendants of {root.cwe_id}: {len(all_descendants)}") print(f"First 10 descendants:") for desc in all_descendants[:10]: print(f" - {desc.cwe_id}: {desc.name}") ``` -------------------------------- ### Get Ancestors with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Perform a breadth-first traversal to find all ancestor nodes from which a target node is reachable, with an optional maximum depth limit. ```python from cwe_tree import query node = query.node("CWE-284") # Get all ancestors all_ancestors = list(query.ancestors(node)) # Get ancestors up to depth 5 ancestors_limited = list(query.ancestors(node, max_depth=5)) ``` -------------------------------- ### Display CWE Forest Structure Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use this code to print the entire CWE forest structure starting from the root nodes. Ensure the 'query' object is properly initialized. ```python print("Displaying entire CWE forest structure:") print("="*60) query.show() ``` -------------------------------- ### Display Specific CWE Subtree Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use the `query.show()` function to display a subtree starting from a given CWE node ID. The ID is automatically normalized to its CWE format. ```python print("Displaying subtree from node 284:") print("="*60) query.show("284") # Automatically normalized to CWE-284 ``` -------------------------------- ### Get Immediate Parent Nodes Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Retrieve a set of direct parent `CweNode` instances for a given CWE ID using `query.get_parents()`. Returns an empty set for root nodes. ```python from cwe_tree import query parents = query.get_parents("CWE-79") for p in parents: print(f"{p.cwe_id}: {p.name} [{p.abstract}]") # Example output: # CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component [Class] # Node with no parents (root node) returns empty set root_parents = query.get_parents("CWE-664") print(len(root_parents)) # 0 ``` -------------------------------- ### Get Parent Nodes with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Retrieve all direct parent nodes connected via incoming PARENT_OF edges to a specified child node. ```python from cwe_tree import query node = query.node("CWE-284") for parent in query.parent(node): print(f"Parent: {parent.cwe_id} - {parent.name}") ``` -------------------------------- ### query.succ(node, predicate=None) / query.prev(node, predicate=None) Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Low-level graph traversal functions to get outgoing (children) or incoming (parents) neighbors of a node. They can be filtered by an optional predicate. ```APIDOC ## `query.succ(node, predicate=None)` / `query.prev(node, predicate=None)` — Low-level graph traversal `succ` returns outgoing neighbors (children); `prev` returns incoming neighbors (parents). These are the base-class traversal primitives that `get_children` and `get_parents` wrap. ### Parameters #### Path Parameters - **node**: The starting `CweNode` object. - **predicate**: An optional function that filters edges based on a condition. ### Request Example ```python from cwe_tree import query node = query.get_cwe("CWE-284") # Raw successors (children via outgoing PARENT_OF edges) children_raw = list(query.succ(node)) # Raw predecessors (parents via incoming PARENT_OF edges) parents_raw = list(query.prev(node)) # With predicate — filter by edge type filtered_children = list(query.succ(node, lambda e: e.edge_type == "PARENT_OF")) print(f"Children: {[n.cwe_id for n in children_raw]}") print(f"Parents: {[n.cwe_id for n in parents_raw]}") ``` ### Response Returns an iterator of `CweNode` objects representing the neighbors. ``` -------------------------------- ### Analyze Specific Weakness Hierarchy (CWE-79) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieve and analyze the hierarchy of a specific CWE, such as CWE-79 (XSS). This involves getting the CWE object, its parents, children, and all descendants using `query.get_cwe`, `query.get_parents`, `query.get_children`, and `query.descendants`. ```python # Analyze CWE-79 (XSS) hierarchy cwe_79 = query.get_cwe("CWE-79") print(f"=== CWE-79 (XSS) Analysis ===") print(f"Name: {cwe_79.name}") print(f"Abstract: {cwe_79.abstract}") # Get parents parents = query.get_parents("CWE-79") print(f"\nParents ({len(parents)}):") for parent in parents: print(f" - {parent.cwe_id}: {parent.name}") # Get children children = query.get_children("CWE-79") print(f"\nChildren ({len(children)}):") for child in list(children)[:5]: print(f" - {child.cwe_id}: {child.name}") if len(children) > 5: print(f" ... and {len(children) - 5} more") # Get all descendants descendants = list(query.descendants(cwe_79)) print(f"\nAll descendants: {len(descendants)}") ``` -------------------------------- ### Get Descendants with Depth Limit using cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Perform a breadth-first traversal to find all descendant nodes reachable from a source node, with an optional maximum depth limit. ```python from cwe_tree import query root = query.get_root_nodes()[0] # Get all descendants up to depth 3 descendants = list(query.descendants(root, max_depth=3)) ``` -------------------------------- ### Get Full Node Metadata with Relationships Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Use `query.get_metadata()` to retrieve a dictionary containing a CWE node's properties and its resolved parent/child relationships. Returns None for non-existent IDs. ```python from cwe_tree import query import json metadata = query.get_metadata("CWE-89") if metadata: print(json.dumps(metadata, indent=2)) # { # "id": "CWE-89", # "name": "Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')", # "abstract": "Base", # "layer": {"CWE-20": 3, "CWE-664": 4, ...}, # "parents": ["CWE-943"], # "children": ["CWE-564"] # } # Graceful handling for unknown IDs print(query.get_metadata("CWE-00000")) # None ``` -------------------------------- ### View All Available Make Commands Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Display all available commands defined in the Makefile for development automation. ```bash make help ``` -------------------------------- ### ASCII Tree Visualization with query.show Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Visualizes the entire CWE forest or a specific subtree as an ASCII tree. Cycles are automatically detected and prevented. Non-existent nodes are handled gracefully. ```python from cwe_tree import query # Visualize entire forest from all roots query.show() # CWE-664: Improper Control of a Resource Through its Lifetime # ├── CWE-118: Improper Access of Indexable Resource ('Range Error') # │ ├── CWE-119: Improper Restriction of Operations within the Bounds of a Memory Buffer # │ │ ├── CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow') # ... # Visualize only the subtree rooted at CWE-74 query.show("CWE-74") # CWE-74: Improper Neutralization of Special Elements in Output Used by a Downstream Component # ├── CWE-77: Improper Neutralization of Special Elements used in a Command ('Command Injection') # │ ├── CWE-78: Improper Neutralization of Special Elements used in an OS Command # │ ├── CWE-89: Improper Neutralization of Special Elements used in an SQL Command # ... # Non-existent node prints a message instead of raising query.show("CWE-99999") # Node CWE-99999 not found. ``` -------------------------------- ### Import cwe_tree Module Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Imports the `cwe_tree` module and prints the type and instance of the pre-loaded `CweForest` singleton. ```python # Import the module # !pip install cwe-tree from cwe_tree import query # `query` is a pre-loaded singleton CweForest instance print(f"CweForest type: {type(query)}") print(f"CweForest instance: {query}") ``` -------------------------------- ### Query CWE Hierarchy and Navigate Relationships Source: https://github.com/samhsu-dev/cwe-tree/blob/main/README.md Demonstrates basic usage of the `cwe_tree.query` module for retrieving CWE nodes, their relationships, and metadata. Use this for general querying and traversal of the CWE structure. ```python from cwe_tree import query # Get a node node = query.get_cwe("CWE-79") # Both "79" and "CWE-79" works # Navigate relationships parents = query.get_parents("CWE-79") children = query.get_children("CWE-79") # Get metadata metadata = query.get_metadata("CWE-79") # Traverse forest roots = query.get_root_nodes() descendants = query.descendants(node) ancenstors = query.ancenstors(node) # Subnode Check query.is_ancestor("CWE-74", "CWE-77") query.is_descendant("CWE-77", "CWE-74") # Visualize structure query.show() # Display entire forest query.show("CWE-79") # Display subtree from specific node ``` -------------------------------- ### Format Code with isort and black Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Format Python code using isort for import sorting and black for code formatting. These commands can be run manually or via make. ```bash make format ``` ```bash uv run isort src/ ``` ```bash uv run black src/ ``` -------------------------------- ### Get Children Nodes with cpg2py Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Retrieve all direct child nodes connected via PARENT_OF edges from a specified parent node. ```python from cwe_tree import query node = query.node("CWE-1") for child in query.children(node): print(f"Child: {child.cwe_id} - {child.name}") ``` -------------------------------- ### query.show(cwe_id=None) Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Generates and prints an ASCII tree visualization of the CWE forest or a specified subtree. Cycles are automatically detected and handled. ```APIDOC ## `query.show(cwe_id=None)` — ASCII tree visualization Prints the CWE forest (or a subtree) as an ASCII tree to stdout. Cycles are detected and prevented automatically. ### Parameters #### Path Parameters - **cwe_id**: Optional. The ID of the CWE to use as the root for the subtree visualization. If `None`, the entire forest is visualized. ### Request Example ```python from cwe_tree import query # Visualize entire forest from all roots query.show() # Visualize only the subtree rooted at CWE-74 query.show("CWE-74") # Non-existent node prints a message instead of raising query.show("CWE-99999") ``` ### Response Prints an ASCII tree to standard output. No return value. ``` -------------------------------- ### Get Parent Nodes of a CWE Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieves all parent nodes for a given CWE weakness ID. Useful for understanding the hierarchical context of a weakness. ```python # Get parents of a node node = query.get_cwe("CWE-77") parents = query.get_parents("CWE-77") print(f"Parents of CWE-77:") for parent in parents: print(f" - {parent.cwe_id}: {parent.name}") print(f"\nTotal parents: {len(parents)}") ``` -------------------------------- ### Regenerate Lock File and Sync Dependencies Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Remove the existing uv.lock file and re-sync dependencies to resolve missing dependency issues. ```bash rm uv.lock uv sync --dev ``` -------------------------------- ### List All Root Nodes in the CWE Forest Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Returns a list of CweNode instances that have no parents, representing the entry points of independent trees in the CWE forest. Requires importing the query module. ```python from cwe_tree import query roots = query.get_root_nodes() print(f"Forest has {len(roots)} root nodes:") for root in roots: children = query.get_children(root.cwe_id) print(f" {root.cwe_id}: {root.name} ({len(children)} direct children)") # Example output: # CWE-664: Improper Control of a Resource Through its Lifetime (12 direct children) # CWE-682: Incorrect Calculation (6 direct children) # ... ``` -------------------------------- ### Check Python Version Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Verify that the current Python version is 3.12.0 or higher, which is a project requirement. ```bash python --version ``` -------------------------------- ### Run Code Quality Checks Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Execute code quality checks including import sorting, formatting, type checking, and linting. These can be run individually or via the make command. ```bash make quality ``` ```bash uv run isort --check-only src/ ``` ```bash uv run black --check src/ ``` ```bash uv run mypy src/ ``` ```bash uv run pylint src/ ``` -------------------------------- ### Find First Matching Node with query.first_node Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Retrieves the first `CweNode` that satisfies a given predicate. Returns `None` if no node matches. ```python from cwe_tree import query # Find first Class-level CWE first_class = query.first_node(lambda n: n.abstract == "Class") if first_class: print(f"{first_class.cwe_id}: {first_class.name}") # Find first node whose name contains a keyword first_injection = query.first_node(lambda n: "injection" in n.name.lower()) print(f"{first_injection.cwe_id}: {first_injection.name}") ``` -------------------------------- ### Get Root Nodes of the CWE Forest Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieves all root nodes in the CWE forest. These are the top-level nodes with no parents, representing independent tree hierarchies. ```python # Get all root nodes roots = query.get_root_nodes() print(f"Forest has {len(roots)} root node(s):\n") for root in roots: print(f"Root: {root.cwe_id}") print(f" Name: {root.name}") print(f" Abstract: {root.abstract}") print() ``` -------------------------------- ### Display CWE Subtree Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use the `query.show()` function to display a specific subtree of the CWE hierarchy. This is useful for exploring related vulnerabilities. ```python print("Displaying subtree from CWE-77:") print("="*60) query.show("CWE-77") ``` -------------------------------- ### Get CWE Node by ID Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieves a specific CWE node using its ID. The ID is automatically normalized. Handles cases where the node does not exist. ```python # Get a node with full ID node_79 = query.get_cwe("CWE-79") if node_79: print(f"Found: {node_79.cwe_id}") print(f"Name: {node_79.name}") print(f"Abstract: {node_79.abstract}") else: print("Node not found") ``` ```python # Get a node with normalized ID (ID normalization works automatically) node_284 = query.get_cwe("284") # Automatically becomes "CWE-284" if node_284: print(f"Found: {node_284.cwe_id}") print(f"Name: {node_284.name}") else: print("Node not found") ``` ```python # Handle non-existent nodes non_existent = query.get_cwe("CWE-99999") print(f"Result for non-existent node: {non_existent}") if non_existent is None: print("Node not found - gracefully handled") ``` -------------------------------- ### Sync Dependencies with Specific Groups using uv Source: https://github.com/samhsu-dev/cwe-tree/blob/main/SETUP.md Manage project dependencies using uv, allowing synchronization of base dependencies or development dependencies. ```bash uv sync ``` ```bash uv sync --dev ``` ```bash uv tree ``` -------------------------------- ### Get Child Nodes of a CWE Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieves all direct child nodes for a given CWE weakness ID. Helps in exploring more specific weaknesses within a broader category. ```python # Get children of a node children = sorted(query.get_children("CWE-77"), key=lambda x: x.cwe_id) print(f"Children of CWE-77:") for child in children: print(f" - {child.cwe_id}: {child.name}") print(f"\nTotal children: {len(children)}") ``` -------------------------------- ### query.first_node(predicate=None) Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Finds and returns the first `CweNode` that satisfies a given predicate function, or `None` if no such node exists. ```APIDOC ## `query.first_node(predicate=None)` — Find first matching node Returns the first `CweNode` satisfying the predicate, or `None` if no match exists. ### Parameters #### Path Parameters - **predicate**: A function that takes a `CweNode` and returns `True` if it matches, `False` otherwise. ### Request Example ```python from cwe_tree import query # Find first Class-level CWE first_class = query.first_node(lambda n: n.abstract == "Class") if first_class: print(f"{first_class.cwe_id}: {first_class.name}") # Find first node whose name contains a keyword first_injection = query.first_node(lambda n: "injection" in n.name.lower()) print(f"{first_injection.cwe_id}: {first_injection.name}") ``` ### Response Returns the first matching `CweNode` object or `None`. ``` -------------------------------- ### Find First Node Matching Predicate Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Use `first_node` to retrieve the initial node that satisfies a given condition. This is useful for targeted searches within the CWE tree. ```python from cwe_tree import query # Find first class-type node first_class = query.first_node(lambda n: n.abstract == "Class") ``` -------------------------------- ### Conceptual Diagram of CweTree Structure Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/idea.md Illustrates the relationship between the CweTree, CweNode objects, and their parent/child connections, as well as the lookup mechanism. ```text [CweTree] │ ├── manages ──> [CweNode (ID: CWE-79)] │ │ │ ├── parents ──> {CweNode (ID: CWE-74)} │ └── children ──> {CweNode (ID: CWE-80), ...} │ └── lookup ───> { "CWE-79": , ... } ``` -------------------------------- ### Trace Ancestry Path to Root Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Implement a function `get_path_to_root` to trace the ancestry of a given CWE ID up to its root node. This function iteratively follows the first parent until no more parents are found or a cycle is detected. ```python # Find complete ancestry path from a specific node to root def get_path_to_root(forest, node_id): """Get the path from a node to its root ancestor.""" path = [] current = forest.get_cwe(node_id) visited = set() while current and current.cwe_id not in visited: path.append(current) visited.add(current.cwe_id) parents = forest.get_parents(current.cwe_id) if parents: current = list(parents)[0] # Follow first parent else: break return path # Example: trace path for CWE-284 path = get_path_to_root(query, "CWE-77") print(f"Path from CWE-77 to root:") for i, node in enumerate(path): indent = " " * i print(f"{indent}-> {node.cwe_id}: {node.name}") ``` -------------------------------- ### Core Methods Source: https://github.com/samhsu-dev/cwe-tree/blob/main/README.md These are the primary methods for querying and retrieving information about CWE nodes and their relationships. ```APIDOC ## Core Methods ### `node(cwe_id)` **Description**: Get node by ID. ### `nodes(predicate=None)` **Description**: Iterate all nodes with optional filter. ### `get_parents(cwe_id)` **Description**: Get parent nodes. ### `get_children(cwe_id)` **Description**: Get child nodes. ### `get_metadata(cwe_id)` **Description**: Get complete node metadata with relationships. ### `get_layer(cwe_id)` **Description**: Get layer/depth information. ### `get_root_nodes()` **Description**: Get all root nodes (no parents). ### `show(cwe_id=None)` **Description**: Visualize forest structure with ASCII tree. ``` -------------------------------- ### Retrieve Layer Information for a CWE ID Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Gets the layer information for a specific CWE ID, indicating its depth in different root hierarchies. Requires the `query` object and the `json` library. ```python # Get layer information layer = query.get_layer("CWE-77") print(f"Layer information for CWE-77:") print(json.dumps(layer, indent=2)) ``` -------------------------------- ### Get Depth Mapping for a CWE ID Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Retrieves a dictionary mapping root CWE IDs to the depth of the specified node within each root's subtree. Useful for understanding hierarchy depth. ```python from cwe_tree import query layer = query.get_layer("CWE-89") print(layer) # {"CWE-664": 4, "CWE-20": 3} # Deeper variant will have higher depth values variant_layer = query.get_layer("CWE-564") print(variant_layer) # {"CWE-664": 5, ...} ``` -------------------------------- ### first_node(predicate=None) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Returns the first node matching the predicate, or None if no match found. ```APIDOC ## first_node(predicate=None) ### Description Returns the first node matching the predicate, or None if no match found. ### Method Signature `first_node(predicate=None) -> Optional[CweNode]` ### Parameters * **predicate** (function, optional) - A function that takes a `CweNode` and returns `True` if the node is a match. ### Returns The first `CweNode` that matches the predicate, or `None` if no match is found. ``` -------------------------------- ### show(cwe_id=None) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Display the forest structure with tree-like ASCII formatting. ```APIDOC ## show(cwe_id=None) ### Description Display the forest structure with tree-like ASCII formatting. ### Parameters #### Query Parameters - **cwe_id** (string) - Optional - The ID of the CWE node to focus on. If not provided, the entire forest is displayed. ``` -------------------------------- ### Find First Node Matching Predicate Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb The `first_node()` method returns the first node that matches the provided predicate function, or `None` if no match is found. This is efficient for finding a single specific node. ```python # Example usage of first_node (predicate not provided in source) ``` -------------------------------- ### Low-level Node Lookup Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Use `query.node()` for direct node access via the base graph interface. Functionally equivalent to `get_cwe` but uses `cpg2py` naming conventions. ```python from cwe_tree import query node = query.node("CWE-284") if node: print(f"{node.cwe_id}: {node.name}") # CWE-284: Improper Access Control ``` -------------------------------- ### prev(node: CweNode, predicate=None) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Returns all predecessor nodes connected via incoming edges to the given node. Can be filtered by a predicate function. ```APIDOC ## prev(node: CweNode, predicate=None) ### Description Returns all predecessor nodes connected via incoming edges to the given node. ### Parameters - `node` - The target CweNode to traverse from - `predicate` (optional) - Filter function to select predecessors based on edge conditions ### Returns Iterable of predecessor CweNode instances ### Example ```python from cwe_tree import query node = query.node("CWE-284") # Get all predecessors all_predecessors = list(query.prev(node)) # Get predecessors filtered by edge type parent_predecessors = list(query.prev(node, lambda e: e.edge_type == "PARENT_OF")) ``` ``` -------------------------------- ### prev(node) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Returns all predecessor nodes (parents) connected via incoming edges. ```APIDOC ## prev(node) ### Description Returns all predecessor nodes (parents) connected via incoming edges. ### Method Signature `prev(node) -> Iterable[CweNode]` ### Parameters * **node** (`CweNode`) - The starting node. ### Returns An iterable of `CweNode` objects representing the predecessors. ``` -------------------------------- ### succ(node: CweNode, predicate=None) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Returns all successor nodes connected via outgoing edges from the given node. Can be filtered by a predicate function. ```APIDOC ## succ(node: CweNode, predicate=None) ### Description Returns all successor nodes connected via outgoing edges from the given node. ### Parameters - `node` - The source CweNode to traverse from - `predicate` (optional) - Filter function to select successors based on edge conditions ### Returns Iterable of successor CweNode instances ### Example ```python from cwe_tree import query node = query.node("CWE-284") # Get all successors all_successors = list(query.succ(node)) # Get successors filtered by edge type child_successors = list(query.succ(node, lambda e: e.edge_type == "PARENT_OF")) ``` ``` -------------------------------- ### Compute Forest Statistics Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Calculate basic statistics for the entire CWE forest, including the total number of nodes and edges, and identify the root nodes. This involves using `query.nodes`, `query.edges`, and `query.get_root_nodes`. ```python # Compute forest statistics all_nodes = list(query.nodes()) all_edges = list(query.edges()) roots = query.get_root_nodes() ``` -------------------------------- ### Find All Variant-Type Weaknesses Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Use the `query.nodes` method with a lambda function to filter and find all nodes where the 'abstract' property is 'Variant'. This is useful for identifying specific categories of weaknesses. ```python # Find all Variant type nodes variant_nodes = list(query.nodes(lambda n: n.abstract == "Variant")) print(f"Total Variant nodes: {len(variant_nodes)}") print(f"\nFirst 10 Variant nodes:") for node in variant_nodes[:10]: print(f" {node.cwe_id}: {node.name}") ``` -------------------------------- ### BFS Traversal of Descendants Source: https://context7.com/samhsu-dev/cwe-tree/llms.txt Performs a Breadth-First Search from a given CweNode to find all reachable descendant nodes. Supports limiting the traversal depth with `max_depth`. ```python from cwe_tree import query node = query.get_cwe("CWE-74") # All descendants (entire subtree) all_descendants = list(query.descendants(node)) print(f"CWE-74 subtree size: {len(all_descendants)}") # Only immediate and second-level children shallow = list(query.descendants(node, max_depth=2)) print(f"Within depth 2: {len(shallow)} nodes") for n in shallow: print(f" {n.cwe_id}: {n.name}") ``` -------------------------------- ### Traversal Methods Source: https://github.com/samhsu-dev/cwe-tree/blob/main/README.md Methods for traversing the CWE hierarchy, inherited from AbcGraphQuerier. ```APIDOC ## Traversal Methods (inherited from AbcGraphQuerier) ### `succ(node, predicate=None)` **Description**: Get successor nodes. ### `prev(node, predicate=None)` **Description**: Get predecessor nodes. ### `descendants(node, max_depth=None)` **Description**: BFS to find all descendants. ### `ancestors(node, max_depth=None)` **Description**: BFS to find all ancestors. ### `edges(predicate=None)` **Description**: Iterate all edges. ### `first_node(predicate=None)` **Description**: Get first matching node. ``` -------------------------------- ### Retrieve Complete Metadata for a CWE ID Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Fetches all metadata for a given CWE ID, including its name, abstract, layer, parents, and children. Requires the `query` object and the `json` library. ```python # Get comprehensive metadata import json metadata = query.get_metadata("CWE-79") print(json.dumps(metadata, indent=2)) ``` -------------------------------- ### ancestors(node: CweNode, max_depth=None) Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/traversal.md Performs breadth-first traversal to find all nodes from which the source node is reachable (all ancestors). Can limit traversal depth. ```APIDOC ## ancestors(node: CweNode, max_depth=None) ### Description Performs breadth-first traversal to find all nodes from which the source node is reachable (all ancestors). ### Parameters - `node` - The target CweNode to traverse to - `max_depth` (optional) - Limit traversal depth ### Returns Iterable of all ancestor CweNode instances ### Example ```python from cwe_tree import query node = query.node("CWE-284") # Get all ancestors all_ancestors = list(query.ancestors(node)) # Get ancestors up to depth 5 ancestors_limited = list(query.ancestors(node, max_depth=5)) ``` ``` -------------------------------- ### Parent-Child Navigation Source: https://github.com/samhsu-dev/cwe-tree/blob/main/docs/demo.ipynb Retrieve all parent or child nodes of a given CWE weakness. ```APIDOC ## `get_parents(cwe_id)` ### Description Retrieve all parent nodes of a given CWE weakness. ### Method `query.get_parents(cwe_id: str) -> Set[CweNode]` ### Parameters #### Path Parameters - **cwe_id** (str) - Required - The ID of the CWE node whose parents are to be retrieved. ### Response #### Success Response (Set[CweNode]) - A set of `CweNode` objects representing the parent nodes. ``` ```APIDOC ## `get_children(cwe_id)` ### Description Retrieve all child nodes of a given CWE weakness. ### Method `query.get_children(cwe_id: str) -> Set[CweNode]` ### Parameters #### Path Parameters - **cwe_id** (str) - Required - The ID of the CWE node whose children are to be retrieved. ### Response #### Success Response (Set[CweNode]) - A set of `CweNode` objects representing the child nodes. ```