[Python] Pydantic - parse a list of objects from YAML configuration file

Discussão em 'Python' iniciado por Stack, Janeiro 31, 2025.

  1. Stack

    Stack Membro Participativo

    I want to read a list of objects from a YAML file:

    - entry1:
    attribute: "Test1"
    amount: 1
    price: 123.45
    - entry2:
    attribute: "Test1"
    amount: 10
    price: 56.78


    For this data structure i created three nested models as follows:

    # Models
    class EntryValues(BaseModel):
    attribute: str
    amount: int
    price: float

    class Entry(BaseModel):
    entry1: EntryValues
    entry2: EntryValues
    class Config(BaseModel):
    __root__: list[Entry]



    My code to read the YAML config file looks as follows:

    # get YAML config path
    def get_cfg_path() -> Path:
    return CWD

    # read YAML file
    def read_cfg(file_name: str, file_path: Path = None) -> YAML:
    if not file_path:
    file_path = get_cfg_path()

    if file_path:
    try:
    file = open(file_path / file_name, "r")
    except Exception as e:
    print(f"open file {file_name} failed", e)
    sys.exit(1)
    else:
    return load(file.read())
    else:
    raise Exception(f"Config file {file_name} not found!")


    Now i want to unpack the values of the YAML to my model. For that i tried to unpack the values with the ** operator. I think im missing one more loop here though, but i can not get it work.

    # Unpack and create config file
    def create_cfg(file_name: str = None) -> Config:
    config_file = read_cfg(file_name=file_name)
    _config = Config(**config_file.data)
    return _config


    I would appreciate any help.

    Update


    So i played around with my model-structure a bit without using the YAML file. I dont quite get why the following throws an ValidationError:

    Consider the following list of entries (thats the same data structure i would receive from my YAML file):

    entries = [
    {'entry1': {'attribute': 'Test1', 'amount': 1, 'price': 123.45}},
    {'entry2': {'attribute': 'Test2', 'amount': 10, 'price': 56.78}}
    ]


    If i run the following simple loop, then Pydantic throws an ValidationError:

    for entry in entries:
    Entry(**entry)


    Error:

    ValidationError: 1 validation error for Entry
    entry2
    field required (type=value_error.missing)


    However, if the list only contains one entry dictionary, then it works:

    class Entry(BaseModel):
    entry1: EntryValues
    #entry2: EntryValues

    entries = [
    {'entry1': {'attribute': 'Test1', 'amount': 1, 'price': 123.45}}
    ]

    for entry in entries:
    Entry(**entry)


    Can someone explain this or what im doing wrong here?

    Continue reading...

Compartilhe esta Página