Skip to content

Commit 88a3d7a

Browse files
chore: add ruff.toml, drop Python 3.8 support
1 parent ce353a9 commit 88a3d7a

File tree

11 files changed

+59
-168
lines changed

11 files changed

+59
-168
lines changed

.github/workflows/python-package.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
strategy:
1414
fail-fast: false
1515
matrix:
16-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
16+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1717
steps:
1818
- name: Checkout
1919
uses: actions/checkout@v4

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The AWS Secrets Manager Python caching client enables in-process caching of secr
1111

1212
To use this client you must have:
1313

14-
- Python 3.8 or newer. Use of Python versions 3.7 or older are not supported.
14+
- Python 3.9 or newer. Use of Python versions 3.8 or older are not supported.
1515
- An Amazon Web Services (AWS) account to access secrets stored in AWS Secrets Manager.
1616

1717
- **To create an AWS account**, go to [Sign In or Create an AWS Account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) and then choose **I am a new user.** Follow the instructions to create an AWS account.

ruff.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
line-length = 120

src/aws_secretsmanager_caching/cache/items.py

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ def __refresh(self):
105105
)
106106
self._exception_count += 1
107107
delay = min(delay, self._config.exception_retry_delay_max)
108-
self._next_retry_time = datetime.now(timezone.utc) + timedelta(
109-
milliseconds=delay
110-
)
108+
self._next_retry_time = datetime.now(timezone.utc) + timedelta(milliseconds=delay)
111109

112110
def get_secret_value(self, version_stage=None):
113111
"""Get the cached secret value for the given version stage.
@@ -215,11 +213,7 @@ def _get_version_id(result, version_stage):
215213
return None
216214
if "VersionIdsToStages" not in result:
217215
return None
218-
ids = [
219-
key
220-
for (key, value) in result["VersionIdsToStages"].items()
221-
if version_stage in value
222-
]
216+
ids = [key for (key, value) in result["VersionIdsToStages"].items() if version_stage in value]
223217
if not ids:
224218
return None
225219
return ids[0]
@@ -232,9 +226,7 @@ def _execute_refresh(self):
232226
"""
233227
result = self._client.describe_secret(SecretId=self._secret_id)
234228
ttl = self._config.secret_refresh_interval
235-
self._next_refresh_time = datetime.now(timezone.utc) + timedelta(
236-
seconds=randint(round(ttl / 2), ttl)
237-
)
229+
self._next_refresh_time = datetime.now(timezone.utc) + timedelta(seconds=randint(round(ttl / 2), ttl))
238230
return result
239231

240232
def _get_version(self, version_stage):
@@ -286,9 +278,7 @@ def _execute_refresh(self):
286278
:rtype: dict
287279
:return: The result of GetSecretValue for the version.
288280
"""
289-
return self._client.get_secret_value(
290-
SecretId=self._secret_id, VersionId=self._version_id
291-
)
281+
return self._client.get_secret_value(SecretId=self._secret_id, VersionId=self._version_id)
292282

293283
def _get_version(self, version_stage):
294284
"""Get the cached version information for the given stage.

src/aws_secretsmanager_caching/decorators.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,7 @@ def _wrapped_func(*args, **kwargs):
9898
Internal function to execute wrapped function
9999
"""
100100
try:
101-
secret = json.loads(
102-
self.cache.get_secret_string(secret_id=self.secret_id)
103-
)
101+
secret = json.loads(self.cache.get_secret_string(secret_id=self.secret_id))
104102
except json.decoder.JSONDecodeError:
105103
raise RuntimeError("Cached secret is not valid JSON") from None
106104

@@ -109,9 +107,7 @@ def _wrapped_func(*args, **kwargs):
109107
try:
110108
resolved_kwargs[orig_kwarg] = secret[secret_key]
111109
except KeyError:
112-
raise RuntimeError(
113-
f"Cached secret does not contain key {secret_key}"
114-
) from None
110+
raise RuntimeError(f"Cached secret does not contain key {secret_key}") from None
115111

116112
return func(*args, **resolved_kwargs, **kwargs)
117113

src/aws_secretsmanager_caching/secret_cache.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ def __init__(self, config=SecretCacheConfig(), client=None):
5050
}
5151
)
5252
if self._client is None:
53-
self._client = botocore.session.get_session().create_client(
54-
"secretsmanager", config=boto_config
55-
)
53+
self._client = botocore.session.get_session().create_client("secretsmanager", config=boto_config)
5654

5755
def _get_cached_secret(self, secret_id):
5856
"""Get a cached secret for the given secret identifier.
@@ -68,9 +66,7 @@ def _get_cached_secret(self, secret_id):
6866
return secret
6967
self._cache.put_if_absent(
7068
secret_id,
71-
SecretCacheItem(
72-
config=self._config, client=self._client, secret_id=secret_id
73-
),
69+
SecretCacheItem(config=self._config, client=self._client, secret_id=secret_id),
7470
)
7571
return self._cache.get(secret_id)
7672

