Skip to content

Commit 41f3413

Browse files
zaphod72Darren Kennedy
andauthored
bugfix: Return None for inaccessible GCP Secret Manager secrets (#712)
Co-authored-by: Darren Kennedy <[email protected]>
1 parent 7b924d2 commit 41f3413

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

pydantic_settings/sources/providers/gcp.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ def __getitem__(self, key: str) -> str | None:
7575
name=self._secret_version_path(key)
7676
).payload.data.decode('UTF-8')
7777
except Exception:
78-
raise KeyError(key)
78+
# If we can't access the secret, we return None
79+
self._loaded_secrets[key] = None
7980

8081
return self._loaded_secrets[key]
8182

tests/test_source_gcp_secret_manager.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ def test_secret_manager_mapping_getitem_access_error(self, secret_manager_mappin
112112
side_effect=Exception('Access denied')
113113
)
114114

115-
with pytest.raises(KeyError):
116-
_ = secret_manager_mapping['test-secret']
115+
assert secret_manager_mapping['test-secret'] is None
117116

118117
def test_secret_manager_mapping_iter(self, secret_manager_mapping):
119118
assert list(secret_manager_mapping) == ['test-secret']
@@ -210,3 +209,36 @@ def settings_customise_sources(
210209

211210
with pytest.raises(ValidationError):
212211
_ = Settings()
212+
213+
def test_pydantic_base_settings_with_default_value(self, mock_secret_client):
214+
class Settings(BaseSettings):
215+
my_field: str | None = Field(default='foo')
216+
217+
@classmethod
218+
def settings_customise_sources(
219+
cls,
220+
settings_cls: type[BaseSettings],
221+
init_settings: PydanticBaseSettingsSource,
222+
env_settings: PydanticBaseSettingsSource,
223+
dotenv_settings: PydanticBaseSettingsSource,
224+
file_secret_settings: PydanticBaseSettingsSource,
225+
) -> tuple[PydanticBaseSettingsSource, ...]:
226+
google_secret_manager_settings = GoogleSecretManagerSettingsSource(
227+
settings_cls, secret_client=mock_secret_client
228+
)
229+
return (
230+
init_settings,
231+
env_settings,
232+
dotenv_settings,
233+
file_secret_settings,
234+
google_secret_manager_settings,
235+
)
236+
237+
settings = Settings()
238+
assert settings.my_field == 'foo'
239+
240+
def test_secret_manager_mapping_list_secrets_error(self, secret_manager_mapping, mocker):
241+
secret_manager_mapping._secret_client.list_secrets = mocker.Mock(side_effect=Exception('Permission denied'))
242+
243+
with pytest.raises(Exception, match='Permission denied'):
244+
_ = secret_manager_mapping._secret_names

0 commit comments

Comments
 (0)