Assigning Pydantic Settings Fields not by alias even when environment variable is defined

91 Views Asked by At

I’d like to be able to create a Pydantic Settings object where the environment variable can be overriden if desired. In the example below the constructor call for user_3 fails:

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
import os

class User(BaseSettings):
    model_config = SettingsConfigDict(populate_by_name=True)
    name: str = Field(alias='full_name')  
    age: int

user_1 = User(full_name='John Doe', age=20)  
print(user_1) # >> name='John Doe' age=20
user_2 = User(name='John Doe', age=20)  
print(user_2) # >> name='John Doe' age=20
os.environ["full_name"] = "foo"
user_3 = User(name='John Doe', age=20)  # >> error (see below)
print(user_3)

with this message:

ValidationError: 1 validation error for User
name
  Extra inputs are not permitted [type=extra_forbidden, input_value='John Doe', input_type=str]
    For further information visit https://errors.pydantic.dev/2.6/v/extra_forbidden

Is there a way to set up the object such that populate_by_name works (user_3 constructor call) even when an environment variable exists?

Thanks!

Related question - Assigning Pydantic Fields not by alias

1

There are 1 best solutions below

2
Aviv Aviv On

That works:


from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
import os

class User(BaseSettings):
    model_config = SettingsConfigDict(populate_by_name=True)
    full_name: str = Field(alias='name')  
    age: int

user_1 = User(full_name='John Doe', age=20)  
print(user_1) # >> name='John Doe' age=20
user_2 = User(name='John Doe', age=20)  
print(user_2) # >> name='John Doe' age=20
os.environ["full_name"] = "foo"
user_3 = User(name='John Doe', age=20)
print(user_3)

This one as well:

from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
import os

class User(BaseSettings):
    model_config = SettingsConfigDict(populate_by_name=True)
    name: str = Field(alias='full_name')  
    age: int

user_1 = User(full_name='John Doe', age=20)  
print(user_1) # >> name='John Doe' age=20
user_2 = User(name='John Doe', age=20)  
print(user_2) # >> name='John Doe' age=20
os.environ["full_name"] = "foo"
user_3 = User(full_name='John Doe', age=20)
print(user_3)

I think that may be a pydantic bug. Anyways, that's some workarounds.