python-configuration icon indicating copy to clipboard operation
python-configuration copied to clipboard

Optional config from file

Open Teivaz opened this issue 3 years ago • 7 comments

I need to create a user configuration file that if present would override the basic config.

base.config.json - checked in
config.json - gitignore

But the following code does not work. I need to separately check for the config file and then modify the configuration sources.

cfg = ConfigurationSet(
    config_from_env(prefix="app_config"),
    config_from_json("config.json", read_from_file=True), # Throws error when file is not present
    config_from_json("base.config.json", read_from_file=True),
)

It would be nice to have this case handled by the library instead. The interface can look like this:

config_from_json("config.json", read_from_file=True, file_optional=True)

Teivaz avatar Jun 02 '21 16:06 Teivaz

+1 from me. I'd like to see this functionality as well. This can, however, be fixed by allocating a json object before the configuration initialization:

fname = "cfg/appsettings.json"
extrajson = {}
if os.path.exists(fname):
    extrajson = json.load(open(fname, "r"))
cfg = config.config(
    ('env', "MYAPP"),
    ('dict', extrajson),
    ('dict', defaultconfig))

oyvindbra avatar Aug 26 '21 19:08 oyvindbra

Isn't this accomplished with https://github.com/tr11/python-configuration/blob/11177291263b6f8a36c241a65c3bd5834f0919c9/tests/test_configuration_set.py#L601?

tr11 avatar Sep 02 '21 17:09 tr11

This will only partially solve the problem. When I need to specify as optional only one file this approach would be too permissive. In my case I need to always have the base config and throw an error when it is absent. But the user config is optional.

cfg = ConfigurationSet(
    config_from_env(prefix="app_config"),
    config_from_json("config.json", read_from_file=True, file_optional=True),
    config_from_json("base.config.json", read_from_file=True),
)

Teivaz avatar Nov 08 '21 16:11 Teivaz

I see, you need the ignore_missing_paths or file_optional in your example to be pushed down to each config_from_<filetype> handler, right?

tr11 avatar Dec 22 '21 05:12 tr11

Yes, I need to be able to control each config file's options individually. The approach I'm using is following:

  1. Base config is essential and is a part of the repo. It should always be present as it contains defaults.
  2. Then the user config is optional it can be stored in the user directory or in the working directory of the application that is being configured. If present this config has precedence over the base config.
  3. Then finally the environment variables configs have precedence over all other configs.

Teivaz avatar Dec 23 '21 09:12 Teivaz

This should be doable without any breaking changes. I'll have a branch with this soon for you to test.

tr11 avatar Dec 28 '21 17:12 tr11

Can you test the PR https://github.com/tr11/python-configuration/pull/72 to see if it works for your use case? You should be able to now use a ConfigurationSet as follows:

cfg = ConfigurationSet(
    config_from_env(prefix="app_config"),
    config_from_json("config.json", read_from_file=True, ignore_missing_paths=True),
    config_from_json("base.config.json", read_from_file=True),
)

tr11 avatar Jan 07 '22 14:01 tr11