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
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')