Skip to content

Instantly share code, notes, and snippets.

@IlluminatiFish
Last active June 4, 2021 00:47
Show Gist options
  • Save IlluminatiFish/315416313fb08cb491a316360c3611de to your computer and use it in GitHub Desktop.
Save IlluminatiFish/315416313fb08cb491a316360c3611de to your computer and use it in GitHub Desktop.
A short utility to use YAML configurations in Python and access their node data using the node1.node2.node3 format
#
# This program is a utility used by myself that I have released
# to the public under the GPLv3 license
#
# Copyright (c) 2021 IlluminatiFish.
#
# 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, version 3.
#
# 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 http://www.gnu.org/licenses/.
#
import yaml
class InvalidNodeException(Exception):
def __init__(self, msg):
super().__init__(msg)
class LoaderException(Exception):
def __init__(self, msg):
super().__init__(msg)
class YAMLLoader:
_path = []
_config_nodes = {}
_preloaded = False
def __init__(self, file):
self._file = file
def _traverse_nodes(self, yaml_dict):
for key, value in yaml_dict.items():
if isinstance(value, dict):
self._path.append(key)
self._traverse_nodes(value)
else:
route = '.'.join(self._path) + '.' + key
self._config_nodes[route] = value
return self._config_nodes
def load_nodes(self):
file = open(self._file, 'r')
stream = file.read()
yaml_dict = yaml.safe_load(stream)
self._traverse_nodes(yaml_dict)
self._preloaded = True
file.close()
def get_node(self, path):
if self._preloaded:
node_data = self._config_nodes.get(path)
if node_data is not None:
return node_data
else:
raise InvalidNodeException(f'It appears that "{path}" is an invalid YAML node')
else:
raise LoaderException('get_node() was referenced before the YAML nodes were loaded with load_nodes()')
loader = YAMLLoader('config.yml')
loader.load_nodes()
node_data = loader.get_node('root.node1.node2.node3')
print(node_data)
@IlluminatiFish
Copy link
Author

IlluminatiFish commented Mar 29, 2021

Better version of the YAMLNodeLoader gist I made a few weeks ago, since it is more OOP based and you don't have as much I/O overhead when calling the get_config_node() method as seen in the other version, as it preloads all the nodes it finds once into a dictionary which you can then call from using the get_node() method in this version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment