Skip to content
Snippets Groups Projects
config.py 4.54 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    config.py
    
    Configuration for obis.
    
    Created by Chandrasekhar Ramakrishnan on 2017-02-10.
    Copyright (c) 2017 Chandrasekhar Ramakrishnan. All rights reserved.
    """
    
    
    
    class ConfigLocation(object):
        """Path for configuration information."""
    
    
            :param desc: A description for the location in the form of a list of keys.
    
            :param basename: The name of the folder for this location.
    
    
    
    class ConfigParam(object):
        """Class for configuration parameters."""
    
    
        def __init__(self, name, private):
    
            :param private: Should the parameter be private to the repo or visible in the data set?
    
    
    
    class ConfigEnv(object):
        """The environment in which configurations are constructed."""
    
        def __init__(self):
            self.locations = {}
            self.params = {}
            self.initialize_locations()
            self.initialize_params()
    
        def initialize_locations(self):
    
            self.add_location(ConfigLocation(['global'], 'user_home', '.obis'))
            self.add_location(ConfigLocation(['local', 'public'], 'data_set', '.obis'))
            self.add_location(ConfigLocation(['local', 'private'], 'data_set', '.git/obis'))
    
            desc = loc.desc
            depth = len(desc) - 1
            locations = self.locations
            for i, sub_desc in enumerate(desc):
                if i == depth:
                    locations[sub_desc] = loc
                else:
    
                    if locations.get(sub_desc) is None:
                        locations[sub_desc] = {}
    
            self.add_param(ConfigParam(name='openbis_url', private=True))
            self.add_param(ConfigParam(name='user', private=False))
            self.add_param(ConfigParam(name='data_set_type', private=True))
            self.add_param(ConfigParam(name='data_set_properties', private=True))
    
    
        def add_param(self, param):
            self.params[param.name] = param
    
    
    def default_location_resolver(location):
        """Given a location, return a path"""
    
        if location.root == 'user_home':
            root = os.path.expanduser('~')
        else:
            # The remaining case is data_set -- find the root of the data set we are in
            root = './'
        return os.path.join(root, location.basename)
    
    
    
    class ConfigResolver(object):
        """Construct a config dictionary."""
    
        def __init__(self, env=None, location_resolver=None):
            self.env = env if env is not None else ConfigEnv()
            self.location_resolver = location_resolver if location_resolver is not None else default_location_resolver
    
            self.location_search_order = ['global', 'local']
            self.location_cache = {}
            self.initialize_location_cache()
    
        def initialize_location_cache(self):
            env = self.env
            for k, v in env.locations.items():
                self.initialize_location(k, v, self.location_cache)
    
        def initialize_location(self, key, loc, cache):
            cache[key] = {}  # Default value is empty dict
            if isinstance(loc, dict):
                for k, v in loc.items():
                    self.initialize_location(k, v, cache[key])
            else:
                root_path = self.location_resolver(loc)
                config_path = os.path.join(root_path, 'config.json')
                if os.path.exists(config_path):
                    with open(config_path) as f:
                        config = json.load(f)
                        cache[key] = config
    
    
        def config_dict(self):
            """Return a configuration dictionary by applying the lookup/resolution rules."""
    
    
            env = self.env
            result = {}
            # Iterate over the locations in the specified order searching for parameter values.
            # Later entries override earlier.
            for name, param in env.params.items():
                result[name] = None
                for l in self.location_search_order:
                    val = self.value_for_parameter(param, l)
                    if val is not None:
                        result[name] = val
            return result
    
        def value_for_parameter(self, param, loc):
            config = self.location_cache[loc]
            if loc != 'global':
                if param.private:
                    config = config['private']
                else:
                    config = config['public']
            return config.get(param.name)