Skip to content

Commit e6416c0

Browse files
committed
chore: split parameter utilities into smaller files
1 parent 6eb012f commit e6416c0

File tree

7 files changed

+276
-243
lines changed

7 files changed

+276
-243
lines changed

aws_lambda_powertools/utilities/parameters/__init__.py

Lines changed: 5 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
Parameter retrieval and caching utility
55
"""
66

7-
from typing import Dict, Optional, Union
8-
9-
import boto3
10-
from boto3.dynamodb.conditions import Key
11-
12-
from .base import BaseProvider, GetParameterError
7+
from .base import BaseProvider
8+
from .dynamodb import DynamoDBProvider
9+
from .exceptions import GetParameterError
10+
from .secrets import SecretsProvider, get_secret
11+
from .ssm import SSMProvider, get_parameter, get_parameters
1312

1413
__all__ = [
1514
"BaseProvider",
@@ -21,227 +20,3 @@
2120
"get_parameters",
2221
"get_secret",
2322
]
24-
25-
26-
class SSMProvider(BaseProvider):
27-
"""
28-
AWS Systems Manager Parameter Store Provider
29-
"""
30-
31-
client = None
32-
33-
def __init__(
34-
self, region: Optional[str] = None,
35-
):
36-
"""
37-
Initialize the SSM Parameter Store client
38-
"""
39-
40-
client_kwargs = {}
41-
if region:
42-
client_kwargs["region_name"] = region
43-
44-
self.client = boto3.client("ssm", **client_kwargs)
45-
46-
super().__init__()
47-
48-
def _get(self, name: str, **kwargs) -> str:
49-
"""
50-
Retrieve a parameter value from AWS Systems Manager Parameter Store
51-
52-
Parameters
53-
----------
54-
name: str
55-
Parameter name
56-
decrypt: bool
57-
If the parameter value should be decrypted
58-
"""
59-
60-
# Load kwargs
61-
decrypt = kwargs.get("decrypt", False)
62-
63-
return self.client.get_parameter(Name=name, WithDecryption=decrypt)["Parameter"]["Value"]
64-
65-
def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]:
66-
"""
67-
Retrieve multiple parameter values from AWS Systems Manager Parameter Store
68-
69-
Parameters
70-
----------
71-
path: str
72-
Path to retrieve the parameters
73-
decrypt: bool
74-
If the parameter values should be decrypted
75-
recursive: bool
76-
If this should retrieve the parameter values recursively or not
77-
"""
78-
79-
# Load kwargs
80-
decrypt = kwargs.get("decrypt", False)
81-
recursive = kwargs.get("recursive", False)
82-
83-
response = self.client.get_parameters_by_path(Path=path, WithDecryption=decrypt, Recursive=recursive)
84-
parameters = response.get("Parameters", [])
85-
86-
# Keep retrieving parameters
87-
while "NextToken" in response:
88-
response = self.client.get_parameters_by_path(
89-
Path=path, WithDecryption=decrypt, Recursive=recursive, NextToken=response["NextToken"]
90-
)
91-
parameters.extend(response.get("Parameters", []))
92-
93-
retval = {}
94-
for parameter in parameters:
95-
96-
# Standardize the parameter name
97-
# The parameter name returned by SSM will contained the full path.
98-
# However, for readability, we should return only the part after
99-
# the path.
100-
name = parameter["Name"]
101-
if name.startswith(path):
102-
name = name[len(path) :]
103-
name = name.lstrip("/")
104-
105-
retval[name] = parameter["Value"]
106-
107-
return retval
108-
109-
110-
class SecretsProvider(BaseProvider):
111-
"""
112-
AWS Secrets Manager Parameter Provider
113-
"""
114-
115-
client = None
116-
117-
def __init__(self, region: Optional[str] = None):
118-
"""
119-
Initialize the Secrets Manager client
120-
"""
121-
122-
client_kwargs = {}
123-
if region:
124-
client_kwargs["region_name"] = region
125-
126-
self.client = boto3.client("secretsmanager", **client_kwargs)
127-
128-
super().__init__()
129-
130-
def _get(self, name: str, **kwargs) -> str:
131-
"""
132-
Retrieve a parameter value from AWS Systems Manager Parameter Store
133-
"""
134-
135-
return self.client.get_secret_value(SecretId=name)["SecretString"]
136-
137-
def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]:
138-
"""
139-
Retrieving multiple parameter values is not supported with AWS Secrets Manager
140-
"""
141-
raise NotImplementedError()
142-
143-
144-
class DynamoDBProvider(BaseProvider):
145-
"""
146-
Amazon DynamoDB Parameter Provider
147-
"""
148-
149-
table = None
150-
key_attr = None
151-
value_attr = None
152-
153-
def __init__(
154-
self, table_name: str, key_attr: str = "id", value_attr: str = "value", region: Optional[str] = None,
155-
):
156-
"""
157-
Initialize the DynamoDB client
158-
"""
159-
160-
client_kwargs = {}
161-
if region:
162-
client_kwargs["region_name"] = region
163-
self.table = boto3.resource("dynamodb", **client_kwargs).Table(table_name)
164-
165-
self.key_attr = key_attr
166-
self.value_attr = value_attr
167-
168-
super().__init__()
169-
170-
def _get(self, name: str, **kwargs) -> str:
171-
"""
172-
Retrieve a parameter value from Amazon DynamoDB
173-
"""
174-
175-
return self.table.get_item(Key={self.key_attr: name})["Item"][self.value_attr]
176-
177-
def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]:
178-
"""
179-
Retrieve multiple parameter values from Amazon DynamoDB
180-
181-
Parameters
182-
----------
183-
path: str
184-
Path to retrieve the parameters
185-
sort_attr: str
186-
Name of the DynamoDB table sort key (defaults to 'sk')
187-
"""
188-
189-
sort_attr = kwargs.get("sort_attr", "sk")
190-
191-
response = self.table.query(KeyConditionExpression=Key(self.key_attr).eq(path))
192-
items = response.get("Items", [])
193-
194-
# Keep querying while there are more items matching the partition key
195-
while "LastEvaluatedKey" in response:
196-
response = self.table.query(
197-
KeyConditionExpression=Key(self.key_attr).eq(path), ExclusiveStartKey=response["LastEvaluatedKey"],
198-
)
199-
items.extend(response.get("Items", []))
200-
201-
retval = {}
202-
for item in items:
203-
retval[item[sort_attr]] = item[self.value_attr]
204-
205-
return retval
206-
207-
208-
# These providers will be dynamically initialized on first use of the helper functions
209-
_DEFAULT_PROVIDERS = {}
210-
211-
212-
def get_parameter(name: str, transform: Optional[str] = None) -> Union[str, list, dict, bytes]:
213-
"""
214-
Retrieve a parameter value from AWS Systems Manager (SSM) Parameter Store
215-
"""
216-
217-
# Only create the provider if this function is called at least once
218-
if "ssm" not in _DEFAULT_PROVIDERS:
219-
_DEFAULT_PROVIDERS["ssm"] = SSMProvider()
220-
221-
return _DEFAULT_PROVIDERS["ssm"].get(name, transform=transform)
222-
223-
224-
def get_parameters(
225-
path: str, transform: Optional[str] = None, recursive: bool = False, decrypt: bool = False
226-
) -> Union[Dict[str, str], Dict[str, dict], Dict[str, bytes]]:
227-
"""
228-
Retrieve multiple parameter values from AWS Systems Manager (SSM) Parameter Store
229-
"""
230-
231-
# Only create the provider if this function is called at least once
232-
if "ssm" not in _DEFAULT_PROVIDERS:
233-
_DEFAULT_PROVIDERS["ssm"] = SSMProvider()
234-
235-
return _DEFAULT_PROVIDERS["ssm"].get_multiple(path, transform=transform, recursive=recursive, decrypt=decrypt)
236-
237-
238-
def get_secret(name: str, transform: Optional[str] = None, decrypt: bool = False) -> Union[str, dict, bytes]:
239-
"""
240-
Retrieve a parameter value from AWS Secrets Manager
241-
"""
242-
243-
# Only create the provider if this function is called at least once
244-
if "secrets" not in _DEFAULT_PROVIDERS:
245-
_DEFAULT_PROVIDERS["secrets"] = SecretsProvider()
246-
247-
return _DEFAULT_PROVIDERS["secrets"].get(name, transform=transform, decrypt=decrypt)

aws_lambda_powertools/utilities/parameters/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
from datetime import datetime, timedelta
1010
from typing import Dict, Optional, Union
1111

12+
from .exceptions import GetParameterError
13+
1214
DEFAULT_MAX_AGE_SECS = 5
1315
ExpirableValue = namedtuple("ExpirableValue", ["value", "ttl"])
14-
15-
16-
class GetParameterError(Exception):
17-
"""When a provider raises an exception on parameter retrieval"""
16+
# These providers will be dynamically initialized on first use of the helper functions
17+
DEFAULT_PROVIDERS = {}
1818

1919

2020
class BaseProvider(ABC):
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
Amazon DynamoDB parameter retrieval and caching utility
3+
"""
4+
5+
6+
from typing import Dict, Optional
7+
8+
import boto3
9+
from boto3.dynamodb.conditions import Key
10+
11+
from .base import BaseProvider
12+
13+
14+
class DynamoDBProvider(BaseProvider):
15+
"""
16+
Amazon DynamoDB Parameter Provider
17+
"""
18+
19+
table = None
20+
key_attr = None
21+
value_attr = None
22+
23+
def __init__(
24+
self, table_name: str, key_attr: str = "id", value_attr: str = "value", region: Optional[str] = None,
25+
):
26+
"""
27+
Initialize the DynamoDB client
28+
"""
29+
30+
client_kwargs = {}
31+
if region:
32+
client_kwargs["region_name"] = region
33+
self.table = boto3.resource("dynamodb", **client_kwargs).Table(table_name)
34+
35+
self.key_attr = key_attr
36+
self.value_attr = value_attr
37+
38+
super().__init__()
39+
40+
def _get(self, name: str, **kwargs) -> str:
41+
"""
42+
Retrieve a parameter value from Amazon DynamoDB
43+
"""
44+
45+
return self.table.get_item(Key={self.key_attr: name})["Item"][self.value_attr]
46+
47+
def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]:
48+
"""
49+
Retrieve multiple parameter values from Amazon DynamoDB
50+
51+
Parameters
52+
----------
53+
path: str
54+
Path to retrieve the parameters
55+
sort_attr: str
56+
Name of the DynamoDB table sort key (defaults to 'sk')
57+
"""
58+
59+
sort_attr = kwargs.get("sort_attr", "sk")
60+
61+
response = self.table.query(KeyConditionExpression=Key(self.key_attr).eq(path))
62+
items = response.get("Items", [])
63+
64+
# Keep querying while there are more items matching the partition key
65+
while "LastEvaluatedKey" in response:
66+
response = self.table.query(
67+
KeyConditionExpression=Key(self.key_attr).eq(path), ExclusiveStartKey=response["LastEvaluatedKey"],
68+
)
69+
items.extend(response.get("Items", []))
70+
71+
retval = {}
72+
for item in items:
73+
retval[item[sort_attr]] = item[self.value_attr]
74+
75+
return retval
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
Parameter retrieval exceptions
3+
"""
4+
5+
6+
class GetParameterError(Exception):
7+
"""When a provider raises an exception on parameter retrieval"""

0 commit comments

Comments
 (0)