63 lines
1.9 KiB
Python
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
|