-
-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot override env var when creating model #180
Comments
This is right.
It's because you initialize the field with its name. you have to use the So, this example works: from pydantic import AnyHttpUrl, Field
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
abc: AnyHttpUrl = Field(validation_alias="my_abc")
def test_(monkeypatch):
monkeypatch.setenv("MY_ABC", "http://localhost.com/")
assert (
str(Settings(my_abc="http://prod.localhost.com/").abc)
== "http://prod.localhost.com/"
) |
Thanks for the reply! If I understand you correctly, there is currently no way to instruct a model to look for a specific env var name but take the declared field name when working just in Python? Looking at it together with some other features, this becomes even more strange to me, e.g. If I want to force upper case env vars, I need to rename the fields to uppercase and then violate pep8 aka use uppercase field names for class members? |
Here is the data that comes to Pydantic and Pydantic picks the As I mentioned above you can initialize |
And how come that |
It does work. but So, in your case, if the |
I would argue that when I explicitly pass a value for a field name,
It's an unexpected side effect for me that an env var changes the parsing logic. Production code potentially needs to change based on some outside condition. Are you open to discuss a change? I believe it can be local to
|
Right now
Source classes don't have any idea about each other and they just collect and return the data related to them and at the end We have the source priority concept that you can change the priority of sources over each other. but in your case, you have multiple data with different names. But this is a special case, honestly, I don't want to add source-specific logic to when looking at your setting class class Settings(BaseSettings):
abc: AnyHttpUrl = Field(validation_alias="my_abc")
model_config = SettingsConfigDict(populate_by_name=True, extra="allow") You defined a I think the simple and correct way to do it is by passing BTW, I am not going to say I don't want to change it. just trying to think louder. |
I am mostly arguing from a user perspective, knowing only a little about pydantic internals. IMO, a strong argument is that env var names are currently coupled to field names (at least in my example). If I modify an env name, I need to update places that do not deal with env vars at all. The documentation does not reflect this coupling well. It says:
I'll wait for other's opinions now. |
@chbndrhnns FYI, after discussion with the Pydantic team we decided to do something clever in So, PR welcome. |
Anyone have a suggestion for a workaround in this issue? I have a similar issue:
When running this via my standard API server, it will initiate via However, there's sometimes instances where I want to manually instantiate settings (tests, scripts, etc), like
As I understand it in this thread, doing the above right now is not possible; I must instead specify the kwarg as Intuitively, I'd expect that when constructing the settings object manually in python, any kwargs I pass should:
Few other thoughts:
Obviously this isn't particularly pretty, but has unblocked me for now |
I expect a field value given while creating a model instance takes precedence over an existing environment variable.
It seems this is not possible here:
One workaround is to use the validation alias when creating the instance:
The text was updated successfully, but these errors were encountered: