Consider the following yaml
config file.
# config.yaml
key1:
value1: x
level1:
level2_1:
key1: y
level3:
key1: z
key2: zz
level2_2:
key1: a
level3: null
I am looking for a pydantic
model that loads the configuration from the config.yaml
file. I am especially interested in using the dot-notation for all levels of this nested configuration.
For example, I would like to use the settings as follows (assuming I assign the model to a variable called settings
):
settings.key1.value1 # x
settings.level1.level2_1.key1 # y
settings.level1.level2_2.level3.key2 # zz
What I did so far:
from pathlib import Path
import yaml
from pydantic import BaseModel, ConfigDict
class Key1Config(BaseModel):
value1: str
class Level3Config(BaseModel):
model_config = ConfigDict(extra="allow")
key1: str
class Level2Config(BaseModel):
key1: str
level3: Level3Config | None
class Config(BaseModel):
key1: Key1Config
level1: dict[str, Level2Config]
@classmethod
def from_yaml(cls, config_file: Path):
with config_file.open() as f:
data = yaml.safe_load(f)
return cls.model_validate(data)
settings = Config.from_yaml(Path(__file__).parent.joinpath("./config.yaml"))
I am struggling in defining level1
, because now it is a simply dict
. I would like it to be another model so that I can access every nested level via dot-notation.
For example, my current solution requires me to do something like settings.level1["level2_1"].level3.key2
.
But what I want is settings.level1.level2_1.level3.key2
.
Further information:
level2_*
can be any arbitrary number, i.e. level2_3
, level2_4
, or any arbitrary_name
.
level3
can also have an arbitrary number of lower level entries OR null
.