Skip to content

Commit 79a369b

Browse files
committed
Add support for AWS Secrets Manager
1 parent 65929cd commit 79a369b

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

pydantic_settings/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .main import BaseSettings, CliApp, SettingsConfigDict
22
from .sources import (
33
CLI_SUPPRESS,
4+
AWSSecretsManagerSettingsSource,
45
AzureKeyVaultSettingsSource,
56
CliExplicitFlag,
67
CliImplicitFlag,
@@ -50,6 +51,7 @@
5051
'TomlConfigSettingsSource',
5152
'YamlConfigSettingsSource',
5253
'AzureKeyVaultSettingsSource',
54+
'AWSSecretsManagerSettingsSource',
5355
'get_subcommand',
5456
'__version__',
5557
)

pydantic_settings/sources.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,17 @@ def import_azure_key_vault() -> None:
108108
) from e
109109

110110

111+
def import_aws_secrets_manager() -> None:
112+
global boto3_client
113+
114+
try:
115+
from boto3 import client as boto3_client
116+
except ImportError as e:
117+
raise ImportError(
118+
'AWS Secrets Manager dependencies are not installed, run `pip install pydantic-settings[aws-secrets-manager]`'
119+
) from e
120+
121+
111122
DotenvType = Union[Path, str, Sequence[Union[Path, str]]]
112123
PathType = Union[Path, str, Sequence[Union[Path, str]]]
113124
DEFAULT_PATH: PathType = Path('')
@@ -2237,6 +2248,40 @@ def __repr__(self) -> str:
22372248
return f'{self.__class__.__name__}(url={self._url!r}, ' f'env_nested_delimiter={self.env_nested_delimiter!r})'
22382249

22392250

2251+
class AWSSecretsManagerSettingsSource(EnvSettingsSource):
2252+
_secret_id: str
2253+
_secretsmanager_client: SecretClient # type: ignore
2254+
2255+
def __init__(
2256+
self,
2257+
settings_cls: type[BaseSettings],
2258+
secret_id: str,
2259+
env_prefix: str | None = None,
2260+
env_parse_none_str: str | None = None,
2261+
env_parse_enums: bool | None = None,
2262+
) -> None:
2263+
import_aws_secrets_manager()
2264+
self._secretsmanager_client = boto3_client('secretsmanager')
2265+
self._secret_id = secret_id
2266+
super().__init__(
2267+
settings_cls,
2268+
case_sensitive=True,
2269+
env_prefix=env_prefix,
2270+
env_nested_delimiter='--',
2271+
env_ignore_empty=False,
2272+
env_parse_none_str=env_parse_none_str,
2273+
env_parse_enums=env_parse_enums,
2274+
)
2275+
2276+
def _load_env_vars(self) -> Mapping[str, Optional[str]]:
2277+
response = self._secretsmanager_client.get_secret_value(SecretId=self._secret_id)
2278+
2279+
return json.loads(response['SecretString'])
2280+
2281+
def __repr__(self) -> str:
2282+
return f'{self.__class__.__name__}(secret_id={self._secret_id!r}, ' f'env_nested_delimiter={self.env_nested_delimiter!r})'
2283+
2284+
22402285
def _get_env_var_key(key: str, case_sensitive: bool = False) -> str:
22412286
return key if case_sensitive else key.lower()
22422287

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ dynamic = ['version']
5050
yaml = ["pyyaml>=6.0.1"]
5151
toml = ["tomli>=2.0.1"]
5252
azure-key-vault = ["azure-keyvault-secrets>=4.8.0", "azure-identity>=1.16.0"]
53+
aws-secrets-manager = ["boto3>=1.35.98"]
5354

5455
[project.urls]
5556
Homepage = 'https://github.com/pydantic/pydantic-settings'

0 commit comments

Comments
 (0)