ssm-parameter-store 26.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ from .stores import EC2ParameterStore
2
+ from .version import __version__
3
+
4
+ __all__ = ['EC2ParameterStore', '__version__']
@@ -0,0 +1,89 @@
1
+ import logging
2
+ import os
3
+
4
+ import boto3
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+
9
+ class EC2ParameterStore:
10
+ def __init__(self, **client_kwargs):
11
+ self.client = boto3.client('ssm', **client_kwargs)
12
+ self.path_delimiter = '/'
13
+
14
+ @staticmethod
15
+ def set_env(parameter_dict):
16
+ for k, v in parameter_dict.items():
17
+ os.environ.setdefault(k, v)
18
+
19
+ def _get_paginated_parameters(self, client_method, strip_path=True, **get_kwargs):
20
+ next_token = None
21
+ parameters = []
22
+ while True:
23
+ result = client_method(**get_kwargs)
24
+ parameters += result.get('Parameters')
25
+ next_token = result.get('NextToken')
26
+ if next_token is None:
27
+ break
28
+ get_kwargs.update({'NextToken': next_token})
29
+ return dict(self.extract_parameter(p, strip_path=strip_path) for p in parameters)
30
+
31
+ def extract_parameter(self, parameter, strip_path=True):
32
+ key = parameter['Name']
33
+ if strip_path:
34
+ key_parts = key.split(self.path_delimiter)
35
+ key = key_parts[-1]
36
+ value = parameter['Value']
37
+ if parameter['Type'] == 'StringList':
38
+ value = value.split(',')
39
+ return (key, value)
40
+
41
+ def get_parameter(self, name, decrypt=True, strip_path=True):
42
+ result = self.client.get_parameter(Name=name, WithDecryption=decrypt)
43
+ p = result['Parameter']
44
+ return dict([self.extract_parameter(p, strip_path=strip_path)])
45
+
46
+ def get_parameters(self, names, decrypt=True, strip_path=True):
47
+ get_kwargs = {'Names': names, 'WithDecryption': decrypt}
48
+ return self._get_paginated_parameters(
49
+ client_method=self.client.get_parameters,
50
+ strip_path=strip_path,
51
+ **get_kwargs
52
+ )
53
+
54
+ def get_parameters_by_path(self, path, decrypt=True, recursive=True, strip_path=True):
55
+ get_kwargs = {'Path': path, 'WithDecryption': decrypt, 'Recursive': recursive}
56
+ return self._get_paginated_parameters(
57
+ client_method=self.client.get_parameters_by_path,
58
+ strip_path=strip_path,
59
+ **get_kwargs
60
+ )
61
+
62
+ def get_parameters_with_hierarchy(self, path, decrypt=True, strip_path=True):
63
+ """Recursively get all parameters under path, keeping the hierarchy
64
+ as a structure of nested dictionaries.
65
+ """
66
+ # Get a flat dictionary
67
+ get_kwargs = {'Path': path, 'WithDecryption': decrypt, 'Recursive': True}
68
+ flat = self._get_paginated_parameters(
69
+ client_method=self.client.get_parameters_by_path,
70
+ strip_path=False,
71
+ **get_kwargs
72
+ )
73
+
74
+ # Convert to a nested dictionary and strip leading path component
75
+ result = {}
76
+
77
+ for key, value in flat.items():
78
+ if strip_path:
79
+ key = key[len(path):]
80
+ if key and key[0] == "/":
81
+ key = key[1:]
82
+
83
+ leafdict = result
84
+ key_segments = key.split("/")
85
+ for key_segment in key_segments[:-1]:
86
+ leafdict = leafdict.setdefault(key_segment, {})
87
+ leafdict[key_segments[-1]] = value
88
+
89
+ return result
@@ -0,0 +1,6 @@
1
+ import importlib.metadata
2
+
3
+ try:
4
+ __version__ = importlib.metadata.version('ssm-parameter-store')
5
+ except importlib.metadata.PackageNotFoundError:
6
+ __version__ = '0.0.0' # package not installed
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.3
2
+ Name: ssm-parameter-store
3
+ Version: 26.8.0
4
+ Summary: Add your description here
5
+ Author: Chris Tippett
6
+ Author-email: Chris Tippett <git@christippett.dev>
7
+ Requires-Dist: boto3>=1.43.81
8
+ Requires-Dist: setuptools>=84.0.0
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+
12
+ SSM Parameter Store
13
+ =============================================================
14
+
15
+ [![PyPI version](https://img.shields.io/pypi/v/ssm-parameter-store.svg)](https://pypi.python.org/pypi/ssm-parameter-store)
16
+ [![Build status](https://img.shields.io/travis/christippett/ssm-parameter-store.svg)](https://travis-ci.org/christippett/ssm-parameter-store)
17
+ [![Coverage](https://img.shields.io/coveralls/github/christippett/ssm-parameter-store.svg)](https://coveralls.io/github/christippett/ssm-parameter-store?branch=master)
18
+ [![Python versions](https://img.shields.io/pypi/pyversions/ssm-parameter-store.svg)](https://pypi.python.org/pypi/ssm-parameter-store)
19
+ [![Github license](https://img.shields.io/github/license/christippett/ssm-parameter-store.svg)](https://github.com/christippett/ssm-parameter-store)
20
+
21
+ Description
22
+ ===========
23
+
24
+ This is a simple Python wrapper for getting values from AWS Systems Manager
25
+ Parameter Store.
26
+
27
+ The module supports getting a single parameter, multiple parameters or all parameters matching a particular path.
28
+
29
+ All parameters are returned as a Python `dict`.
30
+
31
+ Installation
32
+ ============
33
+
34
+ Install with `pip`:
35
+
36
+ ``` bash
37
+ pip install ssm-parameter-store
38
+ ```
39
+
40
+ Usage
41
+ =====
42
+
43
+ Import the module and create a new instance of `EC2ParameterStore`.
44
+
45
+ ```python
46
+ from ssm_parameter_store import EC2ParameterStore
47
+
48
+ store = EC2ParameterStore()
49
+ ```
50
+
51
+ AWS Credentials
52
+ ---------------
53
+
54
+ `ssm-parameter-store` uses `boto3` under the hood and therefore inherits
55
+ the same mechanism for looking up AWS credentials. See [configuring
56
+ credentials](https://boto3.readthedocs.io/en/latest/guide/configuration.html#configuring-credentials)
57
+ in the Boto 3 documentation for more information.
58
+
59
+ `EC2ParameterStore` accepts all `boto3` client parameters as keyword arguments.
60
+
61
+ For example:
62
+
63
+ ``` python
64
+ from ssm_parameter_store import EC2ParameterStore
65
+
66
+ store = EC2ParameterStore(
67
+ aws_access_key_id=ACCESS_KEY,
68
+ aws_secret_access_key=SECRET_KEY,
69
+ aws_session_token=SESSION_TOKEN, # optional
70
+ region_name='us-west-2'
71
+ )
72
+ ```
73
+
74
+ Examples
75
+ ========
76
+
77
+ Given the following parameters:
78
+
79
+ ``` bash
80
+ # set default AWS region
81
+ AWS_DEFAULT_REGION=us-west-2
82
+
83
+ # add parameters
84
+ aws ssm put-parameter --name "param1" --value "value1" --type SecureString
85
+ aws ssm put-parameter --name "param2" --value "value2" --type SecureString
86
+
87
+ # add parameters organised by hierarchy
88
+ aws ssm put-parameter --name "/dev/app/secret" --value "dev_secret" --type SecureString
89
+ aws ssm put-parameter --name "/dev/db/postgres_username" --value "dev_username" --type SecureString
90
+ aws ssm put-parameter --name "/dev/db/postgres_password" --value "dev_password" --type SecureString
91
+ aws ssm put-parameter --name "/prod/app/secret" --value "prod_secret" --type SecureString
92
+ aws ssm put-parameter --name "/prod/db/postgres_username" --value "prod_username" --type SecureString
93
+ aws ssm put-parameter --name "/prod/db/postgres_password" --value "prod_password" --type SecureString
94
+ ```
95
+
96
+
97
+ Get a single parameter
98
+ ----------------------
99
+
100
+ ``` python
101
+ parameter = store.get_parameter('param1', decrypt=True)
102
+
103
+ assert parameter == {
104
+ 'param1': 'value1'
105
+ }
106
+ ```
107
+
108
+ Get multiple parameters
109
+ -----------------------
110
+
111
+ ``` python
112
+ parameters = store.get_parameters(['param1', 'param2'])
113
+
114
+ assert parameters == {
115
+ 'param1': 'value1',
116
+ 'param2': 'value2',
117
+ }
118
+ ```
119
+
120
+ Get parameters by path
121
+ ----------------------
122
+
123
+ ``` python
124
+ parameters = store.get_parameters_by_path('/dev/', recursive=True)
125
+
126
+ assert parameters == {
127
+ 'secret': 'dev_secret',
128
+ 'postgres_username': 'dev_username',
129
+ 'postgres_password': 'dev_password',
130
+ }
131
+ ```
132
+
133
+ By default `get_parameters_by_path` strips the path from each parameter name. To return a parameter's full name, set `strip_path` to `False`.
134
+
135
+ ``` python
136
+ parameters = store.get_parameters_by_path('/dev/', strip_path=False, recursive=True)
137
+
138
+ assert parameters == {
139
+ '/dev/app/secret': 'dev_secret',
140
+ '/dev/db/postgres_username': 'dev_username',
141
+ '/dev/db/postgres_password': 'dev_password'
142
+ }
143
+ ```
144
+
145
+ Get parameters with original hierarchy
146
+ --------------------------------------
147
+ You can also get parameters by path, but in a nested structure that models the path hierarchy.
148
+
149
+ ``` python
150
+ parameters = store.get_parameters_with_hierarchy('/dev/')
151
+
152
+ assert parameters == {
153
+ 'app': {
154
+ 'secret': 'dev_secret',
155
+ },
156
+ 'db': {
157
+ 'postgres_username': 'dev_username',
158
+ 'postgres_password': 'dev_password',
159
+ },
160
+ }
161
+ ```
162
+
163
+ By default `get_parameters_with_hierarchy` strips the leading path component. To return the selected parameters
164
+ with the full hierarchy, set `strip_path` to `False`.
165
+
166
+ ``` python
167
+ parameters = store.get_parameters_with_hierarchy('/dev/', strip_path=False)
168
+
169
+ assert parameters == {
170
+ 'dev': {
171
+ 'app': {
172
+ 'secret': 'dev_secret',
173
+ },
174
+ 'db': {
175
+ 'postgres_username': 'dev_username',
176
+ 'postgres_password': 'dev_password',
177
+ },
178
+ },
179
+ }
180
+ ```
181
+
182
+
183
+ Populating Environment Variables
184
+ ================================
185
+
186
+ The module includes a static method on `EC2ParameterStore` to help populate environment variables. This can be helpful when integrating with a library like [`django-environ`](https://github.com/joke2k/django-environ).
187
+
188
+ Example
189
+ -------
190
+ Given the following parameters:
191
+
192
+ ```bash
193
+ aws ssm put-parameter --name "/prod/django/SECRET_KEY" --value "-$y_^@69bm69+z!fawbdf=h_10+zjzfwr8_c=$$&j@-%p$%ct^" --type SecureString
194
+ aws ssm put-parameter --name "/prod/django/DATABASE_URL" --value "psql://user:pass@db-prod.xyz123.us-west-2.rds.amazonaws.com:5432/db" --type SecureString
195
+ aws ssm put-parameter --name "/prod/django/REDIS_URL" --value "redis://redis-prod.edc1ba.0001.usw2.cache.amazonaws.com:6379" --type SecureString
196
+ ```
197
+
198
+ ```python
199
+ import environ
200
+ from ssm_parameter_store import EC2ParameterStore
201
+
202
+ env = environ.Env(
203
+ DEBUG=(bool, False)
204
+ )
205
+
206
+ # Get parameters and populate os.environ (region not required if AWS_DEFAULT_REGION environment variable set)
207
+ parameter_store = EC2ParameterStore(region_name='us-west-2')
208
+ django_parameters = parameter_store.get_parameters_by_path('/prod/django/', strip_path=True)
209
+ EC2ParameterStore.set_env(django_parameters)
210
+
211
+ # False if not in os.environ
212
+ DEBUG = env('DEBUG')
213
+
214
+ # Raises django's ImproperlyConfigured exception if SECRET_KEY not in os.environ
215
+ SECRET_KEY = env('SECRET_KEY')
216
+
217
+ DATABASES = {
218
+ # read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
219
+ 'default': env.db(),
220
+ }
221
+
222
+ CACHES = {
223
+ 'default': env.cache('REDIS_URL'),
224
+ }
225
+ ```
226
+
227
+ Related Projects
228
+ ================
229
+
230
+ - **[param-store](https://github.com/LabD/python-param-store)** –
231
+ Python module to store secrets in secret stores
232
+ - **[ssm-cache](https://github.com/alexcasalboni/ssm-cache-python)** –
233
+ AWS System Manager Parameter Store caching client for Python
234
+
@@ -0,0 +1,7 @@
1
+ ssm_parameter_store/__init__.py,sha256=ZtdsNKGNga0r8SAWQz3fPRRShl06bfEspqLDhHIW3Qs,119
2
+ ssm_parameter_store/stores.py,sha256=SGWXvEtC9YTtvbq_Zx5gTW-Yk5iTqUiuGJ3osKxKYSM,3179
3
+ ssm_parameter_store/version.py,sha256=K_XsbYhe_xoL2DuCugHuVI2MFtfXNoCg1KXsnhzUy4U,199
4
+ ssm_parameter_store-26.8.0.dist-info/WHEEL,sha256=Lkz__M3n3EKWmzMwHnFILNW2SHO43bOxmbqnBjwb--4,80
5
+ ssm_parameter_store-26.8.0.dist-info/entry_points.txt,sha256=Bt18Vw-a4Hgvm6ps1zqpfhlfKO3U8F0YpTZyGzuD9FQ,66
6
+ ssm_parameter_store-26.8.0.dist-info/METADATA,sha256=0QzTFCnPJHAZaNgh2HNwN9EznkTjiojkqqWK0Ne0nhc,7052
7
+ ssm_parameter_store-26.8.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.12.6
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ ssm-parameter-store = ssm_parameter_store:main
3
+