codesmidgen/codesmidgen/config.py

63 lines
1.9 KiB
Python

import json
import os
from configparser import ConfigParser
from pathlib import Path
from typing import Any
CONFIG_DEFAULTS = {
'SQLALCHEMY_TRACK_MODIFICATIONS': False
}
CONFIG_PREFIXES = ['SMIDGEN_', 'SQLALCHEMY_']
STRIPPED_PREFIXES = ['SMIDGEN_']
def read_from_file() -> dict:
"""Read the configuration file and return the values in a dictionary"""
config_file = Path(__file__).parent / '..' / 'codesmidgen.cfg'
if not config_file.exists():
return {}
config_parser = ConfigParser()
config_parser.read(config_file)
config: dict[str, Any] = {}
for option in config_parser.options('codesmidgen'):
config[option.upper()] = config_parser.get('codesmidgen', option)
return config
def read_from_envvars() -> dict:
"""Read the configuration from environment variables"""
config: dict[str, Any] = {}
for key in sorted(os.environ):
if not any([key.startswith(prefix) for prefix in CONFIG_PREFIXES]):
continue
value = os.environ[key]
try:
value = json.loads(value)
except Exception:
# If the value is not JSON parseable, just leave it as a string
pass
for prefix in STRIPPED_PREFIXES:
key = key.replace(prefix, '')
# Check if there are any "nested" values
if '__' not in key:
config[key] = value
continue
# Navigate the nested values and build the structure
*parents, child = key.split('__')
item = config
for parent in parents:
if parent not in item:
item[parent] = {}
item = item[parent]
item[child] = value
return config
def get_config() -> dict:
"""Read configuration from files, environment variables, etc."""
config = {}
config.update(CONFIG_DEFAULTS)
config.update(read_from_file())
config.update(read_from_envvars())
return config