Simon Bull
03/06/2025, 10:49 PMconf = OmegaConf.merge(
OmegaConf.structured(StructuredConfClass), # Defaults + structure
OmegaConf.create(parsed_yaml_1), # Intermediate prio: yaml
OmegaConf.create(parsed_yaml_2), # Intermediate prio: yaml
OmegaConf.create(cli_args), # Highest prio: cli
)
This object is then dict-like, i.e. conf["section"]["subsection"]["param"], but also accessible via fields conf.section.subsection.param which would necessitate refactoring if using a bare dict.
But usefully, the yaml and cli args are validated at instantiation time against the valid fields and type annotations of the StructuredConfClass.
What I tried
1) I can of course write helper nodes and instantiate StructuredConfClass from parameters, or e.g. one of its ConfSectionClasses from params:section etc in every node. Possible but a but annoying.
2) I can write a custom class to use as CONFIG_LOADER_CLASS inheriting from `OmegaConfigLoader`; one option is to overload __getitem__, watch for parameters key, plug in the structured object there.
-> But, this seems to not be sufficient alone, because the default KedroContext.params method calls <http://OmegaConf.to|OmegaConf.to>_container() to always strip that back to a regular dict. So, I would also need a custom CONTEXT_CLASS to just return the params object as-is, or add structured_config_mode=SCMode.INSTANTIATE to the to_container call.
3) Given the above, I can skip a custom CONFIG_LOADER_CLASS and just add the structured base config to context.params. Vs (2), this comes with slight downside that params are not validated early, and no chance to e.g. flag which param source provides invalid parameters.
Are there any alternative/better approaches to this?
And, are there any dangers to changing the params returned by the context to being an instance of omegaconf.dictconfig.DictConfig or MyStructuredConfClass instead of a regular dict?Hall
03/06/2025, 10:49 PM