test/integ/test_aws_secretsmanager_caching.py

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
from aws_secretsmanager_caching.secret_cache import SecretCache
2424
from botocore.exceptions import ClientError, HTTPClientError, NoCredentialsError
2525

26-
logging.basicConfig(
27-
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
28-
)
26+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
2927
logger = logging.getLogger(__name__)
3028

3129

@@ -51,9 +49,7 @@ def pre_test_cleanup(self, client):
5149
logger.info("Fetching results from ListSecretValue...")
5250
for secret in page["SecretList"]:
5351
if (
54-
secret["Name"].startswith(
55-
TestAwsSecretsManagerCachingInteg.fixture_prefix
56-
)
52+
secret["Name"].startswith(TestAwsSecretsManagerCachingInteg.fixture_prefix)
5753
and (secret["LastChangedDate"] > two_days_ago)
5854
and (secret["LastAccessedDate"] > two_days_ago)
5955
):
@@ -65,11 +61,7 @@ def pre_test_cleanup(self, client):
6561
break
6662
time.sleep(0.5)
6763
except ClientError as e:
68-
logger.error(
69-
"Got ClientError {0} while calling ListSecrets".format(
70-
e.response["Error"]["Code"]
71-
)
72-
)
64+
logger.error("Got ClientError {0} while calling ListSecrets".format(e.response["Error"]["Code"]))
7365
except HTTPClientError:
7466
logger.error("Got HTTPClientError while calling ListSecrets")
7567
except NoCredentialsError:
@@ -85,17 +77,12 @@ def pre_test_cleanup(self, client):
8577
client.delete_secret(SecretId=secret["Name"])
8678
except ClientError as e:
8779
logger.error(
88-
"Got ClientError {0} while calling "
89-
"DeleteSecret for secret {1}".format(
80+
"Got ClientError {0} while calling DeleteSecret for secret {1}".format(
9081
e.response["Error"]["Code"], secret["Name"]
9182
)
9283
)
9384
except HTTPClientError:
94-
logger.error(
95-
"Got HTTPClientError while calling DeleteSecret for secret {0}".format(
96-
secret["Name"]
97-
)
98-
)
85+
logger.error("Got HTTPClientError while calling DeleteSecret for secret {0}".format(secret["Name"]))
9986
time.sleep(0.5)
10087

10188
yield None
@@ -129,9 +116,7 @@ def test_get_secret_string(self, client, secret_string):
129116
)
130117

131118
def test_get_secret_string_refresh(self, client, secret_string):
132-
cache = SecretCache(
133-
config=SecretCacheConfig(secret_refresh_interval=1), client=client
134-
)
119+
cache = SecretCache(config=SecretCacheConfig(secret_refresh_interval=1), client=client)
135120
secret = client.get_secret_value(SecretId=secret_string["ARN"])["SecretString"]
136121

137122
for _ in range(10):
@@ -188,18 +173,16 @@ def secret_string_stage(self, request, client):
188173
)
189174

190175
secret = client.create_secret(Name=name, SecretString="test")
191-
client.put_secret_value(
192-
SecretId=secret["ARN"], SecretString="test2", VersionStages=["AWSCURRENT"]
193-
)
176+
client.put_secret_value(SecretId=secret["ARN"], SecretString="test2", VersionStages=["AWSCURRENT"])
194177

195178
yield client.describe_secret(SecretId=secret["ARN"])
196179
client.delete_secret(SecretId=secret["ARN"], ForceDeleteWithoutRecovery=True)
197180

198181
def test_get_secret_string_stage(self, client, secret_string_stage):
199182
cache = SecretCache(client=client)
200-
secret = client.get_secret_value(
201-
SecretId=secret_string_stage["ARN"], VersionStage="AWSPREVIOUS"
202-
)["SecretString"]
183+
secret = client.get_secret_value(SecretId=secret_string_stage["ARN"], VersionStage="AWSPREVIOUS")[
184+
"SecretString"
185+
]
203186

