2

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?

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

4 Comments

"I found easier customize sources like this" actually this seems to be exactly what they state to do in the docs. Feel free to link these in answer :)
Unfortunately documentation do not provide any information what are some restrictions :( And do not describe that yaml_file parameter makes sense only if settings_customise_sources method is overridden. Anyway, my code will be completely working if you add return (YamlConfigSettingsSource(settings_cls),) without providing c.yaml as argument (all yaml parameters will be taken from model_config). If you would like to update your answer using model_config I will mark it as correct (since my question is about how to use yaml related arguments)
[deleted]
[deleted]
Just one moment: to read sectioned parameters, extra="allow" argument is obligatory → extra is needed here because you simply didn't add port: int field into Settings class. So port: 123 is an extra parameter for the class. It is completely not related to sectioned parameters
@rzlvmp well, fair. fixed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.