Skip to content

How to Override Deeply Nested Settings using Environment Variables? #203

@kschwab

Description

@kschwab

Hello,

Is it possible to override a deeply nested setting without having to redefine the entirety of the model?

Below is a modified example based off of Parsing environment variable values:

import os from pydantic import BaseModel from pydantic_settings import BaseSettings, SettingsConfigDict class DeepSubModel(BaseModel): v4: str class SubModel(BaseModel): v1: str v2: bytes v3: int deep: DeepSubModel class Settings(BaseSettings): model_config = SettingsConfigDict(env_nested_delimiter='__') v0: str sub_model: SubModel @classmethod def settings_customise_sources( cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return env_settings, init_settings, file_secret_settings # Ideal scenario would be a simple point modification os.environ['SUB_MODEL__DEEP__V4'] = 'override-v4' try: print(Settings(v0='0', sub_model=SubModel(v1='init-v1', v2=b'init-v2', v3=3, deep=DeepSubModel(v4='init-v4'))).model_dump()) except ValidationError as e: print(e) """  pydantic_core._pydantic_core.ValidationError: 3 validation errors for Settings  sub_model.v1  Field required [type=missing, input_value={'deep': {'v4': 'override-v4'}}, input_type=dict]  For further information visit https://errors.pydantic.dev/2.5/v/missing  sub_model.v2  Field required [type=missing, input_value={'deep': {'v4': 'override-v4'}}, input_type=dict]  For further information visit https://errors.pydantic.dev/2.5/v/missing  sub_model.v3  Field required [type=missing, input_value={'deep': {'v4': 'override-v4'}}, input_type=dict]  For further information visit https://errors.pydantic.dev/2.5/v/missing  """ # Current scenario seems to require entire definition of nested modes etc. os.environ['SUB_MODEL'] = '{"v1": "reinit-v1", "v2": "reinit-v2"}' os.environ['SUB_MODEL__V3'] = '33' print(Settings(v0='0', sub_model=SubModel(v1='init-v1', v2=b'init-v2', v3=3, deep=DeepSubModel(v4='init-v4'))).model_dump()) """ {'v0': '0', 'sub_model': {'v1': 'reinit-v1', 'v2': b'reinit-v2', 'v3': 33, 'deep': {'v4': 'override-v4'}}} """

The difference here is Settings is defined through instantiation instead of environment variables. Ideally, the below concept would still apply to Settings with respect to nested precedence, allowing for point modifications of nested variables:

Nested environment variables take precedence over the top-level environment variable JSON...

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions