Closed rusmux closed 6 days ago
Thanks @rusmux for reporting this.
Your example code has some problems:
BaseModel
instead of BaseSettings
in sub-models https://docs.pydantic.dev/latest/concepts/pydantic_settings/#parsing-environment-variable-valuesenv_prefix
in sub-model does not have any effect, because pydantic-settings only considers the config of root modelenv_nested_delimiter
config for sub modelsSo, at the end you can collect values like you want by changing your code to:
from pydantic import Field, BaseModel
from pydantic_settings import (
BaseSettings,
PydanticBaseSettingsSource,
SettingsConfigDict,
YamlConfigSettingsSource,
)
class PydanticBaseSettings(BaseSettings):
@classmethod
def settings_customise_sources(
cls,
settings_cls: type[BaseSettings],
init_settings: PydanticBaseSettingsSource,
env_settings: PydanticBaseSettingsSource,
dotenv_settings: PydanticBaseSettingsSource,
file_secret_settings: PydanticBaseSettingsSource,
) -> tuple[PydanticBaseSettingsSource, ...]:
return (init_settings, env_settings, dotenv_settings,
YamlConfigSettingsSource(settings_cls), file_secret_settings)
class SubSettings(BaseModel):
value: str
class Settings(PydanticBaseSettings):
model_config = SettingsConfigDict(yaml_file="config.yaml", env_nested_delimiter="__")
value: str
sub: SubSettings
print(Settings())
You need to call your script by value=b sub__value=c python ...
I see, thank you!
In this example, If I use YAML source, I cannot override
sub_value
field with an environment variable.In
main.py
:In
config.yaml
:In terminal:
value=b sub_value=b python -m main
Gives:
value='b' sub=SubSettings(value='a')
The first value is overridden, but the second is not. If I do not use YAML source everything works as expected. I tried using
PydanticBaseSettings
forSubSettings
, but it doesn't help.