Quickstart¶
This quickstart provides a short introduction on how to get started
with ResConfig
. Read Installation first, if you have
not installed the resconfig
package.
Let us first create an ResConfig
object with a simple
default configuration for your application, myapp.py:
from resconfig ResConfig
config = ResConfig({"db": {"host": "localhost", "port": 5432}})
By default, ResConfig
loads configuration immediately after
its initialization. To control the timing of load, use the
load_on_init
flag:
config = ResConfig({"db": {"host": "localhost", "port": 5432}},
load_on_init=False)
config.load()
The following sections introduce you to the basic usage of
ResConfig
object.
The “.”-Style Key Notation¶
ResConfig
exposes dict
-like interface for value
access but additionally allows the “.”-style notation for nested
keys. The following methods all return the same value, localhost
:
host = config["db"]["host"]
host = config["db.host"]
host = config.get("db.host") # similar to dict.get
The “.”-style can be used elsewhere, e.g.,
config = ResConfig({"db.host": "localhost", "db.port": 5432})
This will be the same default configuration shown
earlier. ResConfig
takes care of nesting the dict
for you.
Use with Configuration Files¶
To read configuration from (multiple) files, supply a list of paths on object initialization:
config = ResConfig({"db.host": "localhost", "db.port": 5432},
config_files=["myconf.yml",
"~/.myconf.yml,
"/etc/myconf.yml"])
If any of the files exists, they are read in the reverse order, i.e., /etc/myconf.yml, ~/.myconf.yml, and then myconf.yml, and the configuration read from them get merged in that order, overriding the default. This allows layered configuration based on specificity by filesystem location. Read Configuration from Files for more detail.
Use with Environment Variables¶
Properly named environment variables can override default
configuration. When you run your myapp.py app with the DB_HOST
and/or DB_PORT
environment variables set, their values override
the default:
$ DB_HOST=remotehost DB_PORT=3306 python myapp.py
That is, config["db.host"]
and config["db.port"]
will return
remotehost
and 3306
, respectively. As a rule of thumb, a
configuration key maps to an uppercased, “_”-delimited (when nested)
environment variable name. Read Environment Variables for more detail.
Use with ArgumentParser¶
A ResConfig
object can dynamically generate
ArgumentParser
arguments from default
configuration:
parser = argparse.ArgumentParser()
parser.add_argument(...) # Define other arguments
config.add_arguments_to_argparse(parser)
# --pg-host and --pg-port arguments are now available
After actually parsing the (command-line) arguments, pass the parse
result to ResConfig
and then load the configuration:
args = parser.parse_args()
config.prepare_from_argparse(args)
config.load()
For more detail, read ArgumentParser Integration.
Adding Actions on Changes¶
A ResConfig
object is aware of changes to its
configuration. Watch functions watch changes happening at any nested
key to act on them:
from resconfig import Action
@config.watch("db.host")
def act_on_nested_key(action, old, new):
if action == Action.ADDED:
# db.host added
elif action == Action.MODIFIED:
# db.host modified
elif action == Action.RELOADED:
# db.host reloaded
elif action == Action.REMOVED:
# db.host removed
Here, the act_on_nested_key()
function is called whenever
configuration changes occur at db.host
and can decide what to do
with the old
and/or new
values. For more detail, read
Watch Functions.