I don't know of any built-in solution for overriding options with environment variables, but you can probably work out some naming convention to make it pretty easy.
I usually have three places to change settings in my programs:
- The source code holds generic defaults that will make sense for most developers, with an exception for security settings that should be secure by default.
- Environment variables can override the source code defaults.
- Command-line arguments can override the environment variables. Just be careful not to put passwords and other sensitive data on the command line, because process command lines can usually be seen by other users on the same system.
It sounds like you want to introduce another configuration file between level 1 and 2.
Here's what my code usually looks like:
def parse_args(argv=None):
parser = ArgumentParser(description='What my program does...',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--server',
default=os.environ.get('MYAPP_SERVER', 'http://localhost:8000'),
help='server to send data to')
parser.add_argument(
'--user',
default=os.environ.get('MYAPP_USER', 'alex'),
help='user name for server')
parser.add_argument(
'--password',
default=SUPPRESS,
help='password for server (default not shown)')
args = parser.parse_args(argv)
if not hasattr(args, 'password'):
args.password = os.environ.get('MYAPP_PASSWORD', 'alex')
return args
If you want to look in some config file, it might look something like this:
def parse_args(argv=None):
parser = ArgumentParser(description='What my program does...',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--server',
default=get_default('server', 'http://localhost:8000'),
help='server to send data to')
parser.add_argument(
'--user',
default=get_default('user', 'alex'),
help='user name for server')
parser.add_argument(
'--password',
default=SUPPRESS,
help='password for server (default not shown)')
args = parser.parse_args(argv)
if not hasattr(args, 'password'):
args.password = get_default('password', 'alex')
return args
def get_default(name, value):
file_value = read_config_file(name)
if file_value is not None:
value = file_value
return os.environ.get(f'MYAPP_{name.upper()}', value)