tonystark1234
tonystark1234

Reputation: 11

Use an environment variable with a different name in pydantic

I have a pydantic.BaseModel class where I'd like the variable node to have a default value based on an environment variable ENV_NODE_POOL.

Although my default environment variable works when I don't pass this variable, it seems to fail when I try to pass it. Would appreciate any help!

from pydantic import Field, BaseModel
from pydantic_settings import SettingsConfigDict

class WorkflowRun(BaseModel):
    id: str
    name: str
    node: str = Field(alias="env_node_pool")
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        env_ignore_empty=True,
    )



WorkflowRun(**{
    "id": "1",
    "name": "test",
    "node": "test", # this fails
})

WorkflowRun(**{
    "id": "1",
    "name": "test",
    "env_node_pool": "test", # this succeeds
})

Error:

ValidationError: 1 validation error for WorkflowRun
env_node_pool
  Field required [type=missing, input_value={'id': '1', 'name': 'test', 'node': 'test'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/missing
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...

Using pydantic.AliasChoices means that the default environment variable is not used:

from pydantic import Field, BaseModel, AliasChoices
from pydantic_settings import SettingsConfigDict

class WorkflowRun(BaseModel):
    id: str
    name: str
    node: str = Field(validation_alias=AliasChoices('node', 'ENV_NODE_POOL'))
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        env_ignore_empty=True,
        populate_by_name=True,
    )
WorkflowRun(**{
    "id": "1",
    "name": "test",
})

returns this error

pydantic_core._pydantic_core.ValidationError: 1 validation error for WorkflowRun
node
  Field required [type=missing, input_value={'id': '1', 'name': 'test'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.9/v/missing

Upvotes: 0

Views: 74

Answers (1)

tonystark1234
tonystark1234

Reputation: 11

Using validation_alias with a BaseSettings class does the trick! It uses your environment variable's value as the default, whilst allowing you to override it when initializing an object.

class WorkflowRun(BaseSettings):
    id: str
    name: str
    node: str = Field(validation_alias=AliasChoices('node', 'ENV_NODE_POOL'))
    model_config = SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        extra="ignore",
        env_ignore_empty=True,
        populate_by_name=True,
    )

Invocations:

>>> WorkflowRun(**{
    "id": "1",
    "name": "test",
})
WorkflowRun(id='1', name='test', node='default-node')

>>> WorkflowRun(**{
     "id": "1",
     "name": "test",
     "node": "new-pool"})
WorkflowRun(id='1', name='test', node='new-pool')

Upvotes: 1

Related Questions