I was working on a project that used TOML as the file format for configuration and it looked like this:
[project_a]
vault = "abc"
repo = "def"
[project_b]
vault = "ghi"
repo = "jkl"and I needed to validate the data based on this schema.
When this data is read in with a library like toml, we get a dict:
>>> import toml
>>> with open('config.toml', 'r') as config_file:
... config_data = toml.load(config_file)
>>> config_data
# {'project_a': {'vault': 'abc', 'repo': 'def'}, 'project_b': {'vault': 'ghi', 'repo': 'jkl'}}and I needed to let the project names to be anything and wanted to validate the configurations themselves.
Here’s how I did that with pydantic using RootModel:
from typing import Dict
from pydantic import RootModel, BaseModel
import toml
class Configuration(RootModel):
root: Dict[str, SiteConfiguration]
class SiteConfiguration(BaseModel):
vault: str
repo: str
def read_configuration(filename: str) -> Configuration:
with open(filename, 'r') as config_file:
config_data = toml.load(config_file)
return Configuration.model_validate(config_data)Now, our config is:
>>> print(read_configuration('config.toml'))
root={'project_a': SiteConfiguration(vault='abc', repo='def'), 'project_b': SiteConfiguration(vault='ghi', repo='jkl')}and we can work on it knowing that our configuration is well formed.