pydantic-settings icon indicating copy to clipboard operation
pydantic-settings copied to clipboard

env_prefix doesn't follow case_sensitive flag in DotEnvSettingsSource

Open appunni-old opened this issue 10 months ago • 4 comments

           if not env_used:
                if is_extra_allowed and env_name.startswith(self.env_prefix):
                    # env_prefix should be respected and removed from the env_name
                    normalized_env_name = env_name[len(self.env_prefix) :]
                    data[normalized_env_name] = env_value
                else:
                    data[env_name] = env_value

in class DotEnvSettingsSource(EnvSettingsSource):

env_prefix doesn't follow case_sensitive flag, alias has to be lower case always, as case_insensitive will cause all env var name into lower case, it doesn't do same with env_prefix , as shown in code above

appunni-old avatar Apr 01 '24 07:04 appunni-old

Please provide more information. Also, it would be great to provide an example that represents your problem. It helps us to find the problem

hramezani avatar Apr 01 '24 07:04 hramezani

from typing import Dict

from pydantic import Json, Field
from pydantic_settings import BaseSettings


class HttpSettings(BaseSettings):
    base_url: str = Field(alias='BASE_URL')
    headers: Json[Dict[str, str]] = Field(default="{}", alias='HTTP_HEADERS')


if __name__ == "__main__":
    settings = HttpSettings(
      _env_prefix="rather_"
    )

""" .env

RATHER_BASE_URL=http://service.domain.com/api/v1/
RATHER_HTTP_HEADERS={"x-request-id": "default-client-id"}

"""

appunni-old avatar Apr 01 '24 10:04 appunni-old

class HttpSettings(LucarioSettings):
    base_url: str = Field(alias='BASE_URL')
    headers: Json[Dict[str, str]] = Field(default="{}", alias='HTTP_HEADERS')


if __name__ == "__main__":
    settings = HttpSettings(
      _env_prefix="RATHER_", _case_sensitive=True
    )

This one works, but _case_sensitive=False is not working. As alias will also validated in case sensitive manner even when _case_sensitive=False

appunni-old avatar Apr 01 '24 11:04 appunni-old

From the doc:

env_prefix does not apply to fields with alias. It means the environment variable name is the same as field alias:

So, you need to change your example like:

from pydantic import Field, Json
from pydantic_settings import BaseSettings

class HttpSettings(BaseSettings):
    base_url: str = Field(alias='BASE_URL')
    headers: Json[dict[str, str]] = Field(default="{}", alias='HTTP_HEADERS')


if __name__ == "__main__":
    settings = HttpSettings(
      _case_sensitive=True, _env_file='.env'
    )

Then, it works in both sensitive and insensitive cases.

hramezani avatar Apr 02 '24 07:04 hramezani