Source code for simplicity.tree.json_tree

# This file is part of SIMPLICITY
# Copyright (C) 2025 Pietro Gerletti
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Mar  9 13:53:52 2025

@author: pietro
"""
import json
from anytree import Node

[docs] def get_node_attributes(node): """Extract all JSON-serializable attributes from an anytree Node, printing warnings for user-defined non-serializable ones.""" serializable_attrs = {} for k, v in vars(node).items(): if k.startswith("_NodeMixin"): # Ignore internal anytree attributes continue if k in ('parent', 'children'): # Explicitly exclude parent/children references continue try: json.dumps(v) # Check if the value is JSON serializable serializable_attrs[k] = v except (TypeError, OverflowError): print(f"Warning: Attribute '{k}' of node '{node.name}' was not stored (non-serializable: {type(v).__name__})") # Attribute is skipped return serializable_attrs
[docs] def serialize(node): node_data = get_node_attributes(node) # Get dynamic attributes node_data["name"] = node.name node_data["children"] = [serialize(child) for child in node.children] return node_data
[docs] def write_json_tree_file(root, json_tree_filepath): with open(json_tree_filepath, "w") as f: json.dump(serialize(root), f, indent=4)
[docs] def deserialize(data, parent=None): node_attributes = {k: v for k, v in data.items() if k not in ("name", "children")} node = Node(data["name"], parent=parent, **node_attributes) # Recreate node for child in data.get("children", []): deserialize(child, node) # Recursively add children return node
[docs] def import_tree(json_tree_filepath): """Import a tree from JSON and reconstruct the hierarchy with attributes.""" with open(json_tree_filepath, "r") as f: data = json.load(f) return deserialize(data)