Skip to content

Instantly share code, notes, and snippets.

@cluelessperson
Created May 5, 2019 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cluelessperson/3a7e73039705b32cb1c6ce23b9a50ff0 to your computer and use it in GitHub Desktop.
Save cluelessperson/3a7e73039705b32cb1c6ce23b9a50ff0 to your computer and use it in GitHub Desktop.
import logging, pathlib, json, sys, subprocess, os
from .logging import root_logger as logger
class Config(object):
def __init__(self, parent_logger:logging.Logger=logger):
self.log = parent_logger.getChild(self.__class__.__name__)
self.config = {"log_level": "INFO"}
def __getattr__(self, attr):
try:
return self.config[attr]
except KeyError:
return None
def __setattr__(self, attr, value):
if attr in ["log", "config"]:
super(Config, self).__setattr__(attr, value)
else:
self.config[attr] = value
class FileConfig(Config):
def __init__(self, *args, path="config.json", required=False, **kwargs):
super(FileConfig, self).__init__(*args, **kwargs)
self._load_config(path, required=required)
def _load_config(self, path, required=False):
path = pathlib.Path(path)
if path.is_file():
self.log.info("Config file found. - {}")
with open(path, 'r') as f:
config = json.load(f)
self.config.update(config)
else:
log = "Config file not found. - {}".format(path)
if required:
self.log.fatal(log)
raise FileNotFoundError(path)
else:
self.log.info(log)
class GCloudFileConfig(Config):
def __init__(self, *args, **kwargs):
super(GCloudFileConfig, self).__init__(*args, **kwargs)
project_name = self._get_cloud_project_name()
file_config = FileConfig(path=f"{project_name}.json", required=False, parent_logger=self.log)
self.config.update(file_config.config)
@staticmethod
def _get_cloud_project_name():
call = "gcloud config get-value project"
result = subprocess.check_output(call.split(" "), stderr=open(os.devnull, 'wb'))
project_name = result.decode('utf-8').strip()
return project_name
class CliConfig(Config):
def __init__(self, *args, **kwargs):
super(CliConfig, self).__init__(*args, **kwargs)
cli_config = self._get_cli_config()
self.log.debug(cli_config)
# if config file specified, load that
if 'config' in cli_config:
self.log.info("Config file specified. - {}".format(cli_config['config']))
file_config = FileConfig(path=cli_config['config'], required=True, parent_logger=self.log)
self.config.update(file_config.config)
self.config.update(cli_config)
@staticmethod
def _get_cli_config():
def get_cli_key_vals():
for i, arg in enumerate(sys.argv):
if "--" in arg and len(sys.argv)-1 > i:
key = arg[2:]
value = sys.argv[i+1]
yield key, value
return dict(get_cli_key_vals())
class ConfigCombiner(Config):
def __init__(self, config_classes:list, *args, **kwargs):
super(ConfigCombiner, self).__init__(*args, **kwargs)
for config_class in config_classes:
config = config_class(*args, parent_logger=self.log)
self.config.update(config.config)
(venv) zac@zwafer:~/work/PyCharmProjects/paste_pizza$ python3 -m paste_pizza
20190505T231711.181276Z | DEBUG | paste_pizza | Starting up. - 20190505_0_dev
20190505T231711.191293Z | INFO | paste_pizza.ConfigCombiner.FileConfig | Config file not found. - config.json
20190505T231711.409322Z | INFO | paste_pizza.ConfigCombiner.GCloudFileConfig.FileConfig | Config file not found. - paste-pizza.json
20190505T231711.409534Z | DEBUG | paste_pizza.ConfigCombiner.CliConfig | {}
INFO
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment