Skip to content

Commit 621e6bb

Browse files
committed
Rename class to RepositoryGoogleSecretManager
1 parent 2d17af6 commit 621e6bb

File tree

2 files changed

+95
-100
lines changed

2 files changed

+95
-100
lines changed

decouple.py

+60-65
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212

1313
if PYVERSION >= (3, 0, 0):
1414
from configparser import ConfigParser, NoOptionError
15+
1516
text_type = str
1617
else:
1718
from ConfigParser import SafeConfigParser as ConfigParser, NoOptionError
19+
1820
text_type = unicode
1921

2022
if PYVERSION >= (3, 2, 0):
@@ -23,13 +25,14 @@
2325
read_config = lambda parser, file: parser.readfp(file)
2426

2527

26-
DEFAULT_ENCODING = 'UTF-8'
28+
DEFAULT_ENCODING = "UTF-8"
2729

2830

2931
# Python 3.10 don't have strtobool anymore. So we move it here.
3032
TRUE_VALUES = {"y", "yes", "t", "true", "on", "1"}
3133
FALSE_VALUES = {"n", "no", "f", "false", "off", "0"}
3234

35+
3336
def strtobool(value):
3437
if isinstance(value, bool):
3538
return value
@@ -51,6 +54,7 @@ class Undefined(object):
5154
"""
5255
Class to represent undefined type.
5356
"""
57+
5458
pass
5559

5660

@@ -71,7 +75,7 @@ def _cast_boolean(self, value):
7175
Helper to convert config values to boolean as ConfigParser do.
7276
"""
7377
value = str(value)
74-
return bool(value) if value == '' else bool(strtobool(value))
78+
return bool(value) if value == "" else bool(strtobool(value))
7579

7680
@staticmethod
7781
def _cast_do_nothing(value):
@@ -89,7 +93,11 @@ def get(self, option, default=undefined, cast=undefined):
8993
value = self.repository[option]
9094
else:
9195
if isinstance(default, Undefined):
92-
raise UndefinedValueError('{} not found. Declare it as envvar or define a default value.'.format(option))
96+
raise UndefinedValueError(
97+
"{} not found. Declare it as envvar or define a default value.".format(
98+
option
99+
)
100+
)
93101

94102
value = default
95103

@@ -108,7 +116,7 @@ def __call__(self, *args, **kwargs):
108116

109117

110118
class RepositoryEmpty(object):
111-
def __init__(self, source='', encoding=DEFAULT_ENCODING):
119+
def __init__(self, source="", encoding=DEFAULT_ENCODING):
112120
pass
113121

114122
def __contains__(self, key):
@@ -122,16 +130,16 @@ class RepositoryIni(RepositoryEmpty):
122130
"""
123131
Retrieves option keys from .ini files.
124132
"""
125-
SECTION = 'settings'
133+
134+
SECTION = "settings"
126135

127136
def __init__(self, source, encoding=DEFAULT_ENCODING):
128137
self.parser = ConfigParser()
129138
with open(source, encoding=encoding) as file_:
130139
read_config(self.parser, file_)
131140

132141
def __contains__(self, key):
133-
return (key in os.environ or
134-
self.parser.has_option(self.SECTION, key))
142+
return key in os.environ or self.parser.has_option(self.SECTION, key)
135143

136144
def __getitem__(self, key):
137145
try:
@@ -144,18 +152,21 @@ class RepositoryEnv(RepositoryEmpty):
144152
"""
145153
Retrieves option keys from .env files with fall back to os.environ.
146154
"""
155+
147156
def __init__(self, source, encoding=DEFAULT_ENCODING):
148157
self.data = {}
149158

150159
with open(source, encoding=encoding) as file_:
151160
for line in file_:
152161
line = line.strip()
153-
if not line or line.startswith('#') or '=' not in line:
162+
if not line or line.startswith("#") or "=" not in line:
154163
continue
155-
k, v = line.split('=', 1)
164+
k, v = line.split("=", 1)
156165
k = k.strip()
157166
v = v.strip()
158-
if len(v) >= 2 and ((v[0] == "'" and v[-1] == "'") or (v[0] == '"' and v[-1] == '"')):
167+
if len(v) >= 2 and (
168+
(v[0] == "'" and v[-1] == "'") or (v[0] == '"' and v[-1] == '"')
169+
):
159170
v = v[1:-1]
160171
self.data[k] = v
161172

@@ -173,12 +184,12 @@ class RepositorySecret(RepositoryEmpty):
173184
e.g. Docker swarm secrets
174185
"""
175186

176-
def __init__(self, source='/run/secrets/'):
187+
def __init__(self, source="/run/secrets/"):
177188
self.data = {}
178189

179190
ls = os.listdir(source)
180191
for file in ls:
181-
with open(os.path.join(source, file), 'r') as f:
192+
with open(os.path.join(source, file), "r") as f:
182193
self.data[file] = f.read()
183194

184195
def __contains__(self, key):
@@ -188,40 +199,41 @@ def __getitem__(self, key):
188199
return self.data[key]
189200

190201

