beetbox/confuse

Cretae config from template

palto42 opened this issue · 5 comments

Is there a way to create a yaml config file from a defined template dict like the one in /eample/__init__.py

The use case is to generate a new config file to start with if there is no configuration file defined yet.

config.dump() only dumps the currently loaded config, but I can't find an option how to dump a template dict.

Hello! What would a "template dict" look like? Would all the values be missing? I'm not 100% clear on how this would work.

The file generated would have the default values if defined in the template dict or empty values , if possible the expected type as comment.

From this example template dict:

template = {
    'library': confuse.Filename(default='/some/file.name'),
    'import_write': confuse.OneOf([bool, 'ask', 'skip'], default=False),
    'ignore': confuse.StrSeq(),
    'plugins': list,

    'paths': {
        'directory': confuse.Filename(),
        'default': confuse.Filename(relative_to='directory'),
    },

    'servers': confuse.Sequence(
        {
            'hostname': confuse.String(default="localhost",
            'options': confuse.StrSeq(),
        }
    )

This should create a file like:

library: /some/file.name # Filename
import_write: False # OneOf([bool, 'ask', 'skip'])
ignore: # StrSeq
plugins: # list

paths:
    directory: # Filename
    default: # Filename(relative_to='directory')

servers:
    - hostname: localhost # str
      options: # strSeq

Aha! To directly answer your question, no, we don't currently have anything like that. It actually seems pretty hard to do, because the resulting value-less config file isn't valid YAML—so we couldn't use a straightforward yaml.dump. Perhaps worth considering if there's a clever way to do it!

I think this is a great suggestion. I've just started using confuse in a toy project and what's irking me is that it kinda feels that using a template is the right thing to do as it allows for validation and lets me access validated config values like this: valid.some.option instead of the more cumbersome config['some']['option'].get(), but now I have two places that I basically need to keep in sync:

  1. config_default.yaml
  2. template definition in my code

If this issue were to somehow be addressed, the default config could be generated as a part of some build process or via a git hook, and the template becomes the one place where the configuration is defined.

Perhaps I'm doing it wrong and focusing too much on the template, but to me, it seems like the best way to use this library.

Thanks!

A validation template could possibly generate an appropriate minimum config file but I doubt it could produce a good default config file. It wouldn't, for example, generate the comments you would expect in a config file that explains the meaning of each parameter.

For my projects, I write the config_default.yaml, then the validation template.

When the program starts, if a config.yaml cannot be found, I copy config_default.yaml to the user directory and tell the user to configure it :) The config_default.yaml file guarantees the program can run properly, the config.yaml file customizes the behavior.