### Run Vault Server and Setup Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use these commands to start a Vault server via Docker Compose and then run the setup script. The Vault server will be accessible at http://localhost:8200. ```shell docker-compose up ``` ```shell make setup-vault ``` -------------------------------- ### Customize Settings Source Priority Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Define the order in which settings sources are loaded. This example includes environment variables, Vault variables, and default values. ```python from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): """ In descending order of priority: - arguments passed to the `Settings` class initializer - environment variables - Vault variables - variables loaded from the secrets directory, such as Docker Secrets - the default field values for the `Settings` model """ @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` ```python class Settings(BaseSettings): """ In descending order of priority: - Vault variables - environment variables - variables loaded from the secrets directory, such as Docker Secrets - the default field values for the `Settings` model Here we chose to remove the "init arguments" source, and move the Vault source up before the environment source """ @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 ( VaultSettingsSource(settings_cls), env_settings, dotenv_settings, file_secret_settings, ) ``` -------------------------------- ### Install pydantic-settings-vault with pip Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use pip to install the pydantic-settings-vault package. ```shell pip install pydantic-settings-vault ``` -------------------------------- ### Install pydantic-settings-vault with poetry Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use poetry to add pydantic-settings-vault as a dependency. ```shell poetry add pydantic-settings-vault ``` -------------------------------- ### Configure JWT/OIDC Authentication for Vault Settings Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md This example demonstrates configuring settings for Vault JWT/OIDC authentication. It allows specifying the token role and token via environment variables or model_config. VaultSettingsSource must be included in settings_customise_sources. ```python from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): username: str = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_password", }, ) model_config = { "vault_url": "https://vault.tld", "vault_jwt_role": "my-role", "vault_jwt_token": SecretStr("my-token"), } @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` -------------------------------- ### Accessing Specific Vault Secrets with Field Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use Pydantic's `Field` with `json_schema_extra` to specify the Vault secret path and key. This example demonstrates accessing a 'password' from a 'secret/data/database/prod' secret in Vault. ```python password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/database/prod", "vault_secret_key": "password", }, ) ``` -------------------------------- ### AppRole Authentication with Pydantic Settings Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Set up AppRole authentication using role_id and secret_id, prioritizing environment variables over model configuration. The VAULT_ADDR must be set. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource os.environ["VAULT_ADDR"] = "https://vault.example.com" # Provide secret_id at runtime via env var for security os.environ["VAULT_SECRET_ID"] = "runtime-secret-id" class Settings(BaseSettings): db_password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/db/prod", "vault_secret_key": "password", } ) model_config = { "vault_url": "https://vault.example.com", "vault_role_id": "my-app-role-id", # safe to commit "vault_secret_id": SecretStr("fallback-id"), # overridden by VAULT_SECRET_ID env var # Optional: custom approle mount point (default: "approle") "vault_auth_mount_point": "custom-approle", } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() print(settings.db_password.get_secret_value()) # fetched via Approle auth ``` -------------------------------- ### Load Secrets from Vault using Environment Variables Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Configure Vault connection and authentication using environment variables. Fields annotated with `vault_secret_path` in `json_schema_extra` are fetched from Vault. Ensure `VaultSettingsSource` is included in `settings_customise_sources` with the desired priority. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource # Set connection/auth via environment variables (or use model_config below) os.environ["VAULT_ADDR"] = "https://vault.example.com" os.environ["VAULT_TOKEN"] = "s.mytoken" class Settings(BaseSettings): # KV v2: full path includes /data/ between mount point and secret path db_username: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp/prod", "vault_secret_key": "username", } ) db_password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp/prod", "vault_secret_key": "password", } ) # Fields without vault_secret_path are skipped by VaultSettingsSource app_name: str = "my-app" @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, ...]: # Priority: init > env > dotenv > vault > file secrets return ( init_settings, env_settings, dotenv_settings, VaultSettingsSource(settings_cls), file_secret_settings, ) settings = Settings() print(settings.db_username) # "prod_user" (from Vault) print(settings.db_password.get_secret_value()) # "s3cr3t" (from Vault) print(settings.app_name) # "my-app" (default, not from Vault) ``` -------------------------------- ### Configure Token Authentication for Vault Settings Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use this snippet to configure settings with Vault token authentication. The token can be provided via environment variables, a local file, or directly in model_config. Ensure VaultSettingsSource is included in settings_customise_sources. ```python from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): username: str = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_password", }, ) model_config = { "vault_url": "https://vault.tld", "vault_token": SecretStr("my-secret-token"), } @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` -------------------------------- ### Token Authentication with Pydantic Settings Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Configure Vault token authentication by prioritizing environment variables, then falling back to model configuration. Ensure VAULT_ADDR is set. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource # Option 1: environment variable (highest priority) os.environ["VAULT_ADDR"] = "https://vault.example.com" os.environ["VAULT_TOKEN"] = "s.myRootToken" # Option 2: model_config (used if env var is absent) class Settings(BaseSettings): api_key: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp/credentials", "vault_secret_key": "api_key", } ) model_config = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.fallbackToken"), # used if VAULT_TOKEN not set } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() # VAULT_TOKEN env var takes precedence over model_config vault_token print(settings.api_key.get_secret_value()) # secret loaded with env token ``` -------------------------------- ### Configure Vault Settings Inline with `SettingsConfigDict` Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Declare Vault connection and authentication details directly within the `model_config` using `SettingsConfigDict`. This provides IDE type-checking and auto-completion for Vault options. Ensure `VaultSettingsSource` is included in `settings_customise_sources`. ```python from typing import ClassVar from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource from pydantic_vault.entities import SettingsConfigDict class Settings(BaseSettings): secret_value: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp/config", "vault_secret_key": "api_key", } ) # All Vault config declared inline — no environment variables needed model_config: ClassVar[SettingsConfigDict] = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.mytoken"), "vault_namespace": "my-org/team-a", # Vault Enterprise namespaces "vault_certificate_verify": "/etc/ssl/certs/ca-bundle.crt", # or False to disable } @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, VaultSettingsSource(settings_cls)) settings = Settings() print(settings.secret_value) # value fetched from Vault ``` -------------------------------- ### AppRole Authentication with Pydantic Settings Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Configure settings to authenticate with Vault using the AppRole method. Provide role ID and secret ID via environment variables or model_config. Ensure VaultSettingsSource is included in settings_customise_sources. ```python from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): username: str = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_password", }, ) model_config = { "vault_url": "https://vault.tld", "vault_role_id": "my-role-id", "vault_secret_id": SecretStr("my-secret-id"), } @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` -------------------------------- ### Kubernetes Authentication with Pydantic Settings Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Configure settings to authenticate with Vault using the Kubernetes method. Provide the role via environment variables or model_config. The service account token is automatically read from the standard Kubernetes path. Ensure VaultSettingsSource is included in settings_customise_sources. ```python from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): username: str = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "path/to/secret", "vault_secret_key": "my_password", }, ) model_config = { "vault_url": "https://vault.tld", "vault_kubernetes_role": "my-role", } @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` -------------------------------- ### Dynamically Generate Vault Secret Paths with Environment Variables Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use string formatting with environment variables to dynamically generate Vault secret paths. This is useful for managing secrets across different environments. The default environment is 'dev'. ```python import os # You will need to specify the environment in an environment variable, but by # default it falls back to "dev" ENV = os.getenv("ENV", "dev") class Settings(BaseSettings): # This will load different secrets depending on the value of the ENV environment variable username: str = Field( json_schema_extra={ "vault_secret_path": f"kv/my-api/{ENV}", "vault_secret_key": "root_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": f"kv/my-api/{ENV}", "vault_secret_key": "root_password", }, ) settings = Settings() print(settings.username) # "root" print(settings.password.get_secret_value()) # "a_v3ry_s3cur3_p4ssw0rd" ``` -------------------------------- ### Load Settings from Vault with Pydantic Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Define a Pydantic settings class to load username and password from Vault. Ensure VAULT_ADDR and VAULT_TOKEN environment variables are set. The `settings_customise_sources` method prioritizes environment variables over Vault secrets. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): # The `vault_secret_path` is the full path (with mount point included) to the secret # The `vault_secret_key` is the specific key to extract from a secret username: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/path/to/secret", "vault_secret_key": "my_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/path/to/secret", "vault_secret_key": "my_password", }, ) @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, ...]: # This is where you can choose which settings sources to use and their priority return ( init_settings, env_settings, dotenv_settings, VaultSettingsSource(settings_cls), file_secret_settings, ) settings = Settings() # These variables will come from the Vault secret you configured print(settings.username) print(settings.password.get_secret_value()) # Now let's pretend we have already set the USERNAME in an environment variable # (see the Pydantic documentation for more information and to know how to configure it) # With the priority order we defined above, its value will override the Vault secret os.environ["USERNAME"] = "my user" settings = Settings() print(settings.username) # "my user", defined in the environment variable print(settings.password.get_secret_value()) # the value set in Vault ``` -------------------------------- ### Configure Pydantic Vault Debug Logging Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Enable debug logging for the 'pydantic-vault' library to aid in troubleshooting. Ensure this is set at the entry point of your application. ```python # At the beginning of your main file or entrypoint import logging logging.basicConfig() logging.getLogger("pydantic-vault").setLevel(logging.DEBUG) # Change the log level here ``` -------------------------------- ### Kubernetes Authentication with Pydantic Settings Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Enable Kubernetes authentication by configuring the role name, which can be set via environment variables or model configuration. The JWT is read automatically from the service account. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource # In a Kubernetes pod, VAULT_ADDR is typically injected by the Vault agent os.environ["VAULT_ADDR"] = "https://vault.example.com" os.environ["VAULT_KUBERNETES_ROLE"] = "my-k8s-app-role" class Settings(BaseSettings): db_url: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/k8s/db", "vault_secret_key": "connection_string", } ) model_config = { "vault_url": "https://vault.example.com", # Alternative to env var: set role in model_config # "vault_kubernetes_role": "my-k8s-app-role", # Optional: custom kubernetes mount point (default: "kubernetes") # "vault_auth_mount_point": "k8s-cluster-prod", } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) # In a running Kubernetes pod this will transparently use the service account token settings = Settings() print(settings.db_url) # "postgresql://user:pass@db.internal/mydb" ``` -------------------------------- ### JWT/OIDC Authentication with Vault Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Configure Pydantic settings to authenticate with Vault using JWT/OIDC. Set environment variables or model_config for role, token, and auth path. Requires `pydantic-vault` and `pydantic-settings`. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource os.environ["VAULT_ADDR"] = "https://vault.example.com" os.environ["VAULT_JWT_ROLE"] = "my-jwt-role" os.environ["VAULT_JWT_TOKEN"] = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." class Settings(BaseSettings): service_password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/ci/credentials", "vault_secret_key": "service_password", } ) model_config = { "vault_url": "https://vault.example.com", # Optional: custom JWT auth path (e.g., for GitLab CI OIDC) "vault_auth_path": "jwt/gitlab", # Can also set role/token inline: # "vault_jwt_role": "my-jwt-role", # "vault_jwt_token": SecretStr("eyJ..."), } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() print(settings.service_password.get_secret_value()) # secret via JWT auth ``` -------------------------------- ### Dynamic Secret Paths with Environment Variables Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Compute Vault secret paths at module load time using Python string formatting. This allows environment-specific routing with a single Settings class definition. Ensure the `APP_ENV` environment variable is set to 'dev', 'staging', or 'prod'. ```python import os from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource ENV = os.getenv("APP_ENV", "dev") # "dev", "staging", or "prod" class Settings(BaseSettings): db_username: str = Field( json_schema_extra={ "vault_secret_path": f"secret/data/myapp/{ENV}", "vault_secret_key": "db_username", } ) db_password: SecretStr = Field( json_schema_extra={ "vault_secret_path": f"secret/data/myapp/{ENV}", "vault_secret_key": "db_password", } ) model_config = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.mytoken"), } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) # APP_ENV=prod → reads from secret/data/myapp/prod # APP_ENV=dev → reads from secret/data/myapp/dev settings = Settings() print(f"[{ENV}] db_username:", settings.db_username) ``` -------------------------------- ### Enabling Debug Logging for Vault Operations Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Enable debug logging for the 'pydantic-vault' logger to trace credential discovery and authentication steps. Set the logger level to `DEBUG` for detailed output, or `WARNING` to surface only authentication failures. ```python import logging from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource # Enable debug logging to trace credential resolution logging.basicConfig(level=logging.DEBUG) logging.getLogger("pydantic-vault").setLevel(logging.DEBUG) class Settings(BaseSettings): secret: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp/config", "vault_secret_key": "some_key", } ) model_config = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.mytoken"), } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() # DEBUG output example: # pydantic-vault: Found Vault Address 'https://vault.example.com' in model_config # pydantic-vault: Found Vault Token in model_config # INFO pydantic-vault: Connecting to Vault 'https://vault.example.com' with method 'Vault Token' ``` -------------------------------- ### Configure Vault Credentials in model_config Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Alternatively, declare Vault connection details like URL and token directly within the `Settings.model_config` dictionary. This approach embeds credentials within the code, which may be less secure than environment variables. ```python ... class Settings(BaseSettings): ... model_config = { "vault_url": "https://vault.tld", "vault_token": "my-vault-token", } ... ``` -------------------------------- ### Retrieving Whole Secrets from Vault Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Load entire secrets as dicts or Pydantic models by omitting `vault_secret_key`. Useful for dynamic secrets or complex configurations. Requires `pydantic-vault` and `pydantic-settings`. ```python from pydantic import BaseModel, Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class DbCredentials(BaseModel): username: str password: SecretStr class Settings(BaseSettings): # Load dynamic DB credentials as a validated BaseModel (single Vault read) db_creds: DbCredentials = Field( json_schema_extra={"vault_secret_path": "database/creds/my-db-role"} ) # Load an entire KV v2 secret as a raw dict app_config: dict = Field( json_schema_extra={"vault_secret_path": "secret/data/myapp/config"} ) model_config = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.mytoken"), } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() # Dynamic DB credentials — username and password come from the SAME Vault call print(settings.db_creds.username) # "v-approle-mydb-abc123" print(settings.db_creds.password.get_secret_value()) # "A1B2C3-generated-password" # Full config dict print(settings.app_config) # {"feature_flag": "true", "max_connections": "100", ...} ``` -------------------------------- ### Retrieve Dynamic Database Secrets with Pydantic Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use this snippet to retrieve dynamic database credentials generated by Vault. Ensure `vault_secret_key` is not provided to fetch the entire secret at once. Supports storing credentials in a dict or a custom BaseModel. ```python class DbCredentials(BaseModel): username: str password: SecretStr class Settings(BaseSettings): # The `vault_secret_path` is the full path (with mount point included) to the secret. # For a database secret engine, the secret path is `/creds/`. # For example if your mount point is `database/` (the default) and your role name is # `my-db-prod`, the full path to use is `database/creds/my-db-prod`. You will receive # `username` and `password` fields in response. # You must *not* pass a `vault_secret_key` so that pydantic-settings-vault fetches both fields at once. db_creds: DbCredentials = Field( json_schema_extra={"vault_secret_path": "database/creds/my-db-prod"} ) db_creds_in_dict: dict = Field( json_schema_extra={"vault_secret_path": "database/creds/my-db-prod"} ) settings = Settings() print(settings.db_creds.username) # "generated-username-1" print( settings.db_creds.password.get_secret_value() ) # "generated-password-for-username-1" print(settings.db_creds_in_dict["username"]) # "generated-username-2" print(settings.db_creds_in_dict["password"]) # "generated-password-for-username-2" ``` -------------------------------- ### Retrieve Secrets from Vault KV v2 Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Define a Pydantic settings model to retrieve specific keys from a Vault KV v2 secret engine. Requires `vault_secret_path` and `vault_secret_key` in `json_schema_extra`. ```python from pydantic import Field from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): ############################################### # THIS PART CHANGES IN THE DIFFERENT EXAMPLES # username: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/path/to/secret", "vault_secret_key": "my_user", }, ) ############################################### model_config = {"vault_url": "https://vault.tld"} @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, VaultSettingsSource(settings_cls), file_secret_settings, ) ``` ```python class Settings(BaseSettings): # The `vault_secret_path` is the full path (with mount point included) to the secret. # For a KV v2 secret engine, there is always a `data/` sub-path between the mount point and # the secret actual path, eg. if your mount point is `secret/` (the default) and your secret # path is `my-api/prod`, the full path to use is `secret/data/my-api/prod`. # The `vault_secret_key` is the specific key to extract from a secret. username: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/my-api/prod", "vault_secret_key": "root_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "secret/data/my-api/prod", "vault_secret_key": "root_password", }, ) settings = Settings() print(settings.username) # "root" print(settings.password.get_secret_value()) # "a_v3ry_s3cur3_p4ssw0rd" ``` -------------------------------- ### Retrieve Entire Secret into a Pydantic Model Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Load all key-value pairs from a secret and parse them into a Pydantic model for validation. Omit `vault_secret_key` and define a Pydantic model for the expected structure. ```python class Credentials(BaseModel): root_user: str root_password: SecretStr class Settings(BaseSettings): credentials: Credentials = Field( json_schema_extra={"vault_secret_path": "secret/data/my-api/prod"} ) settings = Settings() print(settings.credentials.root_user) # "root" print(settings.credentials.root_password.get_secret_value()) # "a_v3ry_s3cur3_p4ssw0rd" ``` -------------------------------- ### Retrieve Entire Secret into a Dictionary Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use this when you need to load all key-value pairs from a secret into a dictionary field. Ensure `vault_secret_key` is omitted in the Field configuration. ```python class Settings(BaseSettings): credentials: dict = Field( json_schema_extra={"vault_secret_path": "secret/data/my-api/prod"} ) settings = Settings() print( settings.credentials ) # { "root_user": "root", "root_password": "a_v3ry_s3cur3_p4ssw0rd" } ``` -------------------------------- ### Retrieve Specific Secret Key from KV v1 Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Use this to fetch a single value from a KV v1 secret engine. Specify both `vault_secret_path` and `vault_secret_key` in the Field configuration. ```python class Settings(BaseSettings): username: str = Field( json_schema_extra={ "vault_secret_path": "kv/my-api/prod", "vault_secret_key": "root_user", }, ) password: SecretStr = Field( json_schema_extra={ "vault_secret_path": "kv/my-api/prod", "vault_secret_key": "root_password", }, ) settings = Settings() print(settings.username) # "root" print(settings.password.get_secret_value()) # "a_v3ry_s3cur3_p4ssw0rd" ``` -------------------------------- ### Handling Missing Vault URL with VaultParameterError Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Catch `VaultParameterError` when no Vault URL is provided via `VAULT_ADDR` environment variable or `vault_url` in `model_config`. This exception inherits from `PydanticVaultException` and `ValueError`. ```python import pytest from pydantic import Field from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource, VaultParameterError class Settings(BaseSettings): secret: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/myapp", "vault_secret_key": "value", } ) # No vault_url in model_config and no VAULT_ADDR env var set @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) try: settings = Settings() except VaultParameterError as e: print(f"Configuration error: {e}") # "Configuration error: No URL provided to connect to Vault" ``` -------------------------------- ### KV v1 Secret Engine Integration Source: https://context7.com/aleksey925/pydantic-settings-vault/llms.txt Access secrets from KV v1 engines using the mount point directly in `vault_secret_path`. Be aware of potential key conflicts if a secret contains a key named 'data'. Requires `pydantic-vault` and `pydantic-settings`. ```python from pydantic import Field, SecretStr from pydantic_settings import BaseSettings, PydanticBaseSettingsSource from pydantic_vault import VaultSettingsSource class Settings(BaseSettings): # KV v1: path is / (no /data/ infix) legacy_api_key: str = Field( json_schema_extra={ "vault_secret_path": "kv/myapp/prod", # mount="kv", secret="myapp/prod" "vault_secret_key": "api_key", } ) legacy_db_pass: SecretStr = Field( json_schema_extra={ "vault_secret_path": "kv/myapp/prod", "vault_secret_key": "db_password", } ) model_config = { "vault_url": "https://vault.example.com", "vault_token": SecretStr("s.mytoken"), } @classmethod def settings_customise_sources(cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings): return (init_settings, env_settings, VaultSettingsSource(settings_cls)) settings = Settings() print(settings.legacy_api_key) # "abc-legacy-key" print(settings.legacy_db_pass.get_secret_value()) # "legacy-db-pass" ``` -------------------------------- ### Vault Parameters Ignored in Nested Pydantic Models Source: https://github.com/aleksey925/pydantic-settings-vault/blob/master/README.md Demonstrates that `vault_secret_path` and `vault_secret_key` are only processed for top-level fields in a `Settings` class. Vault parameters within nested Pydantic models are ignored. ```python class DatabaseConfig(BaseModel): # This will NOT work - vault_secret_path is ignored in nested models! username: str = Field( json_schema_extra={ "vault_secret_path": "secret/data/db", "vault_secret_key": "user", }, ) class Settings(BaseSettings): db: DatabaseConfig # vault_secret_path inside DatabaseConfig is not processed ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.