191-
class RepositoryString(RepositoryEmpty):
202+
class RepositoryGoogleSecretManager(RepositoryEnv):
192203
"""
193-
Repository class to retrieve options from a string.
204+
Repository class for retrieving configuration options from Google Secret Manager.
194205
195-
Parses a string formatted like a `.env` file into a dictionary of options.
196-
This class is an extension of the `RepositoryEmpty` class that provides a
197-
way to read configuration keys from an environment string.
206+
This class extends `RepositoryEnv` to specifically handle configurations stored in
207+
Google Secret Manager. It parses strings formatted in a similar way to `.env` files,
208+
converting them into a dictionary of configuration options.
198209
199210
Attributes:
200-
data (dict): A dictionary to hold the parsed key-value pairs.
211+
data (dict): A dictionary holding the parsed key-value pairs from the Google
212+
Secret Manager source.
201213
"""
202214

203215
def __init__(self, source):
204216
"""
205-
Initializes the RepositoryString with a given string source.
217+
Initialize RepositoryGoogleSecretManager with a Google Secret Manager source.
206218
207-
The provided string should have one "KEY=value" pair per line, similar
208-
to a `.env` file format. Lines starting with `#` are considered as
209-
comments and ignored. Surrounding whitespace is stripped from keys
210-
and values.
219+
The source string is expected to have one "KEY=value" pair per line, akin to
220+
the `.env` file format. Lines beginning with `#` are treated as comments and
221+
are disregarded. Keys and values are trimmed of surrounding whitespace for
222+
accurate parsing.
211223
212224
Args:
213-
source (str): The string source to parse.
225+
source (str): The string source from Google Secret Manager to be parsed.
214226
"""
215227
self.data = {}
216-
source_lines = source.split('\n')
228+
source_lines = source.split("\n")
217229

218230
for line in source_lines:
219231
line = line.strip()
220232

221-
if not line or line.startswith('#') or '=' not in line:
233+
if not line or line.startswith("#") or "=" not in line:
222234
continue
223235

224-
key, value = line.split('=', 1)
236+
key, value = line.split("=", 1)
225237
key = key.strip()
226238
value = value.strip()
227239

@@ -233,33 +245,6 @@ def __init__(self, source):
233245

234246
self.data[key] = value
235247

236-
def __contains__(self, key):
237-
"""
238-
Check if a key is present in the repository or the environment.
239-
240-
Args:
241-
key (str): The key to check for presence.
242-
243-
Returns:
244-
bool: True if key is in the repository or os.environ, False otherwise.
245-
"""
246-
return key in os.environ or key in self.data
247-
248-
def __getitem__(self, key):
249-
"""
250-
Retrieve the value associated with the given key.
251-
252-
Args:
253-
key (str): The key to retrieve the value for.
254-
255-
Returns:
256-
str: The value associated with the key.
257-
258-
Raises:
259-
KeyError: If the key is not found in the repository.
260-
"""
261-
return self.data[key]
262-
263248

264249
class AutoConfig(object):
265250
"""
@@ -272,10 +257,13 @@ class AutoConfig(object):
272257
caller's path.
273258
274259
"""
275-
SUPPORTED = OrderedDict([
276-
('settings.ini', RepositoryIni),
277-
('.env', RepositoryEnv),
278-
])
260+
261+
SUPPORTED = OrderedDict(
262+
[
263+
("settings.ini", RepositoryIni),
264+
(".env", RepositoryEnv),
265+
]
266+
)
279267

280268
encoding = DEFAULT_ENCODING
281269

@@ -292,18 +280,20 @@ def _find_file(self, path):
292280

293281
# search the parent
294282
parent = os.path.dirname(path)
295-
if parent and os.path.normcase(parent) != os.path.normcase(os.path.abspath(os.sep)):
283+
if parent and os.path.normcase(parent) != os.path.normcase(
284+
os.path.abspath(os.sep)
285+
):
296286
return self._find_file(parent)
297287

298288
# reached root without finding any files.
299-
return ''
289+
return ""
300290

301291
def _load(self, path):
302292
# Avoid unintended permission errors
303293
try:
304294
filename = self._find_file(os.path.abspath(path))
305295
except Exception:
306-
filename = ''
296+
filename = ""
307297
Repository = self.SUPPORTED.get(os.path.basename(filename), RepositoryEmpty)
308298

309299
self.config = Config(Repository(filename, encoding=self.encoding))
@@ -327,12 +317,15 @@ def __call__(self, *args, **kwargs):
327317

328318
# Helpers
329319

320+
330321
class Csv(object):
331322
"""
332323
Produces a csv parser that return a list of transformed elements.
333324
"""
334325

335-
def __init__(self, cast=text_type, delimiter=',', strip=string.whitespace, post_process=list):
326+
def __init__(
327+
self, cast=text_type, delimiter=",", strip=string.whitespace, post_process=list
328+
):
336329
"""
337330
Parameters:
338331
cast -- callable that transforms the item just before it's added to the list.
@@ -382,8 +375,10 @@ def __init__(self, flat=None, cast=text_type, choices=None):
382375
def __call__(self, value):
383376
transform = self.cast(value)
384377
if transform not in self._valid_values:
385-
raise ValueError((
386-
'Value not in list: {!r}; valid values are {!r}'
387-
).format(value, self._valid_values))
378+
raise ValueError(
379+
("Value not in list: {!r}; valid values are {!r}").format(
380+
value, self._valid_values
381+
)
382+
)
388383
else:
389384
return transform

0 commit comments

Comments
 (0)