Last active
June 4, 2021 00:47
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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