Config File Inheritance

It may already be obvious, if you read Typical File Paths, but it’s possible for config files to “inherit” from one another. The general idea is that all config is collected from various files, when assembling the “final” config to be used by the app.

For a simple example let’s assume you have just 2 typical config files in your app dir:

  • /srv/envs/poser/app/rattail.conf

  • /srv/envs/poser/app/quiet.conf

Let’s say that rattail.conf is a “complete” config file and may be used directly, as-is. And that quiet.conf is not complete but “inherits” from rattail.conf (as is typical) so that it also may be used directly.

In other words either of these commands should work when ran from /srv/envs/poser:

bin/rattail -c app/rattail.conf make-uuid
bin/rattail -c app/quiet.conf make-uuid

The contents of quiet.conf are usually quite minimal:

[rattail.config]
include = %(here)s/rattail.conf

[handler_console]
level = INFO

The “include” option within “rattail.config” section above, tells the Rattail config parser to bring in the contents of rattail.conf whenever it is reading quiet.conf - although any settings defined in quiet.conf will override whatever was brought in from rattail.conf. (In this example, quiet.conf only needs to set level = INFO to cut down on some logging output on the console.)

Caveats

There is a gotcha which can break the inheritance logic, but it can be avoided if you follow one simple rule:

The primary config file you reference when invoking the app (e.g. bin/rattail -c qpp/quiet.conf ...) must not contain a ‘loggers’ section, i.e. it should not have a snippet like this:

[loggers]
keys = root, exc_logger, ...

To be clear the gotcha only exists when:

  • config file which app is told to read, contains snippet like above

  • config file has an include setting, meaning inheritance should happen

  • config file also says to configure logging

The reason it breaks is that we let Python standard logging module take care of the logging configuration, but it will try to do so using the specified config file (e.g. quiet.conf) only instead of doing so with the combined result.

So again, just make sure there is no ‘loggers’ section in the config file you present to your app. Or alternatively, you can make sure that same config file does have all logging config within it, so e.g. inheritance would not affect that part.