Skip to content

Instantly share code, notes, and snippets.

@unpluggedcoder
Last active February 11, 2024 19:01
Show Gist options
  • Save unpluggedcoder/741137b7845f70611bada2c254c0a458 to your computer and use it in GitHub Desktop.
Save unpluggedcoder/741137b7845f70611bada2c254c0a458 to your computer and use it in GitHub Desktop.
[Python Config Parser Compatible With Environment Var] Get config from config file or environment variables. The priority order of config is: Config file > Environment > default_value. #python #configparser #env
import os
import configparser
class Config:
""" Get config from config file or environment variables.
The priority order of config is: Config file > Environment > default_value.
The env var is composed by: [SECTION]_[OPTION]
For example:
get_or_else('smtp', 'BIND_ADDRESS', '127.0.0.1')
=> os.environ.get('SMTP_BIND_ADDRESS', '127.0.0.1')
"""
config = configparser.ConfigParser()
BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
'0': False, 'no': False, 'false': False, 'off': False}
@staticmethod
def init_config(file):
if file:
Config.config.read_file(file)
@staticmethod
def get_or_else(section, option, default_value):
if Config.config.has_option(section, option):
return Config.config.get(section, option,
fallback=default_value)
else:
return os.environ.get('_'.join([section.upper(), option]),
default_value)
@staticmethod
def getint_or_else(section, option, default_value):
if Config.config.has_option(section, option):
return Config.config.getint(section, option,
fallback=default_value)
else:
return Config._get_conv_env_or_else(section, option,
int, default_value)
@staticmethod
def getfloat_or_else(section, option, default_value):
if Config.config.has_option(section, option):
return Config.config.getfloat(section, option,
fallback=default_value)
else:
return Config._get_conv_env_or_else(section, option,
float, default_value)
@staticmethod
def getboolean_or_else(section, option, default_value):
if Config.config.has_option(section, option):
return Config.config.getboolean(section, option,
fallback=default_value)
else:
return Config._get_conv_env_or_else(section, option,
Config._convert_to_boolean,
default_value)
@staticmethod
def _get_conv_env_or_else(section, option, conv, default_value):
return conv(os.environ.get('_'.join([section.upper(), option.upper()]),
default_value))
@staticmethod
def _convert_to_boolean(value):
"""Return a boolean value translating from other types if necessary.
"""
if value.lower() not in Config.BOOLEAN_STATES:
raise ValueError('Not a boolean: %s' % value)
return Config.BOOLEAN_STATES[value.lower()]
import argparse
from config import Config
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', help='Custom config file.',
type=argparse.FileType('r'))
args = parser.parse_args()
Config.init_config(args.config)
local_address = Config.get_or_else('smtp', 'BIND_ADDRESS', '127.0.0.1')
port = Config.getint_or_else('smtp', 'PORT', 25)
# ...
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment