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:
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:
message: Hello YAML!
{
"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()
:
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:
message: Hello YAML!
{
"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!