Skip to content

Commit 1ee6624

Browse files
authored
Expose AWS Secrets Manager case sensitive option (#629)
1 parent 180e74e commit 1ee6624

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

pydantic_settings/sources/providers/aws.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from collections.abc import Mapping
55
from typing import TYPE_CHECKING, Optional
66

7+
from ..utils import parse_env_vars
78
from .env import EnvSettingsSource
89

910
if TYPE_CHECKING:
@@ -36,6 +37,7 @@ def __init__(
3637
settings_cls: type[BaseSettings],
3738
secret_id: str,
3839
region_name: str | None = None,
40+
case_sensitive: bool | None = True,
3941
env_prefix: str | None = None,
4042
env_parse_none_str: str | None = None,
4143
env_parse_enums: bool | None = None,
@@ -45,7 +47,7 @@ def __init__(
4547
self._secret_id = secret_id
4648
super().__init__(
4749
settings_cls,
48-
case_sensitive=True,
50+
case_sensitive=case_sensitive,
4951
env_prefix=env_prefix,
5052
env_nested_delimiter='--',
5153
env_ignore_empty=False,
@@ -56,7 +58,12 @@ def __init__(
5658
def _load_env_vars(self) -> Mapping[str, Optional[str]]:
5759
response = self._secretsmanager_client.get_secret_value(SecretId=self._secret_id) # type: ignore
5860

59-
return json.loads(response['SecretString'])
61+
return parse_env_vars(
62+
json.loads(response['SecretString']),
63+
self.case_sensitive,
64+
self.env_ignore_empty,
65+
self.env_parse_none_str,
66+
)
6067

6168
def __repr__(self) -> str:
6269
return (

tests/test_source_aws_secrets_manager.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,43 @@ class AWSSecretsManagerSettings(BaseSettings):
8888
assert settings['SqlServerUser'] == 'test-user'
8989
assert settings['SqlServer']['Password'] == 'test-password'
9090

91+
@mock_aws
92+
def test_secret_manager_case_insensitive_success(self) -> None:
93+
"""Test secret manager getitem case insensitive success."""
94+
95+
class SqlServer(BaseModel):
96+
password: str = Field(..., alias='Password')
97+
98+
class AWSSecretsManagerSettings(BaseSettings):
99+
"""AWSSecretsManager settings."""
100+
101+
sql_server_user: str
102+
sql_server: SqlServer
103+
104+
@classmethod
105+
def settings_customise_sources(
106+
cls,
107+
settings_cls: type[BaseSettings],
108+
init_settings: PydanticBaseSettingsSource,
109+
env_settings: PydanticBaseSettingsSource,
110+
dotenv_settings: PydanticBaseSettingsSource,
111+
file_secret_settings: PydanticBaseSettingsSource,
112+
) -> tuple[PydanticBaseSettingsSource, ...]:
113+
return (AWSSecretsManagerSettingsSource(settings_cls, 'test-secret', case_sensitive=False),)
114+
115+
secret_data = {
116+
'SQL_SERVER_USER': 'test-user',
117+
'SQL_SERVER--PASSWORD': 'test-password',
118+
}
119+
120+
client = boto3.client('secretsmanager')
121+
client.create_secret(Name='test-secret', SecretString=json.dumps(secret_data))
122+
123+
settings = AWSSecretsManagerSettings() # type: ignore
124+
125+
assert settings.sql_server_user == 'test-user'
126+
assert settings.sql_server.password == 'test-password'
127+
91128
@mock_aws
92129
def test_aws_secrets_manager_settings_source(self) -> None:
93130
"""Test AWSSecretsManagerSettingsSource."""

0 commit comments

Comments
 (0)