Comments (9)
Hi @JerPk and thanks a lot for reporting!
IMO you're right it's a bug. The behaviour with both secrets and env_prefix
was not tested so I guess that's why we never saw it.
I chose the 2nd solution on the 3 you suggested because for me the 1st doesn't make sense (it shouldn't use env_prefix
when we talk about secrets) and the 3rd doesn't really make sense when you already have folders!
Feedback more than welcome :)
Cheers
from pydantic-settings.
Hi @PrettyWood, I didn't expect such a fast response and implementation.
I completely agree with the solution. (although I will need to change some things in my code when I am updating to this future version.)
Thanks!
from pydantic-settings.
Similar issue exists, if "env" is set for a field.
class Settings(BaseSettings):
auth_key: str
api_key: str = Field(..., env="my_api_key")
redis_dsn: RedisDsn = "redis://user:pass@localhost:6379/1"
pg_dsn: PostgresDsn = "postgres://postgres:password@localhost:5432/postgres"
# to override domains:
# export my_prefix_domains='["foo.com", "bar.com"]'
domains: Set[str] = set()
# to override more_settings:
# export my_prefix_more_settings='{"foo": "x", "apple": 1}'
more_settings: SubModel = SubModel()
class Config:
# env_prefix = "my_prefix_" # defaults to no prefix, i.e. ""
fields = {
"auth_key": {"env": "my_auth_key",},
"redis_dsn": {"env": ["service_redis_dsn", "redis_url"]},
}
secrets_dir = "/var/run"
My secret had to be renamed to my_auth_key to succeed.
from pydantic-settings.
Proposal
Keep the solution as is now - thus use the environment variable name in all situations - not only for trying to read values from env var (and from dotenv file), but also from secrets.
Action needed: update the docs to clarify this rule.
Reasoning
Keep things simple. With unique naming rule for named configuration sources it is much simpler to document the applicaiton - simply give single set of names and add, that they can be provided via env vars, dotenv file or via secrets in a directory.
Another advantage: all existing deployment will work.
from pydantic-settings.
To quote @JerPk we have two solutions
- Make it clear in the documentation that
env_prefix
is also used for secrets - Do not use the
env_prefix
for the secrets
I thought option 2 made more sense but reading @vlcinsky opinion, I understand option 1 can be desired.
I will also add option 3 just to be sure
- Try without
env_prefix
and then with it (or the other way)
This would hence break nothing and allow both behaviours but could have side effects and is definitely less clear...
I add "feedback wanted" label and hope others will share their point of view :)
from pydantic-settings.
Thanks @PrettyWood for reaction.
Here is my feedback:
Following the KISS I would invite not to add any extra option (such as "for secrets use env_prefix yes/no") unless it is really needed.
$ python -c "import this"|grep -E "Simple|Special cases|There should be one|hard to explain"
Simple is better than complex.
Special cases aren't special enough to break the rules.
There should be one-- and preferably only one --obvious way to do it.
If the implementation is hard to explain, it's a bad idea.
from pydantic-settings.
But, if pydantic/pydantic#2190 get merged, we won't be able to transparently prefix secrets? My stack has many services, and I would like to store secrets as /run/secrets/my_project_api_key
, but I really don't want to add my_project_
to all field names. Maybe we should have a secrets_prefix
in Config
??
from pydantic-settings.
Proposal
Keep the solution as is now - thus use the environment variable name in all situations - not only for trying to read values from env var (and from dotenv file), but also from secrets.
Action needed: update the docs to clarify this rule.
Agree. But if we go this way, then aliases passed via Field(env=...)
must honor env_prefix too. Because now they don't.
After that we will get a simple consistent rule: "env_prefix affects every setting source by default. Don't use it or create your own settings source if you want different behavior."
from pydantic-settings.
The workaround to ignore the env_prefix
for secrets is adding this method to your settings class:
@classmethod
def settings_customise_sources(
cls,
settings_cls: Type[BaseSettings],
init_settings: PydanticBaseSettingsSource,
env_settings: PydanticBaseSettingsSource,
dotenv_settings: PydanticBaseSettingsSource,
file_secret_settings: PydanticBaseSettingsSource,
) -> Tuple[PydanticBaseSettingsSource, ...]:
return init_settings, env_settings, dotenv_settings, SecretsSettingsSource(settings_cls, env_prefix=None)
from pydantic-settings.
Related Issues (20)
- Override default file in Yaml/Toml/Json ConfigSettingsSource at runtime. HOT 3
- Order dependent dict overwriting environment-variable issue HOT 4
- env_prefix doesn't follow case_sensitive flag in DotEnvSettingsSource HOT 4
- `BaseSettings` initialisation causes nested `BaseModel.model_fields_set` to be incorrect HOT 1
- Desynchronization of the extra field documentation between ConfigDict and default creation of model_config HOT 4
- want to leak non-`env_prefix`'d values from dotenv? HOT 1
- Pydantic settings not reloading env vars when .env file is updated HOT 2
- How can I use Settings().model_dump() to access property names directly instead of using a dictionary? HOT 19
- How to override nested list of dictionaries HOT 5
- Typing JsonValue field HOT 2
- env source: superflous deep env conflicts with non-dict model
- BaseSettings fails to load nested models overridden by ENV with case_senitivity=False HOT 3
- Unable to create config with submodel named "api"
- Cannot load prefixed nested model from dotenv. HOT 3
- Unable to override loading of .env with .env.testing HOT 5
- Discriminated unions with callable discriminator don't work correctly. HOT 2
- Create default templates (feature request)
- case_sensitive doesn't work in optional nested Settings models HOT 2
- Example from docs doesn't work can't import from pydantic.env_settings import SettingsSourceCallable HOT 1
- Can my custom PydanticBaseSettingsSource get values already retrieved from other PydanticBaseSettingsSources? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pydantic-settings.