Reputation: 2514
Using pydantic-settings (v2.0.3), I want to manage settings for services service1
and service2
, nesting them under the common settings
object, so I can address them like settings.service1.secret1
or settings.service2.secret2
. Currently, I have this code in my config.py
:
from pydantic_settings import BaseSettings
class FirstServiceSettings(BaseSettings):
secret1: str
class SecondServiceSettings(BaseSettings):
secret2: str
class Settings(BaseSettings):
service1: FirstServiceSettings
service2: SecondServiceSettings
class Config:
env_file = ".env"
settings = Settings()
And this is my .env
file:
secret1=secret1
secret2=secret2
However, I'm getting pydantic_core._pydantic_core.ValidationError: 4 validation errors for Settings
.
The problem can be solved by adding service1__
and service2__
prefixes to keys in .env
file and setting env_nested_delimiter = '__'
, but I wonder is there a way to make this without adding those prefixes in .env
file.
Upvotes: 8
Views: 3876
Reputation: 572
This problem can be solved using BaseModel
and set extra='ignore'
to BaseSettings
:
from pydantic import BaseModel
from pydantic_settings import VERSION, BaseSettings, SettingsConfigDict
print(f'{VERSION = }')
# > VERSION = '2.0.3'
class BaseServiceSettings(BaseSettings):
model_config = SettingsConfigDict(env_file='.env', extra='ignore')
class FirstServiceSettings(BaseServiceSettings):
secret1: str
class SecondServiceSettings(BaseServiceSettings):
secret2: str
class Settings2(BaseModel):
service1: FirstServiceSettings = FirstServiceSettings()
service2: SecondServiceSettings = SecondServiceSettings()
settings = Settings2()
print(settings.model_dump_json())
# > {"service1":{"secret1":"secret1"},"service2":{"secret2":"secret2"}}
Upvotes: 8