You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Setting env. variables for auth config is awkward, so python-dotenv can be used to load them from a .env text file instead
Keyrings can be preferable to plain text secret storage for security, and Python has a keyring module [source]
These recommended keyring backends are supported:
macOS Keychain
Freedesktop Secret Service supports many DE including GNOME (requires secretstorage)
KDE4 & KDE5 KWallet (requires dbus)
Windows Credential Locker
This practice is used by other well known tools such as the GitHub CLI tool gh and twine[source]
Where Twine gets configuration and credentials
A user can set the repository URL, username, and/or password via command line, .pypirc files, environment variables, and keyring.
This could be made an optional dependency if desired (perhaps to keep package size minimal/consistent).
Impact
When I pip install keyring on Linux after first installing pydantic and pydantic-settings the additional dependencies are:
The gh tool sets the username to an empty string, indicating that it's used as a simple key-value secret store.
You can also access specific keyrings, also known as 'collections' (for instance if you wanted to have different applications using different keys with the same name, say a different API key for different services). For reference
Proposed implementation
Essentially we are replacing os.environ.get(validation_alias) for keyring.get_password(validation_alias)
In this library, both environment variables and .env configured variables are loaded into the env_vars attribute.
EnvSettingsSource calls _load_env_vars() at initialisation:
Since @hramezani already replied on the PR I'll assign him here, but in general I think it makes sense for us to support/maintain this if you are willing to provide an initial implementation. (And it seems like you are — thank you!)
Outline
Setting env. variables for auth config is awkward, so
python-dotenv
can be used to load them from a.env
text file insteadKeyrings can be preferable to plain text secret storage for security, and Python has a
keyring
module [source]This practice is used by other well known tools such as the GitHub CLI tool
gh
andtwine
[source]This could be made an optional dependency if desired (perhaps to keep package size minimal/consistent).
Impact
When I
pip install keyring
on Linux after first installingpydantic
andpydantic-settings
the additional dependencies are:Usage
Once installed, secret access is achieved like so:
The
gh
tool sets the username to an empty string, indicating that it's used as a simple key-value secret store.You can also access specific keyrings, also known as 'collections' (for instance if you wanted to have different applications using different keys with the same name, say a different API key for different services). For reference
Proposed implementation
Essentially we are replacing
os.environ.get(validation_alias)
forkeyring.get_password(validation_alias)
In this library, both environment variables and
.env
configured variables are loaded into theenv_vars
attribute.EnvSettingsSource
calls_load_env_vars()
at initialisation:pydantic-settings/pydantic_settings/sources.py
Lines 376 to 381 in 5933ea6
DotEnvSettingsSource
subclassesEnvSettingsSource
and overrides the_load_env_vars()
methodpydantic-settings/pydantic_settings/sources.py
Lines 571 to 590 in 5933ea6
I would have this work similarly to
.env
handling with a subclass exposing a custom way to load env vars.We can enumerate all keys (as bytes) via:
(In real code you'd have to have some error handling in case the 3 chained methods error!)
I think default conversion of bytes to str type would be reasonable here?
Proof of concept
The attached PR supplies a working implementation of this feature on Linux, using the
SecretStorage
backend.This is overridden by setting an environment variable.
Selected Assignee: @dmontagu
The text was updated successfully, but these errors were encountered: