diff --git a/docs/index.md b/docs/index.md index 117e37f2..1ef6a8b3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -416,6 +416,7 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (MyCustomSource(settings_cls),) @@ -749,6 +750,7 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return env_settings, CliSettingsSource(settings_cls, cli_parse_args=True) @@ -1817,6 +1819,7 @@ class AWSSecretsManagerSettings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: aws_secrets_manager_settings = AWSSecretsManagerSettingsSource( settings_cls, @@ -1920,6 +1923,7 @@ class AzureKeyVaultSettings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: az_key_vault_settings = AzureKeyVaultSettingsSource( settings_cls, @@ -1983,6 +1987,7 @@ To use Google Cloud Secret Manager, you need to: env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: # Create the GCP Secret Manager settings source gcp_settings = GoogleSecretManagerSettingsSource( @@ -2000,6 +2005,7 @@ To use Google Cloud Secret Manager, you need to: env_settings, dotenv_settings, file_secret_settings, + loadcredential_settings, gcp_settings, ) ``` @@ -2072,6 +2078,7 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (TomlConfigSettingsSource(settings_cls),) ``` @@ -2115,6 +2122,7 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (PyprojectTomlConfigSettingsSource(settings_cls),) @@ -2177,6 +2185,7 @@ class DiscoverSettings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (PyprojectTomlConfigSettingsSource(settings_cls),) @@ -2194,6 +2203,7 @@ class ExplicitFilePathSettings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( PyprojectTomlConfigSettingsSource( @@ -2245,8 +2255,14 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: - return env_settings, init_settings, file_secret_settings + return ( + env_settings, + init_settings, + file_secret_settings, + loadcredential_settings, + ) print(Settings(database_dsn='postgres://postgres@localhost:5432/kwargs_db')) @@ -2327,12 +2343,14 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( init_settings, JsonConfigSettingsSource(settings_cls), env_settings, file_secret_settings, + loadcredential_settings, ) @@ -2391,9 +2409,10 @@ class Settings(BaseSettings): env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: # here we choose to ignore arguments from init_settings - return env_settings, file_secret_settings + return env_settings, file_secret_settings, loadcredential_settings try: diff --git a/pydantic_settings/main.py b/pydantic_settings/main.py index 66cfbe90..5baf0d00 100644 --- a/pydantic_settings/main.py +++ b/pydantic_settings/main.py @@ -14,6 +14,8 @@ from pydantic.dataclasses import is_pydantic_dataclass from pydantic.main import BaseModel +from pydantic_settings.sources.providers.loadcredential import LoadCredentialSettingsSource + from .exceptions import SettingsError from .sources import ( ENV_FILE_SENTINEL, @@ -220,6 +222,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: """ Define the sources and their order for loading the settings values. @@ -234,7 +237,7 @@ def settings_customise_sources( Returns: A tuple containing the sources and their order for loading the settings values. """ - return init_settings, env_settings, dotenv_settings, file_secret_settings + return init_settings, env_settings, dotenv_settings, file_secret_settings, loadcredential_settings def _settings_build_values( self, @@ -374,6 +377,10 @@ def _settings_build_values( file_secret_settings = SecretsSettingsSource( self.__class__, secrets_dir=secrets_dir, case_sensitive=case_sensitive, env_prefix=env_prefix ) + + loadcredential_settings = LoadCredentialSettingsSource( + self.__class__, case_sensitive=case_sensitive, env_prefix=env_prefix + ) # Provide a hook to set built-in sources priority and add / remove sources sources = self.settings_customise_sources( self.__class__, @@ -381,6 +388,7 @@ def _settings_build_values( env_settings=env_settings, dotenv_settings=dotenv_settings, file_secret_settings=file_secret_settings, + loadcredential_settings=loadcredential_settings, ) + (default_settings,) if not any([source for source in sources if isinstance(source, CliSettingsSource)]): if isinstance(cli_settings_source, CliSettingsSource): diff --git a/pydantic_settings/sources/providers/__init__.py b/pydantic_settings/sources/providers/__init__.py index 31759f33..522f1906 100644 --- a/pydantic_settings/sources/providers/__init__.py +++ b/pydantic_settings/sources/providers/__init__.py @@ -15,6 +15,7 @@ from .env import EnvSettingsSource from .gcp import GoogleSecretManagerSettingsSource from .json import JsonConfigSettingsSource +from .loadcredential import LoadCredentialSettingsSource from .pyproject import PyprojectTomlConfigSettingsSource from .secrets import SecretsSettingsSource from .toml import TomlConfigSettingsSource @@ -34,6 +35,7 @@ 'EnvSettingsSource', 'GoogleSecretManagerSettingsSource', 'JsonConfigSettingsSource', + 'LoadCredentialSettingsSource', 'PyprojectTomlConfigSettingsSource', 'SecretsSettingsSource', 'TomlConfigSettingsSource', diff --git a/pydantic_settings/sources/providers/loadcredential.py b/pydantic_settings/sources/providers/loadcredential.py new file mode 100644 index 00000000..ae2678d7 --- /dev/null +++ b/pydantic_settings/sources/providers/loadcredential.py @@ -0,0 +1,118 @@ +"""LoadCredential settings source""" + +from __future__ import annotations as _annotations + +import os +import warnings +from pathlib import Path +from typing import TYPE_CHECKING, Any + +from pydantic.fields import FieldInfo + +from pydantic_settings.utils import path_type_label + +from ...exceptions import SettingsError +from ..base import PydanticBaseEnvSettingsSource + +if TYPE_CHECKING: + from pydantic_settings.main import BaseSettings + + +class LoadCredentialSettingsSource(PydanticBaseEnvSettingsSource): + """ + Source class for loading settings values from secret files. + """ + + def __init__( + self, + settings_cls: type[BaseSettings], + case_sensitive: bool | None = None, + env_prefix: str | None = None, + env_ignore_empty: bool | None = None, + env_parse_none_str: str | None = None, + env_parse_enums: bool | None = None, + ) -> None: + super().__init__( + settings_cls, + case_sensitive, + env_prefix, + env_ignore_empty, + env_parse_none_str, + env_parse_enums, + ) + self.secrets_dir = os.environ.get('CREDENTIALS_DIRECTORY') + + def __call__(self) -> dict[str, Any]: + """ + Build fields from "secrets" files. + """ + secrets: dict[str, str | None] = {} + + if self.secrets_dir is None: + return secrets + + self.secrets_path = Path(self.secrets_dir) + + if not self.secrets_path.exists(): + warnings.warn(f'directory "{self.secrets_path}" does not exist') + return secrets + + if not self.secrets_path.is_dir(): + raise SettingsError( + f'secrets_dir must reference a directory, not a {path_type_label(self.secrets_path)}' + ) + + return super().__call__() + + @classmethod + def find_case_path( + cls, dir_path: Path, file_name: str, case_sensitive: bool + ) -> Path | None: + """ + Find a file within path's directory matching filename, optionally ignoring case. + + Args: + dir_path: Directory path. + file_name: File name. + case_sensitive: Whether to search for file name case sensitively. + + Returns: + Whether file path or `None` if file does not exist in directory. + """ + for f in dir_path.iterdir(): + if f.name == file_name: + return f + elif not case_sensitive and f.name.lower() == file_name.lower(): + return f + return None + + def get_field_value( + self, field: FieldInfo, field_name: str + ) -> tuple[Any, str, bool]: + """ + Gets the value for field from credentials and a flag to determine whether value is complex. + + Args: + field: The field. + field_name: The field name. + + Returns: + A tuple that contains the value (`None` if the credential does not exist), key, and + a flag to determine whether value is complex. + """ + + for field_key, env_name, value_is_complex in self._extract_field_info( + field, field_name + ): + path = self.find_case_path(self.secrets_path, env_name, self.case_sensitive) + + if path: + if path.is_file(): + return path.read_text().strip(), field_key, value_is_complex + else: + warnings.warn( + f'attempted to load credential "{path}" but found a {path_type_label(path)} instead of a file.', + stacklevel=4, + ) + + return None, field_key, value_is_complex diff --git a/tests/test_settings.py b/tests/test_settings.py index a7bd86c3..201ce403 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -251,6 +251,20 @@ class Settings(BaseSettings): assert s.apple == 'bongusta', 'Expected alias value to be prioritized.' +def test_loadcredential(tmp_path, env): + class Settings(BaseSettings): + apple: str + + with pytest.raises(ValidationError): + Settings() + p = tmp_path / "credentials" + p.mkdir() + env.set('CREDENTIALS_DIRECTORY', p) + (p / "apple").write_text('honeycrisp') + s = Settings() + assert s.apple == 'honeycrisp' + + def test_with_prefix(env): class Settings(BaseSettings): apple: str @@ -643,9 +657,9 @@ class Settings(BaseSettings, env_nested_delimiter='__', nested_model_default_par @classmethod def settings_customise_sources( - cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings + cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings, loadcredential_settings ): - return env_settings, dotenv_settings, init_settings, file_secret_settings + return env_settings, dotenv_settings, init_settings, file_secret_settings, loadcredential_settings env.set('SUB_MODEL__DEEP__V4', 'override-v4') @@ -944,6 +958,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return env_settings, init_settings @@ -975,6 +990,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return env_settings, init_settings, nornir_settings_source @@ -1809,12 +1825,14 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( init_settings, env_settings, dotenv_settings, file_secret_settings, + loadcredential_settings, external_source_0, external_source_1, ) @@ -1855,12 +1873,14 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( init_settings, env_settings, dotenv_settings, file_secret_settings, + loadcredential_settings, VaultSettingsSource(settings_cls, user='user', password='password'), ) @@ -1931,6 +1951,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (CustomEnvSettingsSource(settings_cls),) @@ -1959,6 +1980,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (BadCustomEnvSettingsSource(settings_cls),) @@ -1993,6 +2015,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (CustomSecretsSettingsSource(settings_cls, tmp_path),) @@ -2017,6 +2040,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (BadCustomSettingsSource(settings_cls),) @@ -2808,6 +2832,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (env_settings, SettingsSource(settings_cls)) @@ -2849,6 +2874,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (env_settings, init_settings, function_settings_source, SettingsSource(settings_cls)) diff --git a/tests/test_source_aws_secrets_manager.py b/tests/test_source_aws_secrets_manager.py index 46160070..26c06635 100644 --- a/tests/test_source_aws_secrets_manager.py +++ b/tests/test_source_aws_secrets_manager.py @@ -109,6 +109,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (AWSSecretsManagerSettingsSource(settings_cls, 'test-secret'),) diff --git a/tests/test_source_azure_key_vault.py b/tests/test_source_azure_key_vault.py index 89f48add..7c71dbd4 100644 --- a/tests/test_source_azure_key_vault.py +++ b/tests/test_source_azure_key_vault.py @@ -125,6 +125,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( AzureKeyVaultSettingsSource( @@ -176,6 +177,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return ( AzureKeyVaultSettingsSource( diff --git a/tests/test_source_cli.py b/tests/test_source_cli.py index 5d711fe1..51e31519 100644 --- a/tests/test_source_cli.py +++ b/tests/test_source_cli.py @@ -204,6 +204,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return env_settings, CliSettingsSource(settings_cls, cli_parse_args=['--foo', 'FOO FROM CLI']) @@ -2516,6 +2517,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (CliSettingsSource(settings_cls),) diff --git a/tests/test_source_gcp_secret_manager.py b/tests/test_source_gcp_secret_manager.py index e43c45ad..efb298b8 100644 --- a/tests/test_source_gcp_secret_manager.py +++ b/tests/test_source_gcp_secret_manager.py @@ -165,6 +165,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: google_secret_manager_settings = GoogleSecretManagerSettingsSource( settings_cls, secret_client=mock_secret_client @@ -174,6 +175,7 @@ def settings_customise_sources( env_settings, dotenv_settings, file_secret_settings, + loadcredential_settings, google_secret_manager_settings, ) @@ -196,6 +198,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: google_secret_manager_settings = GoogleSecretManagerSettingsSource( settings_cls, secret_client=mock_secret_client @@ -205,6 +208,7 @@ def settings_customise_sources( env_settings, dotenv_settings, file_secret_settings, + loadcredential_settings, google_secret_manager_settings, ) diff --git a/tests/test_source_json.py b/tests/test_source_json.py index b86ced6b..408b0427 100644 --- a/tests/test_source_json.py +++ b/tests/test_source_json.py @@ -46,6 +46,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (JsonConfigSettingsSource(settings_cls),) @@ -66,6 +67,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (JsonConfigSettingsSource(settings_cls),) @@ -94,6 +96,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (JsonConfigSettingsSource(settings_cls, json_file=[p5, p6]),) diff --git a/tests/test_source_toml.py b/tests/test_source_toml.py index 4f1b648f..25fb5b7e 100644 --- a/tests/test_source_toml.py +++ b/tests/test_source_toml.py @@ -54,6 +54,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (TomlConfigSettingsSource(settings_cls),) @@ -75,6 +76,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (TomlConfigSettingsSource(settings_cls),) @@ -109,6 +111,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (TomlConfigSettingsSource(settings_cls, toml_file=[p1, p2]),) diff --git a/tests/test_source_yaml.py b/tests/test_source_yaml.py index fdedc39a..a7499aba 100644 --- a/tests/test_source_yaml.py +++ b/tests/test_source_yaml.py @@ -47,6 +47,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),) @@ -83,6 +84,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),) @@ -104,6 +106,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),) @@ -127,6 +130,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),) @@ -161,6 +165,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls, yaml_file=[p3, p4]),) @@ -192,6 +197,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),) @@ -223,6 +229,7 @@ def settings_customise_sources( env_settings: PydanticBaseSettingsSource, dotenv_settings: PydanticBaseSettingsSource, file_secret_settings: PydanticBaseSettingsSource, + loadcredential_settings: PydanticBaseSettingsSource, ) -> tuple[PydanticBaseSettingsSource, ...]: return (YamlConfigSettingsSource(settings_cls),)