pydantic / pydantic-settings

Settings management using pydantic
https://docs.pydantic.dev/latest/usage/pydantic_settings/
MIT License
508 stars 50 forks source link

Cannot load prefixed nested model from dotenv. #279

Closed voodoo11 closed 2 months ago

voodoo11 commented 2 months ago

How to reproduce:

Given .env:

NESTED_FOO=foo
BAR=bar
from pydantic_settings import BaseSettings, SettingsConfigDict

class NestedConfig(BaseSettings):
    foo: str = ""
    model_config = SettingsConfigDict(env_prefix="NESTED_")

class Config(BaseSettings):
    nested: NestedConfig = NestedConfig()
    bar: str = ""
    model_config = SettingsConfigDict(
        env_file=".env", env_file_encoding="utf-8", extra="ignore", case_sensitive=False
    )

print(Config())

results in:

nested=NestedConfig(foo='') bar='bar'

Setting env variable by hand e.g. NESTED_FOO=foo python test.py works fine.

hramezani commented 2 months ago

Couple of points:

Here is the working example:

from pydantic import BaseModel
from pydantic_settings import BaseSettings, SettingsConfigDict

class NestedConfig(BaseModel):
    foo: str = ""

class Config(BaseSettings):
    nested: NestedConfig = NestedConfig()
    bar: str = ""
    model_config = SettingsConfigDict(
        env_file=".env", env_file_encoding="utf-8", extra="ignore", case_sensitive=False, env_nested_delimiter="__"
    )

print(Config())
voodoo11 commented 2 months ago

@hramezani Thanks, that makes sense. Is it possible then to override model config for submodels somehow?

hramezani commented 2 months ago

pydantic-settigns only loads the config for the models you are initializing(Config in your example) and collect values for the model fields. so it only consider the parent model configs