204187
for _ in range(10):
205188
assert (

test/unit/test_aws_secretsmanager_caching.py

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ def setUp(self):
3232
pass
3333

3434
def get_client(self, response={}, versions=None, version_response=None):
35-
client = botocore.session.get_session().create_client(
36-
"secretsmanager", region_name="us-west-2"
37-
)
35+
client = botocore.session.get_session().create_client("secretsmanager", region_name="us-west-2")
3836

3937
stubber = Stubber(client)
4038
expected_params = {"SecretId": "test"}
@@ -74,18 +72,14 @@ def test_get_secret_string_missing(self):
7472
response = {}
7573
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
7674
version_response = {"Name": "test"}
77-
cache = SecretCache(
78-
client=self.get_client(response, versions, version_response)
79-
)
75+
cache = SecretCache(client=self.get_client(response, versions, version_response))
8076
self.assertIsNone(cache.get_secret_string("test"))
8177

8278
def test_get_secret_string_no_current(self):
8379
response = {}
8480
versions = {"01234567890123456789012345678901": ["NOTCURRENT"]}
8581
version_response = {"Name": "test"}
86-
cache = SecretCache(
87-
client=self.get_client(response, versions, version_response)
88-
)
82+
cache = SecretCache(client=self.get_client(response, versions, version_response))
8983
self.assertIsNone(cache.get_secret_string("test"))
9084

9185
def test_get_secret_string_no_versions(self):
@@ -97,19 +91,15 @@ def test_get_secret_string_empty(self):
9791
response = {}
9892
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
9993
version_response = {}
100-
cache = SecretCache(
101-
client=self.get_client(response, versions, version_response)
102-
)
94+
cache = SecretCache(client=self.get_client(response, versions, version_response))
10395
self.assertIsNone(cache.get_secret_string("test"))
10496

10597
def test_get_secret_string(self):
10698
secret = "mysecret"
10799
response = {}
108100
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
109101
version_response = {"SecretString": secret}
110-
cache = SecretCache(
111-
client=self.get_client(response, versions, version_response)
112-
)
102+
cache = SecretCache(client=self.get_client(response, versions, version_response))
113103
for _ in range(10):
114104
self.assertEqual(secret, cache.get_secret_string("test"))
115105

@@ -130,9 +120,7 @@ def test_get_secret_string_stage(self):
130120
response = {}
131121
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
132122
version_response = {"SecretString": secret}
133-
cache = SecretCache(
134-
client=self.get_client(response, versions, version_response)
135-
)
123+
cache = SecretCache(client=self.get_client(response, versions, version_response))
136124
for _ in range(10):
137125
self.assertEqual(secret, cache.get_secret_string("test", "AWSCURRENT"))
138126

@@ -146,9 +134,7 @@ def test_get_secret_binary(self):
146134
response = {}
147135
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
148136
version_response = {"SecretBinary": secret}
149-
cache = SecretCache(
150-
client=self.get_client(response, versions, version_response)
151-
)
137+
cache = SecretCache(client=self.get_client(response, versions, version_response))
152138
for _ in range(10):
153139
self.assertEqual(secret, cache.get_secret_binary("test"))
154140

@@ -161,9 +147,7 @@ def test_refresh_secret_now(self):
161147
response = {}
162148
versions = {"01234567890123456789012345678901": ["AWSCURRENT"]}
163149
version_response = {"SecretString": secret}
164-
cache = SecretCache(
165-
client=self.get_client(response, versions, version_response)
166-
)
150+
cache = SecretCache(client=self.get_client(response, versions, version_response))
167151
secret = cache._get_cached_secret("test")
168152
self.assertIsNotNone(secret)
169153

@@ -180,9 +164,7 @@ def test_refresh_secret_now(self):
180164
self.assertTrue(new_refresh_time > old_refresh_time)
181165

182166
def test_get_secret_string_exception(self):
183-
client = botocore.session.get_session().create_client(
184-
"secretsmanager", region_name="us-west-2"
185-
)
167+
client = botocore.session.get_session().create_client("secretsmanager", region_name="us-west-2")
186168

187169
stubber = Stubber(client)
188170
cache = SecretCache(client=client)

test/unit/test_cache_hook.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ def setUp(self):
5656
pass
5757

5858
def get_client(self, response={}, versions=None, version_response=None):
59-
client = botocore.session.get_session().create_client(
60-
"secretsmanager", region_name="us-west-2"
61-
)
59+
client = botocore.session.get_session().create_client("secretsmanager", region_name="us-west-2")
6260

6361
stubber = Stubber(client)
6462
expected_params = {"SecretId": "test"}
@@ -83,9 +81,7 @@ def test_calls_hook_string(self):
8381
hook = DummySecretCacheHook()
8482
config = SecretCacheConfig(secret_cache_hook=hook)
8583

86-
cache = SecretCache(
87-
config=config, client=self.get_client(response, versions, version_response)
88-
)
84+
cache = SecretCache(config=config, client=self.get_client(response, versions, version_response))
8985

9086
for _ in range(10):
9187
fetched_secret = cache.get_secret_string("test")
@@ -101,9 +97,7 @@ def test_calls_hook_binary(self):
10197
hook = DummySecretCacheHook()
10298
config = SecretCacheConfig(secret_cache_hook=hook)
10399

104-
cache = SecretCache(
105-
config=config, client=self.get_client(response, versions, version_response)
106-
)
100+
cache = SecretCache(config=config, client=self.get_client(response, versions, version_response))
107101

108102
for _ in range(10):
109103
self.assertEqual(hooked_secret, cache.get_secret_binary("test")[0:24])

0 commit comments

Comments
 (0)