appsettings2 1.2.6__tar.gz → 1.3.0__tar.gz
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.
- {appsettings2-1.2.6 → appsettings2-1.3.0}/LICENSE +1 -1
- {appsettings2-1.2.6 → appsettings2-1.3.0}/PKG-INFO +34 -4
- {appsettings2-1.2.6 → appsettings2-1.3.0}/pyproject.toml +17 -4
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/Configuration.py +42 -31
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/ConfigurationBuilder.py +6 -6
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/ConfigurationException.py +5 -2
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/__init__.py +4 -3
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/helpers.py +5 -2
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/CommandLineConfigurationProvider.py +7 -4
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/ConfigurationProvider.py +1 -1
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/EnvironmentConfigurationProvider.py +1 -1
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/JsonConfigurationProvider.py +5 -5
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/TomlConfigurationProvider.py +5 -5
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/YamlConfigurationProvider.py +7 -7
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/__init__.py +1 -1
- appsettings2-1.3.0/src/appsettings2/py.typed +0 -0
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2.egg-info/PKG-INFO +34 -4
- appsettings2-1.3.0/src/appsettings2.egg-info/SOURCES.txt +21 -0
- appsettings2-1.3.0/src/appsettings2.egg-info/requires.txt +7 -0
- appsettings2-1.3.0/src/appsettings2.egg-info/top_level.txt +1 -0
- appsettings2-1.2.6/appsettings2.egg-info/SOURCES.txt +0 -20
- appsettings2-1.2.6/appsettings2.egg-info/requires.txt +0 -1
- appsettings2-1.2.6/appsettings2.egg-info/top_level.txt +0 -4
- {appsettings2-1.2.6 → appsettings2-1.3.0}/README.md +0 -0
- {appsettings2-1.2.6 → appsettings2-1.3.0}/setup.cfg +0 -0
- {appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2.egg-info/dependency_links.txt +0 -0
|
@@ -1,20 +1,50 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: appsettings2
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Unifies configuration sources into a Configuration object that can be bound to complex types, or accessed directly for configuration data.
|
|
5
5
|
Author-email: Shaun Wilson <mrshaunwilson@msn.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
© 2025 Shaun Wilson
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
6
28
|
Project-URL: Documentation, https://appsettings2.readthedocs.io/
|
|
7
29
|
Project-URL: Homepage, https://github.com/wilson0x4d/appsettings2
|
|
8
30
|
Project-URL: Repository, https://github.com/wilson0x4d/appsettings2.git
|
|
31
|
+
Keywords: appsettings,configuration
|
|
9
32
|
Classifier: Intended Audience :: Developers
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
33
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier:
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
38
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
39
|
Requires-Python: >=3.11
|
|
15
40
|
Description-Content-Type: text/markdown
|
|
16
41
|
License-File: LICENSE
|
|
17
42
|
Requires-Dist: pyyaml>=6.0.2
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: mypy; extra == "dev"
|
|
45
|
+
Requires-Dist: punit>=1.2.8; extra == "dev"
|
|
46
|
+
Requires-Dist: twine; extra == "dev"
|
|
47
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
18
48
|
Dynamic: license-file
|
|
19
49
|
|
|
20
50
|
# `appsettings2`
|
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "appsettings2"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
4
4
|
description = "Unifies configuration sources into a Configuration object that can be bound to complex types, or accessed directly for configuration data."
|
|
5
|
+
keywords = ["appsettings", "configuration"]
|
|
5
6
|
authors = [
|
|
6
7
|
{ name="Shaun Wilson", email="mrshaunwilson@msn.com" }
|
|
7
8
|
]
|
|
8
9
|
readme = "README.md"
|
|
10
|
+
license = {file = "LICENSE"}
|
|
9
11
|
classifiers = [
|
|
10
12
|
"Intended Audience :: Developers",
|
|
11
|
-
"License :: OSI Approved :: MIT License",
|
|
12
13
|
"Operating System :: OS Independent",
|
|
13
|
-
"Programming Language :: Python",
|
|
14
|
-
"
|
|
14
|
+
"Programming Language :: Python :: 3.11",
|
|
15
|
+
"Programming Language :: Python :: 3.12",
|
|
16
|
+
"Programming Language :: Python :: 3.13",
|
|
17
|
+
"Programming Language :: Python :: 3.14",
|
|
18
|
+
"Topic :: Software Development :: Libraries :: Python Modules"
|
|
15
19
|
]
|
|
16
20
|
requires-python = ">=3.11"
|
|
17
21
|
dependencies = [
|
|
18
22
|
"pyyaml>=6.0.2"
|
|
19
23
|
]
|
|
20
24
|
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
dev = [
|
|
27
|
+
"mypy",
|
|
28
|
+
"punit>=1.2.8",
|
|
29
|
+
"twine",
|
|
30
|
+
"types-PyYAML"
|
|
31
|
+
]
|
|
32
|
+
|
|
21
33
|
[project.urls]
|
|
22
34
|
Documentation = "https://appsettings2.readthedocs.io/"
|
|
23
35
|
Homepage = "https://github.com/wilson0x4d/appsettings2"
|
|
@@ -28,6 +40,7 @@ requires = ["setuptools"]
|
|
|
28
40
|
build-backend = "setuptools.build_meta"
|
|
29
41
|
|
|
30
42
|
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
31
44
|
exclude = [
|
|
32
45
|
"docs",
|
|
33
46
|
"tests",
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
import logging
|
|
5
|
-
from .ConfigurationException import ConfigurationException
|
|
6
5
|
import json
|
|
7
6
|
import re
|
|
8
7
|
import types
|
|
9
8
|
import typing
|
|
9
|
+
from typing import Any, TYPE_CHECKING
|
|
10
10
|
import unicodedata
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
from .ConfigurationException import ConfigurationException
|
|
13
|
+
|
|
14
14
|
|
|
15
15
|
class Configuration:
|
|
16
16
|
"""
|
|
17
17
|
The :py:class:`~appsettings2.Configuration` class is how applications access configuration data populated by :py:class:`~appsettings2.providers.ConfigurationProvider` objects. It exposes configuration data through dynamic object attributes as well as a dictionary-like interface.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
__key_scrub_re:re.Pattern
|
|
20
|
+
__key_scrub_re:re.Pattern|None
|
|
21
21
|
__keys:dict[str, str]
|
|
22
22
|
__normalize:bool
|
|
23
23
|
|
|
@@ -31,6 +31,13 @@ class Configuration:
|
|
|
31
31
|
self.__normalize = normalize
|
|
32
32
|
self.__key_scrub_re = None if not scrubkeys else re.compile(r'[^A-Za-z0-9_]', re.IGNORECASE | re.UNICODE)
|
|
33
33
|
|
|
34
|
+
if TYPE_CHECKING:
|
|
35
|
+
# This tells mypy that accessing any attribute returns 'Any'
|
|
36
|
+
def __getattr__(self, name: str) -> Any: ...
|
|
37
|
+
|
|
38
|
+
# This tells mypy that setting any attribute is allowed
|
|
39
|
+
def __setattr__(self, name: str, value: Any) -> None: ...
|
|
40
|
+
|
|
34
41
|
def __delitem__(self, key:str) -> None:
|
|
35
42
|
key = key.upper()
|
|
36
43
|
k = self.__keys.get(key)
|
|
@@ -38,7 +45,7 @@ class Configuration:
|
|
|
38
45
|
delattr(self, k)
|
|
39
46
|
self.__keys.pop(key)
|
|
40
47
|
|
|
41
|
-
def __getitem__(self, key:str) ->
|
|
48
|
+
def __getitem__(self, key:str) -> Any:
|
|
42
49
|
"""
|
|
43
50
|
Gets the configuration data associated with the specified `key`.
|
|
44
51
|
|
|
@@ -64,7 +71,7 @@ class Configuration:
|
|
|
64
71
|
def __len__(self) -> int:
|
|
65
72
|
return len(self.__keys)
|
|
66
73
|
|
|
67
|
-
def __recursiveBind(self, target:object, source:Configuration|dict) ->
|
|
74
|
+
def __recursiveBind(self, target:object, source:Configuration|dict) -> Any:
|
|
68
75
|
if target is None:
|
|
69
76
|
return None
|
|
70
77
|
if hasattr(target, '__class__'):
|
|
@@ -89,11 +96,18 @@ class Configuration:
|
|
|
89
96
|
except AttributeError:
|
|
90
97
|
lval = None
|
|
91
98
|
self.__logger.debug(f'Failed to bind {aname}', exc_info=True)
|
|
92
|
-
if (not hasattr(prop, 'fset')
|
|
99
|
+
if (not hasattr(prop, 'fset') or getattr(prop, 'fset') is None):
|
|
93
100
|
# NOTE: lval is not settable
|
|
94
|
-
if
|
|
95
|
-
#
|
|
101
|
+
if rval is None:
|
|
102
|
+
# no assigment attempt will be made
|
|
96
103
|
continue
|
|
104
|
+
elif lval is not None:
|
|
105
|
+
if rval is not None and lval == rval:
|
|
106
|
+
# same value, no need to assign
|
|
107
|
+
continue
|
|
108
|
+
elif not (issubclass(type(lval), list) and issubclass(type(rval), list)):
|
|
109
|
+
# non-list values cannot be merged
|
|
110
|
+
raise Exception(f'Cannot bind `None` to attribute `{aname}`')
|
|
97
111
|
phints = typing.get_type_hints(getattr(prop, 'fget'))
|
|
98
112
|
if phints is None or (not issubclass(type(phints), dict)):
|
|
99
113
|
# NOTE: can't get hints from getter, can't bind
|
|
@@ -105,14 +119,11 @@ class Configuration:
|
|
|
105
119
|
if rval is None:
|
|
106
120
|
setattr(target, aname, None)
|
|
107
121
|
elif ahint is float:
|
|
108
|
-
|
|
109
|
-
setattr(target, aname, v)
|
|
122
|
+
setattr(target, aname, float(rval))
|
|
110
123
|
elif ahint is int:
|
|
111
|
-
|
|
112
|
-
setattr(target, aname, v)
|
|
124
|
+
setattr(target, aname, int(rval))
|
|
113
125
|
elif ahint is str:
|
|
114
|
-
|
|
115
|
-
setattr(target, aname, v)
|
|
126
|
+
setattr(target, aname, str(rval))
|
|
116
127
|
elif isinstance(rval, Configuration):
|
|
117
128
|
if typing.get_origin(ahint) is dict:
|
|
118
129
|
lval = rval.toDictionary()
|
|
@@ -128,13 +139,14 @@ class Configuration:
|
|
|
128
139
|
lval = ahint()
|
|
129
140
|
setattr(target, aname, lval)
|
|
130
141
|
for e in rval:
|
|
131
|
-
|
|
132
|
-
|
|
142
|
+
lval.append(
|
|
143
|
+
self.__recursiveBindType(elementType, e)
|
|
144
|
+
)
|
|
133
145
|
else:
|
|
134
146
|
setattr(target, aname, rval)
|
|
135
147
|
return target
|
|
136
148
|
|
|
137
|
-
def __recursiveBindType(self, elementType:type, source:
|
|
149
|
+
def __recursiveBindType(self, elementType:type, source:Any) -> Any:
|
|
138
150
|
if isinstance(source, elementType):
|
|
139
151
|
return source
|
|
140
152
|
elif elementType is float:
|
|
@@ -152,8 +164,7 @@ class Configuration:
|
|
|
152
164
|
def __scrub_key(self, key:str) -> str:
|
|
153
165
|
"""Scrubs a key for use as an attribute/identifier according to the Python lexer/standard."""
|
|
154
166
|
key = key.replace(':', '__').replace('.', '_')
|
|
155
|
-
return key if None
|
|
156
|
-
self.__key_scrub_re.sub(
|
|
167
|
+
return key if self.__key_scrub_re is None else self.__key_scrub_re.sub(
|
|
157
168
|
self.__scrub_uc,
|
|
158
169
|
unicodedata.normalize(
|
|
159
170
|
'NFKC',
|
|
@@ -166,13 +177,13 @@ class Configuration:
|
|
|
166
177
|
case _:
|
|
167
178
|
return '_'
|
|
168
179
|
|
|
169
|
-
def __setitem__(self, key:str, value:
|
|
180
|
+
def __setitem__(self, key:str, value:Any) -> None:
|
|
170
181
|
self.set(key, value)
|
|
171
182
|
|
|
172
183
|
def __str__(self) -> str:
|
|
173
184
|
return json.dumps(self.toDictionary())
|
|
174
185
|
|
|
175
|
-
def bind(self, target:object, key:str|None = None) ->
|
|
186
|
+
def bind(self, target:object, key:str|None = None) -> Any:
|
|
176
187
|
"""
|
|
177
188
|
Binds the configuration values into the target object.
|
|
178
189
|
Can optionally specify a configuration key to bind from.
|
|
@@ -218,7 +229,7 @@ class Configuration:
|
|
|
218
229
|
config.set(kvp[0], v)
|
|
219
230
|
return config
|
|
220
231
|
|
|
221
|
-
def get(self, key:str, default:
|
|
232
|
+
def get(self, key:str, default:Any = None) -> Any:
|
|
222
233
|
"""
|
|
223
234
|
Gets the configuration data associated with the specified `key`.
|
|
224
235
|
|
|
@@ -242,7 +253,7 @@ class Configuration:
|
|
|
242
253
|
def has_key(self, key:str) -> bool:
|
|
243
254
|
return self.__keys.get(key.upper()) is not None
|
|
244
255
|
|
|
245
|
-
def items(self) -> list[tuple[str,
|
|
256
|
+
def items(self) -> list[tuple[str,Any]]:
|
|
246
257
|
it = []
|
|
247
258
|
for k in self.keys():
|
|
248
259
|
v = self.get(k)
|
|
@@ -250,14 +261,14 @@ class Configuration:
|
|
|
250
261
|
return it
|
|
251
262
|
|
|
252
263
|
def keys(self) -> list[str]:
|
|
253
|
-
return self.__keys.values()
|
|
264
|
+
return list(self.__keys.values())
|
|
254
265
|
|
|
255
|
-
def pop(self, key:str) ->
|
|
266
|
+
def pop(self, key:str) -> Any:
|
|
256
267
|
value = self[key]
|
|
257
268
|
del self[key]
|
|
258
269
|
return value
|
|
259
270
|
|
|
260
|
-
def set(self, key:str, value:
|
|
271
|
+
def set(self, key:str, value:Any) -> None:
|
|
261
272
|
"""
|
|
262
273
|
Sets the configuration data for the specified `key`.
|
|
263
274
|
|
|
@@ -307,13 +318,13 @@ class Configuration:
|
|
|
307
318
|
else:
|
|
308
319
|
o.set(key, value)
|
|
309
320
|
|
|
310
|
-
def toDictionary(self) -> dict:
|
|
321
|
+
def toDictionary(self) -> dict[str,Any]:
|
|
311
322
|
"""
|
|
312
323
|
Creates a dictionary from the `Configuration` object.
|
|
313
324
|
|
|
314
325
|
:return: A dictionary containing all keys and their associated values, in a structure that mimics the structure if the data contained within the `Configuration` object.
|
|
315
326
|
"""
|
|
316
|
-
result =
|
|
327
|
+
result = dict[str,Any]()
|
|
317
328
|
for k in self.__keys.values():
|
|
318
329
|
v = getattr(self, self.__scrub_key(k))
|
|
319
330
|
if isinstance(v, Configuration):
|
|
@@ -330,7 +341,7 @@ class Configuration:
|
|
|
330
341
|
result[k] = v
|
|
331
342
|
return result
|
|
332
343
|
|
|
333
|
-
def values(self) -> list[
|
|
344
|
+
def values(self) -> list[Any]:
|
|
334
345
|
values = []
|
|
335
346
|
for k in self.__keys.values():
|
|
336
347
|
v = getattr(self, self.__scrub_key(k))
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
from .Configuration import Configuration
|
|
5
5
|
from .ConfigurationException import ConfigurationException
|
|
6
6
|
from .providers import *
|
|
7
|
-
import
|
|
7
|
+
from typing import Optional
|
|
8
8
|
|
|
9
9
|
type FileDescriptor = int
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
|
|
12
12
|
class ConfigurationBuilder:
|
|
13
13
|
"""
|
|
@@ -56,7 +56,7 @@ class ConfigurationBuilder:
|
|
|
56
56
|
"""
|
|
57
57
|
return self.addProvider(EnvironmentConfigurationProvider())
|
|
58
58
|
|
|
59
|
-
def addJson(self, filepath:str = None, *, json:str = None, fd:FileDescriptor = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
59
|
+
def addJson(self, filepath:Optional[str] = None, *, json:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
60
60
|
"""
|
|
61
61
|
Adds a :py:class:`~appsettings2.providers.JsonConfigurationProvider`.
|
|
62
62
|
The `filepath`, `json`, and `fd` parameters are mutually exclusive.
|
|
@@ -69,7 +69,7 @@ class ConfigurationBuilder:
|
|
|
69
69
|
"""
|
|
70
70
|
return self.addProvider(JsonConfigurationProvider(filepath=filepath, json=json, fd=fd, required=required))
|
|
71
71
|
|
|
72
|
-
def addToml(self, filepath:str = None, *, toml:str = None, fd:FileDescriptor = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
72
|
+
def addToml(self, filepath:Optional[str] = None, *, toml:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
73
73
|
"""
|
|
74
74
|
Adds a :py:class:`~appsettings2.providers.TomlConfigurationProvider`.
|
|
75
75
|
The `filepath`, `toml`, and `fd` parameters are mutually exclusive.
|
|
@@ -82,7 +82,7 @@ class ConfigurationBuilder:
|
|
|
82
82
|
"""
|
|
83
83
|
return self.addProvider(TomlConfigurationProvider(filepath=filepath, toml=toml, fd=fd, required=required))
|
|
84
84
|
|
|
85
|
-
def addYaml(self, filepath:str = None, *, yaml:str = None, fd:FileDescriptor = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
85
|
+
def addYaml(self, filepath:Optional[str] = None, *, yaml:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True) -> 'ConfigurationBuilder':
|
|
86
86
|
"""
|
|
87
87
|
Adds a :py:class:`~appsettings2.providers.YamlConfigurationProvider`.
|
|
88
88
|
The `filepath`, `yaml`, and `fd` parameters are mutually exclusive.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
|
|
4
7
|
class ConfigurationException(Exception):
|
|
5
8
|
"""An exception raised by `appsettings2` library."""
|
|
6
|
-
def __init__(self, reason:str = None):
|
|
9
|
+
def __init__(self, reason:Optional[str] = None):
|
|
7
10
|
super().__init__(reason)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
__version__ = '1.
|
|
5
|
-
__commit__ = '
|
|
4
|
+
__version__ = '1.3.0'
|
|
5
|
+
__commit__ = '0abc123'
|
|
6
6
|
|
|
7
7
|
from .Configuration import Configuration
|
|
8
8
|
from .ConfigurationBuilder import ConfigurationBuilder
|
|
@@ -11,6 +11,7 @@ from .helpers import getConfiguration
|
|
|
11
11
|
from . import helpers
|
|
12
12
|
from . import providers
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
__all__ = [
|
|
15
16
|
'__version__', '__commit__',
|
|
16
17
|
'Configuration',
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
4
6
|
from .Configuration import Configuration
|
|
5
7
|
from .ConfigurationBuilder import ConfigurationBuilder
|
|
6
8
|
from .providers import *
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
|
|
11
|
+
def getConfiguration(baseName:str = 'appsettings', json:bool = True, toml:bool = True, yaml:bool = True, cli:bool = True, environment:bool = True, variations:Optional[list[str|None]] = ['', 'prod', 'production', 'stage', 'staging', 'qa', 'dev', 'development', 'local']) -> Configuration:
|
|
9
12
|
builder:ConfigurationBuilder = ConfigurationBuilder()
|
|
10
13
|
variations = variations if variations is not None and len(variations) > 0 else [None]
|
|
11
14
|
for variation in variations:
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
from .ConfigurationProvider import ConfigurationProvider
|
|
5
|
-
from ..Configuration import Configuration
|
|
6
4
|
import sys
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from ..Configuration import Configuration
|
|
8
|
+
from .ConfigurationProvider import ConfigurationProvider
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
class CommandLineConfigurationProvider(ConfigurationProvider):
|
|
9
12
|
"""
|
|
@@ -12,7 +15,7 @@ class CommandLineConfigurationProvider(ConfigurationProvider):
|
|
|
12
15
|
|
|
13
16
|
__argv:list[str]
|
|
14
17
|
|
|
15
|
-
def __init__(self, argv:list[str] = None):
|
|
18
|
+
def __init__(self, argv:Optional[list[str]] = None):
|
|
16
19
|
"""
|
|
17
20
|
:param argv: Optional arg list used in lieu of `sys.argv`, defaults to None.
|
|
18
21
|
"""
|
{appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/JsonConfigurationProvider.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
from .ConfigurationProvider import ConfigurationProvider
|
|
@@ -6,19 +6,19 @@ from ..Configuration import Configuration
|
|
|
6
6
|
from ..ConfigurationException import ConfigurationException
|
|
7
7
|
import json as _json
|
|
8
8
|
import os
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Optional
|
|
10
10
|
|
|
11
11
|
type FileDescriptor = int
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
|
|
14
14
|
class JsonConfigurationProvider(ConfigurationProvider):
|
|
15
15
|
"""
|
|
16
16
|
Populates structured configuration data from JSON.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
__obj:dict
|
|
19
|
+
__obj:dict|None
|
|
20
20
|
|
|
21
|
-
def __init__(self, filepath:str = None, *, json:str = None, fd:FileDescriptor = None, required:bool = True):
|
|
21
|
+
def __init__(self, filepath:Optional[str] = None, *, json:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True):
|
|
22
22
|
"""
|
|
23
23
|
The `filepath`, `json`, and `fd` parameters are mutually exclusive.
|
|
24
24
|
|
{appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/TomlConfigurationProvider.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
from .ConfigurationProvider import ConfigurationProvider
|
|
@@ -6,19 +6,19 @@ from ..Configuration import Configuration
|
|
|
6
6
|
from ..ConfigurationException import ConfigurationException
|
|
7
7
|
import os
|
|
8
8
|
import tomllib as _toml
|
|
9
|
-
from typing import Any
|
|
9
|
+
from typing import Any, Optional
|
|
10
10
|
|
|
11
11
|
type FileDescriptor = int
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
|
|
14
14
|
class TomlConfigurationProvider(ConfigurationProvider):
|
|
15
15
|
"""
|
|
16
16
|
Populates structured configuration data from TOML.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
__obj:dict
|
|
19
|
+
__obj:dict|None
|
|
20
20
|
|
|
21
|
-
def __init__(self, filepath:str = None, *, toml:str = None, fd:FileDescriptor = None, required:bool = True):
|
|
21
|
+
def __init__(self, filepath:Optional[str] = None, *, toml:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True):
|
|
22
22
|
"""
|
|
23
23
|
The `filepath`, `toml`, and `fd` parameters are mutually exclusive.
|
|
24
24
|
|
{appsettings2-1.2.6 → appsettings2-1.3.0/src}/appsettings2/providers/YamlConfigurationProvider.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SPDX-FileCopyrightText:
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 Shaun Wilson
|
|
2
2
|
# SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
from .ConfigurationProvider import ConfigurationProvider
|
|
@@ -6,25 +6,25 @@ from ..Configuration import Configuration
|
|
|
6
6
|
from ..ConfigurationException import ConfigurationException
|
|
7
7
|
from io import StringIO
|
|
8
8
|
import os
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Optional
|
|
10
10
|
import yaml as _yaml
|
|
11
11
|
|
|
12
12
|
type FileDescriptor = int
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
|
|
15
15
|
class YamlConfigurationProvider(ConfigurationProvider):
|
|
16
16
|
"""
|
|
17
17
|
Populates structured configuration data from YAML.
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
-
__obj:dict
|
|
20
|
+
__obj:dict|None
|
|
21
21
|
|
|
22
|
-
def __init__(self, filepath:str = None, *, yaml:str = None, fd:FileDescriptor = None, required:bool = True):
|
|
22
|
+
def __init__(self, filepath:Optional[str] = None, *, yaml:Optional[str] = None, fd:Optional[FileDescriptor] = None, required:bool = True):
|
|
23
23
|
"""
|
|
24
24
|
The `filepath`, `yaml`, and `fd` parameters are mutually exclusive.
|
|
25
25
|
|
|
26
|
-
:param filepath: Optional path to a
|
|
27
|
-
:param yaml: Optional
|
|
26
|
+
:param filepath: Optional path to a YAML file used as a configuration source, defaults to None.
|
|
27
|
+
:param yaml: Optional YAML string used as a configuration source, defaults to None.
|
|
28
28
|
:param fd: Optional file descriptor (int) to be used as a configuration source, defaults to None.
|
|
29
29
|
:param required: Optional parameter indicating whether the configuration source will raise `ConfigurationException` if the specified configuration source is missing, defaults to True.
|
|
30
30
|
"""
|
|
File without changes
|
|
@@ -1,20 +1,50 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: appsettings2
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Unifies configuration sources into a Configuration object that can be bound to complex types, or accessed directly for configuration data.
|
|
5
5
|
Author-email: Shaun Wilson <mrshaunwilson@msn.com>
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
© 2025 Shaun Wilson
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
6
28
|
Project-URL: Documentation, https://appsettings2.readthedocs.io/
|
|
7
29
|
Project-URL: Homepage, https://github.com/wilson0x4d/appsettings2
|
|
8
30
|
Project-URL: Repository, https://github.com/wilson0x4d/appsettings2.git
|
|
31
|
+
Keywords: appsettings,configuration
|
|
9
32
|
Classifier: Intended Audience :: Developers
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
33
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier:
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
38
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
39
|
Requires-Python: >=3.11
|
|
15
40
|
Description-Content-Type: text/markdown
|
|
16
41
|
License-File: LICENSE
|
|
17
42
|
Requires-Dist: pyyaml>=6.0.2
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: mypy; extra == "dev"
|
|
45
|
+
Requires-Dist: punit>=1.2.8; extra == "dev"
|
|
46
|
+
Requires-Dist: twine; extra == "dev"
|
|
47
|
+
Requires-Dist: types-PyYAML; extra == "dev"
|
|
18
48
|
Dynamic: license-file
|
|
19
49
|
|
|
20
50
|
# `appsettings2`
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/appsettings2/Configuration.py
|
|
5
|
+
src/appsettings2/ConfigurationBuilder.py
|
|
6
|
+
src/appsettings2/ConfigurationException.py
|
|
7
|
+
src/appsettings2/__init__.py
|
|
8
|
+
src/appsettings2/helpers.py
|
|
9
|
+
src/appsettings2/py.typed
|
|
10
|
+
src/appsettings2.egg-info/PKG-INFO
|
|
11
|
+
src/appsettings2.egg-info/SOURCES.txt
|
|
12
|
+
src/appsettings2.egg-info/dependency_links.txt
|
|
13
|
+
src/appsettings2.egg-info/requires.txt
|
|
14
|
+
src/appsettings2.egg-info/top_level.txt
|
|
15
|
+
src/appsettings2/providers/CommandLineConfigurationProvider.py
|
|
16
|
+
src/appsettings2/providers/ConfigurationProvider.py
|
|
17
|
+
src/appsettings2/providers/EnvironmentConfigurationProvider.py
|
|
18
|
+
src/appsettings2/providers/JsonConfigurationProvider.py
|
|
19
|
+
src/appsettings2/providers/TomlConfigurationProvider.py
|
|
20
|
+
src/appsettings2/providers/YamlConfigurationProvider.py
|
|
21
|
+
src/appsettings2/providers/__init__.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
appsettings2
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
appsettings2/Configuration.py
|
|
5
|
-
appsettings2/ConfigurationBuilder.py
|
|
6
|
-
appsettings2/ConfigurationException.py
|
|
7
|
-
appsettings2/__init__.py
|
|
8
|
-
appsettings2/helpers.py
|
|
9
|
-
appsettings2.egg-info/PKG-INFO
|
|
10
|
-
appsettings2.egg-info/SOURCES.txt
|
|
11
|
-
appsettings2.egg-info/dependency_links.txt
|
|
12
|
-
appsettings2.egg-info/requires.txt
|
|
13
|
-
appsettings2.egg-info/top_level.txt
|
|
14
|
-
appsettings2/providers/CommandLineConfigurationProvider.py
|
|
15
|
-
appsettings2/providers/ConfigurationProvider.py
|
|
16
|
-
appsettings2/providers/EnvironmentConfigurationProvider.py
|
|
17
|
-
appsettings2/providers/JsonConfigurationProvider.py
|
|
18
|
-
appsettings2/providers/TomlConfigurationProvider.py
|
|
19
|
-
appsettings2/providers/YamlConfigurationProvider.py
|
|
20
|
-
appsettings2/providers/__init__.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
pyyaml>=6.0.2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|