Config Serialization

By default, coma favors YAML over JSON for its config serialization, since omegaconf only supports YAML. However, coma does natively support JSON as well.

Default Behavior

To illustrate the default behavior, let’s revisit an example from the introductory tutorial:

main.py
from dataclasses import dataclass

import coma

@dataclass
class Config:
    message: str = "Hello World!"

if __name__ == "__main__":
    coma.register("greet", lambda cfg: print(cfg.message), Config)
    coma.wake()

Because Config has type name config, it will be serialized to config.yaml by default:

$ python main.py greet
Hello World!
$ cat config.yaml
message: Hello World!

We can force coma to serialize to JSON by specifying an explicit file path for Config:

$ python main.py greet --config-path config.json
Hello World!
$ cat config.json
{
    "message": "Hello World!"
}

Note

By default, coma automatically adds the --config-path flag through the default parser_hook of initiate(). Specifically, a flag of the form --{config_id}-path is added for each global and local config, where {config_id} is the corresponding config identifier.

Now we have two competing config files. Let’s modify each one to distinguish them:

config.yaml
message: Hello YAML!
config.json
{
    "message": "Hello JSON!"
}

Now, if we run the program, we see that YAML is favored:

$ python main.py greet
Hello YAML!

But we can still force coma to use JSON instead:

$ python main.py greet --config-path config.json
Hello JSON!

If we specify a file path without an extension, coma will again favor YAML:

$ python main.py greet --config-path config
Hello YAML!

Finally, if we delete the YAML file while keeping the JSON file, coma will ignore the existing JSON file (and create a new YAML file instead) unless explicitly given a JSON file extension:

$ rm config.yaml
$ python main.py greet --config-path config
Hello World!
$ python main.py greet --config-path config.json
Hello JSON!

In summary, by default coma natively supports JSON, but YAML always takes precedence.

Favoring JSON

We can reverse coma’s default preference by setting JSON as the default file extension through the config_hook of initiate():

main.py
from dataclasses import dataclass

import coma

@dataclass
class Config:
    message: str = "Hello World!"

if __name__ == "__main__":
    coma.initiate(
        config_hook=coma.hooks.config_hook.multi_load_and_write_factory(
            default_ext=coma.config.io.Extension.JSON
        )
    )
    coma.register("greet", lambda cfg: print(cfg.message), Config)
    coma.wake()

First, let’s ensure that both YAML and JSON config files exist and are differentiated:

config.yaml
message: Hello YAML!
config.json
{
    "message": "Hello JSON!"
}

Now, when running the program, we see that JSON is favored in all cases, unless a YAML file extension is explicitly provided:

$ python main.py greet
Hello JSON!
$ python main.py greet --config-path config
Hello JSON!
$ python main.py greet --config-path config.json
Hello JSON!
$ python main.py greet --config-path config.yaml
Hello YAML!