Skip to content

Instantly share code, notes, and snippets.

@lances101
Created December 6, 2019 13:02
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 lances101/083635c37c55bba59c43568f9f0a0c08 to your computer and use it in GitHub Desktop.
Save lances101/083635c37c55bba59c43568f9f0a0c08 to your computer and use it in GitHub Desktop.
Python Config
import json
import os
from pathlib import Path
from typing import Optional
DEFAULT_CONFIG_NAME = "default.json"
SECRETS_FILE_PATH = "secrets.json"
class Config(object):
"""
Your one stop solution for path based configuration files.
Loads stuff via JSON. Has commodity functions.
"""
def __init__(self, config_path_str: str or None = None):
if config_path_str is None or config_path_str == '':
config_path = Path(os.path.join(os.path.dirname(__file__), 'conf', DEFAULT_CONFIG_NAME))
else:
config_path = Path(config_path_str)
if not config_path.exists():
raise Exception(f"Config path was passed, but file is unreachable at '{config_path.absolute()}' ")
with open(str(config_path), 'r') as file:
self._config: dict = json.load(file)
secrets_path_str = self.get_property('application.secrets_path')
if secrets_path_str is None or secrets_path_str == '':
secrets_path = Path(os.path.join(os.path.dirname(__file__), 'conf', SECRETS_FILE_PATH))
else:
secrets_path = Path(secrets_path_str)
with open(str(secrets_path), 'r') as file:
self._config['secrets'] = json.load(file)
def _find(self, path: str, dictionary: dict) -> Optional[any]:
keys = path.split('.')
current_value: any = dictionary
for key in keys:
if key not in current_value:
return None
current_value = current_value[key]
return current_value
def get_property(self, property_path: str) -> Optional[any]:
"""
Returns the property or None
:param property_path:
:return:
"""
return self._find(property_path, self._config)
def get_property_or_raise(self, property_path: str, message: str = None) -> any:
"""
Returns a property or raises an exception
:param property_path:
:param message:
:return:
"""
value = self._find(property_path, self._config)
if value is None:
if message is None:
message = f"value for path {property_path} not found in config"
raise Exception(message)
return value
def get_property_or_default(self, property_path: str, default: any) -> any:
"""
Returns the property or a default value
:param property_path:
:param default:
:return:
"""
value = self._find(property_path, self._config)
if value is None:
return default
return value
def override_property(self, property_path: str, new_value: any):
"""
Overrides a property in the config
:param property_path:
:param new_value:
:return:
"""
keys = property_path.split('.')
value: any = self._config
for (index, key) in enumerate(keys, start=0):
if index < len(keys) - 1:
if key not in value:
value[key] = {}
else:
value = value[key]
else:
value[key] = new_value
return value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment