Source code for nutsml.config

"""
.. module:: config
   :synopsis: Handling of configuration files.
"""

import os
import yaml
import json


[docs]class Config(dict): """ Dictionary that allows access via keys or attributes. Used to store and access configuration data. """
[docs] def __init__(self, *args, **kwargs): """ Create dictionary. >>> contact = Config({'name':'stefan', 'address':{'number':12}}) >>> contact['name'] 'stefan' >>> contact.name 'stefan' >>> contact.address.number 12 >>> contact.surname = 'maetschke' >>> contact.surname 'maetschke' :param args args: See dict :param kwargs kwargs: See dict """ wrap = lambda v: Config(v) if type(v) is dict else v contents = ((k, wrap(v)) for k, v in dict(*args, **kwargs).items()) super(Config, self).__init__(contents) self.__dict__ = self
[docs] @staticmethod def isjson(filepath): """ Return true if filepath ends with '.json'. :param str filepath: Filepaht :return: True if filepath points ot JSON file. :rtype: bool """ return filepath.lower().endswith('.json')
def __repr__(self): return json.dumps(self, indent=2, sort_keys=True)
[docs] def load(self, filepath): """ Load configuration from file in JSON or YAML format. >>> cfg = Config().load('tests/data/configuration.json') >>> cfg.number 13 :param str filepath: Path to JSON or YAML file. :return: returns loaded configuration. :rtype: Config """ yaml_load = lambda fp: yaml.load(fp, Loader=yaml.SafeLoader) reader = json.load if Config.isjson(filepath) else yaml_load with open(filepath, 'r') as f: self.__init__(reader(f)) return self
[docs] def save(self, filepath): """ Save configuration to file in JSON or YAML format. >>> cfg = Config({'number': 13, 'name': 'Stefan'}) >>> cfg.save('tests/data/configuration.yaml') :param str filepath: Filepath. Should end with '.json' or '.yaml' """ writer = json.dump if Config.isjson(filepath) else yaml.dump with open(filepath, 'w') as f: writer(dict(self), f)
[docs]def load_config(filename): """ Load configuration file in YAML format from locations in defined order. The search order for the config file is: 1) user home dir 2) current dir 3) full path | Example file: 'tests/data/config.yaml' | filepath : c:/Maet | imagesize : [100, 200] >>> cfg = load_config('tests/data/config.yaml') >>> cfg.filepath 'c:/Maet' >>> cfg['imagesize'] [100, 200] :param filename: Name or full path of configuration file. :return: dictionary with config data. Note that config data can be accessed by key or attribute, e.g. cfg.filepath or cfg.['filepath'] :rtype: ConfigDict """ filepaths = [] for dirpath in os.path.expanduser('~'), os.curdir, '': try: filepath = os.path.join(dirpath, filename) filepaths.append(filepath) with open(filepath, 'r') as f: return Config(yaml.safe_load(f)) except IOError: pass raise IOError('Configuration file not found: ' + ', '.join(filepaths))