pythonyamlpydantic

How to use yaml_file parameter for pydantic settings


Here is my example code:

from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(
        yaml_file=Path('c.yaml'),
        yaml_config_section='blah',
    )

    port: int


s = Settings()

and my c.yaml stored in the same directory:

blah:
  port: 123

When I'm running Python file I'm getting message:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Settings
port
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.11/v/missing

That means that Pydantic isn't even trying to read YAML file. I found multiple answers how to read YAML and most of it is about how to read YAML, convert it to dict and pass the dict as constructor arguments. But I could not find any information why this yaml_file and yaml_config_section exists and what it does.

Is here a simple way to read YAML using these arguments?


Solution

  • Due some restrictions Pydantic has in direct reading of YAML files, I found it easier to customize sources like this (as per documentation):

    from pydantic import BaseModel
    from pydantic_settings import BaseSettings, YamlConfigSettingsSource
    
    # Nothe the model declaration for your section
    class BlahSettings(BaseModel):
        port: int
    
    class Settings(BaseSettings):
        blah: BlahSettings
        @classmethod
        def settings_customise_sources(cls, settings_cls, **kwargs):
            return (YamlConfigSettingsSource(settings_cls, "c.yaml"),)
    
    s = Settings()
    print(s.blah.port)
    

    which, hopefully, gives:

    123
    

    UPDATE

    as OP mentioned in the conmment, it was possible to use model_config along with overridden method settings_customise_sources without explicit use of yaml_file parameter, which would be taken from the model_config itself.

    from pydantic_settings import BaseSettings, YamlConfigSettingsSource, SettingsConfigDict
    
    class Settings(BaseSettings):
        port: int
        model_config = SettingsConfigDict(
            yaml_file='c.yaml',
            yaml_config_section='blah',
            )
        @classmethod
        def settings_customise_sources(cls, settings_cls, **kwargs):
            return (YamlConfigSettingsSource(settings_cls),)
    
    
    
    s = Settings()
    print(s.port)