Skip to content

Instantly share code, notes, and snippets.

@gitmpr
Last active October 18, 2024 09:30
Show Gist options
  • Save gitmpr/ac6f45154d85e2801895e108e7b01466 to your computer and use it in GitHub Desktop.
Save gitmpr/ac6f45154d85e2801895e108e7b01466 to your computer and use it in GitHub Desktop.
## This script demonstrates how input parameters can be specified in multiple ways and
## a recommended common approach and order of reading, and potentially overwriting these
## parameters if multiple input sources provide a different value for the same parameter.
## configuration parameter value set method precedence order:
## cli args override everything
## env vars take presedence over a config file
## If none of the three are supplied it is nice to fallback to hardcoded sane default values if applicable
## Lower number configuration method overrides higher number
## 1 cli args
## 2 env vars
## 3 config file
## 4 sane default values hardcoded in application
## in some software, 2 and 3 are swapped. Check!
import argparse
import os
import configparser
import subprocess
# 4
# Set the default value for the variable
value = "default value declared in script"
# 3
# Read the value from a config file to use instead
config = configparser.ConfigParser()
config_file = "parameter_precedence_example_config.toml"
config.read(config_file)
if config.has_option('SETTINGS', 'value'):
value = config['SETTINGS']['value']
# 2
# Check if the environment variable exists and override the value
if "ENV_VAR_VALUE" in os.environ:
value = os.environ["ENV_VAR_VALUE"]
# 1
# If an optional command-line argument is provided, override the value
parser = argparse.ArgumentParser()
parser.add_argument("--arg", help="Override the default value")
args = parser.parse_args()
if args.arg:
value = args.arg
# Print the variable with the final value
print("\033[0;35m" + F"{value = }" + "\033[0m")
#print(F"{value = }")
print()
if not os.getenv('CONF_DEMO_FIRST_RUN'):
commands = [
"echo -en \"[SETTINGS]\\nvalue = value read from config file\" > parameter_precedence_example_config.toml &&\\\npython configuration_parameters_precedence.py",
"export ENV_VAR_VALUE=\"value set from env var\" &&\\\npython configuration_parameters_precedence.py",
"python configuration_parameters_precedence.py --arg \"value overridden with cli arg\"",
"rm ./parameter_precedence_example_config.toml"
]
# we only want to let this script execute itself a few times, but not recursively
os.environ['CONF_DEMO_FIRST_RUN'] = "1"
for command in commands:
print(command) # and print the command output in magenta ANSI color
subprocess.run(command, shell=True, executable='/bin/bash') # needs bash instead of sh to use -e flag of echo command
# print("echo -n \"[SETTINGS]\\nvalue = value read from config file\" > parameter_precedence_example_config.toml")
# print("python configuration_parameters_precedence.py")
# subprocess.run("echo -n \"[SETTINGS]\\nvalue = value read from config file\n\" > parameter_precedence_example_config.toml && python configuration_parameters_precedence.py", shell=True)
# print("export ENV_VAR_VALUE=\"value set from env var\"")
# print("python configuration_parameters_precedence.py")
# subprocess.run("export ENV_VAR_VALUE=\"value set from env var\" && python configuration_parameters_precedence.py", shell=True)
# print("python configuration_parameters_precedence.py --arg \"value overriden with cli arg\"")
# subprocess.run("python configuration_parameters_precedence.py --arg \"value overriden with cli arg\"", shell=True)
# subprocess.run("rm ./parameter_precedence_example_config.toml", shell=True)
# parameter_precedence_example_config.toml
# [SETTINGS]
# value = "value read from config file"
# It is also possible, and arguably better, to write the config file with the configparser library object also, or with python
#config_file_text = """
#[SETTINGS]
#value = "value read from config file"
#"""
#with open("./parameter_precedence_example_config.toml", 'w') as file:
# file.write(config_file_text)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment