allconf 4.0.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.
Files changed (42) hide show
  1. allconf-4.0.0/LICENSE +22 -0
  2. allconf-4.0.0/PKG-INFO +118 -0
  3. allconf-4.0.0/README.md +63 -0
  4. allconf-4.0.0/allconf/__init__.py +5 -0
  5. allconf-4.0.0/allconf/cli/__init__.py +0 -0
  6. allconf-4.0.0/allconf/cli/render/__init__.py +0 -0
  7. allconf-4.0.0/allconf/cli/render/main.py +66 -0
  8. allconf-4.0.0/allconf/cli/stubber/__init__.py +0 -0
  9. allconf-4.0.0/allconf/cli/stubber/main.py +74 -0
  10. allconf-4.0.0/allconf/loaders/__init__.py +4 -0
  11. allconf-4.0.0/allconf/loaders/autoloader.py +93 -0
  12. allconf-4.0.0/allconf/loaders/base.py +442 -0
  13. allconf-4.0.0/allconf/loaders/interface.py +89 -0
  14. allconf-4.0.0/allconf/loaders/jsonfile.py +48 -0
  15. allconf-4.0.0/allconf/loaders/yamlfile.py +35 -0
  16. allconf-4.0.0/allconf/quickloader.py +2 -0
  17. allconf-4.0.0/allconf/renderers/__init__.py +1 -0
  18. allconf-4.0.0/allconf/renderers/static/__init__.py +2 -0
  19. allconf-4.0.0/allconf/renderers/static/_simple.py +34 -0
  20. allconf-4.0.0/allconf/renderers/static/interface.py +21 -0
  21. allconf-4.0.0/allconf/structs/__init__.py +3 -0
  22. allconf-4.0.0/allconf/structs/_base.py +2 -0
  23. allconf-4.0.0/allconf/structs/baseconfig.py +124 -0
  24. allconf-4.0.0/allconf/structs/cfgstub.py +12 -0
  25. allconf-4.0.0/allconf/structs/errors.py +94 -0
  26. allconf-4.0.0/allconf/structs/singletonconfig.py +10 -0
  27. allconf-4.0.0/allconf/stubber/__init__.py +1 -0
  28. allconf-4.0.0/allconf/stubber/stubmaker/__init__.py +3 -0
  29. allconf-4.0.0/allconf/stubber/stubmaker/_simple.py +74 -0
  30. allconf-4.0.0/allconf/stubber/stubmaker/_structs.py +296 -0
  31. allconf-4.0.0/allconf/stubber/stubmaker/interface.py +23 -0
  32. allconf-4.0.0/allconf/utils/__init__.py +1 -0
  33. allconf-4.0.0/allconf/utils/kwfields.py +89 -0
  34. allconf-4.0.0/allconf.egg-info/PKG-INFO +118 -0
  35. allconf-4.0.0/allconf.egg-info/SOURCES.txt +40 -0
  36. allconf-4.0.0/allconf.egg-info/dependency_links.txt +1 -0
  37. allconf-4.0.0/allconf.egg-info/entry_points.txt +3 -0
  38. allconf-4.0.0/allconf.egg-info/requires.txt +5 -0
  39. allconf-4.0.0/allconf.egg-info/top_level.txt +1 -0
  40. allconf-4.0.0/pyproject.toml +62 -0
  41. allconf-4.0.0/setup.cfg +4 -0
  42. allconf-4.0.0/setup.py +6 -0
allconf-4.0.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Thordur Matthiasson
4
+ Copyright (c) 2019-2024 CCP Games
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
allconf-4.0.0/PKG-INFO ADDED
@@ -0,0 +1,118 @@
1
+ Metadata-Version: 2.1
2
+ Name: allconf
3
+ Version: 4.0.0
4
+ Summary: Configuration file reader with some nifty bells and whistles added
5
+ Author-email: Thordur Matthiasson <doddi79@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Thordur Matthiasson
9
+ Copyright (c) 2019-2024 CCP Games
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: Homepage, https://github.com/doddi79/allconf
30
+ Project-URL: Documentation, https://github.com/doddi79/allconf/blob/main/README.md
31
+ Project-URL: Repository, https://github.com/doddi79/allconf.git
32
+ Project-URL: Issues, https://github.com/doddi79/allconf/issues
33
+ Project-URL: Changelog, https://github.com/doddi79/allconf/blob/main/CHANGELOG.md
34
+ Keywords: config,configuration,json,yaml,tools,utils
35
+ Classifier: Development Status :: 5 - Production/Stable
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Intended Audience :: Developers
38
+ Classifier: Programming Language :: Python
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.8
41
+ Classifier: Programming Language :: Python :: 3.9
42
+ Classifier: Programming Language :: Python :: 3.10
43
+ Classifier: Programming Language :: Python :: 3.11
44
+ Classifier: Programming Language :: Python :: 3.12
45
+ Classifier: Topic :: Software Development
46
+ Classifier: Topic :: Software Development :: Libraries
47
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
48
+ Classifier: Topic :: Utilities
49
+ Description-Content-Type: text/markdown
50
+ License-File: LICENSE
51
+ Requires-Dist: PyYAML<7,>=6.0.1
52
+ Requires-Dist: batutils<3,>=2
53
+ Provides-Extra: fidelius
54
+ Requires-Dist: fidelius<2,>=1.0; extra == "fidelius"
55
+
56
+ # AllConf the All-Knowing Config Reader
57
+
58
+ Generic Configuration file reader/parser with a bunch of nifty extra
59
+ features, most notably:
60
+
61
+ - File Inclusion & Extension
62
+ - Internal variable reference parsing
63
+ - Nested fault-tolerant fetching of non-existing values
64
+ - Environment variable embedding
65
+ - On-demand external secret credential embedding _(untested in this new fork thus far)_
66
+ - Python script result embedding
67
+ - Single-file rendering of parsed config file (via CLI)
68
+ - Python dataclass stub generation (via CLI)
69
+ - JSON, YAML & custom support
70
+ - ...and more
71
+
72
+
73
+ ## Note
74
+
75
+ This was forked from the [`alviss`](https://github.com/ccpgames/allconf) package
76
+ in order to continue development and support.
77
+
78
+ ## The TL;DR...
79
+
80
+ Given this `my_cfg.yaml` config file example:
81
+
82
+ ```yaml
83
+ app:
84
+ name: MyApp
85
+ environment: dev
86
+ log_level: INFO
87
+ ```
88
+
89
+ This is how you load and use it with `allconf`:
90
+
91
+ ```python
92
+ from allconf import quickloader
93
+
94
+ cfg = quickloader.autoload('my_cfg.yaml')
95
+
96
+ assert cfg.app.name == 'MyApp'
97
+ assert cfg.app.environment == 'dev'
98
+ assert cfg.app.log_level == 'INFO'
99
+ ```
100
+
101
+ And that's basically it really!
102
+
103
+ Read on for description of more features in order of "quality of life" impact
104
+ for you as a programmer _(as gauged by myself)_ and it goes more or less like this:
105
+
106
+ 1. File Inclusion & Extension
107
+ 2. Internal variable reference parsing
108
+ 3. Nested fault-tolerant fetching of non-existing values
109
+ 4. Environment variable embedding
110
+ 5. On-demand external secret credential embedding _(untested in this new fork thus far)_
111
+ 6. Python script result embedding
112
+ 7. Single-file rendering of parsed config file (via CLI)
113
+ 8. Python dataclass stub generation (via CLI)
114
+ 9. JSON, YAML & custom support
115
+
116
+ ...I'll document this later!
117
+
118
+ Check out the (`_OLD_README.md`)[_OLD_README.md] file for the old documentation (which may or may not be up to date)!
@@ -0,0 +1,63 @@
1
+ # AllConf the All-Knowing Config Reader
2
+
3
+ Generic Configuration file reader/parser with a bunch of nifty extra
4
+ features, most notably:
5
+
6
+ - File Inclusion & Extension
7
+ - Internal variable reference parsing
8
+ - Nested fault-tolerant fetching of non-existing values
9
+ - Environment variable embedding
10
+ - On-demand external secret credential embedding _(untested in this new fork thus far)_
11
+ - Python script result embedding
12
+ - Single-file rendering of parsed config file (via CLI)
13
+ - Python dataclass stub generation (via CLI)
14
+ - JSON, YAML & custom support
15
+ - ...and more
16
+
17
+
18
+ ## Note
19
+
20
+ This was forked from the [`alviss`](https://github.com/ccpgames/allconf) package
21
+ in order to continue development and support.
22
+
23
+ ## The TL;DR...
24
+
25
+ Given this `my_cfg.yaml` config file example:
26
+
27
+ ```yaml
28
+ app:
29
+ name: MyApp
30
+ environment: dev
31
+ log_level: INFO
32
+ ```
33
+
34
+ This is how you load and use it with `allconf`:
35
+
36
+ ```python
37
+ from allconf import quickloader
38
+
39
+ cfg = quickloader.autoload('my_cfg.yaml')
40
+
41
+ assert cfg.app.name == 'MyApp'
42
+ assert cfg.app.environment == 'dev'
43
+ assert cfg.app.log_level == 'INFO'
44
+ ```
45
+
46
+ And that's basically it really!
47
+
48
+ Read on for description of more features in order of "quality of life" impact
49
+ for you as a programmer _(as gauged by myself)_ and it goes more or less like this:
50
+
51
+ 1. File Inclusion & Extension
52
+ 2. Internal variable reference parsing
53
+ 3. Nested fault-tolerant fetching of non-existing values
54
+ 4. Environment variable embedding
55
+ 5. On-demand external secret credential embedding _(untested in this new fork thus far)_
56
+ 6. Python script result embedding
57
+ 7. Single-file rendering of parsed config file (via CLI)
58
+ 8. Python dataclass stub generation (via CLI)
59
+ 9. JSON, YAML & custom support
60
+
61
+ ...I'll document this later!
62
+
63
+ Check out the (`_OLD_README.md`)[_OLD_README.md] file for the old documentation (which may or may not be up to date)!
@@ -0,0 +1,5 @@
1
+ __version__ = '4.0.0'
2
+
3
+ __author__ = 'Thordur Matthiasson <doddi79@gmail.com>'
4
+ __license__ = 'MIT License'
5
+ __copyright__ = 'Copyright 2024 -Thordur Matthiasson, Copyright 2019-2024 - CCP Games ehf'
File without changes
File without changes
@@ -0,0 +1,66 @@
1
+ import argparse
2
+
3
+ from allconf import __version__ as version
4
+ from allconf.renderers import SimpleStaticRenderer
5
+ from allconf.structs.errors import *
6
+
7
+ import sys
8
+
9
+
10
+ def main():
11
+ parser = argparse.ArgumentParser(description='Renders a single static config from an AllConf formatted file and '
12
+ 'its extends, includes and other expressions.',
13
+ epilog=f'AllConf version {version}')
14
+
15
+ parser.add_argument('file', help='The AllConf formatted config file to read, parse and render')
16
+ parser.add_argument('-o', '--output', help='File to write the results to (otherwise its just printed to stdout)',
17
+ default='', nargs='?')
18
+ parser.add_argument('-f', '--force-overwrite', help='Overwrite existing output file if it exists',
19
+ action='store_true')
20
+
21
+ loudness_group = parser.add_mutually_exclusive_group()
22
+ loudness_group.add_argument('-s', '--silent', action='store_true',
23
+ help='Only outputs the resulting rendered config (and errors print to stderr)')
24
+ loudness_group.add_argument('-v', '--verbose', action="store_true",
25
+ help='Spits out DEBUG level logs')
26
+
27
+ args = parser.parse_args()
28
+
29
+ if args.verbose:
30
+ import logging
31
+ logging.basicConfig(level=logging.DEBUG)
32
+
33
+ if not args.silent:
34
+ print(f'Reading and parsing file: {args.file}...')
35
+
36
+ try:
37
+ if args.output:
38
+ if not args.silent:
39
+ print(f'Writing output to: {args.output}...')
40
+
41
+ SimpleStaticRenderer().render_static_config_to_file(input_file=args.file,
42
+ output_file=args.output,
43
+ overwrite_existing=args.force_overwrite)
44
+
45
+ else:
46
+ if not args.silent:
47
+ print(f'Printing results:')
48
+ print(f'==================================================')
49
+ print(SimpleStaticRenderer().render_static_config_from_file(args.file))
50
+
51
+ if not args.silent:
52
+ print(f'==================================================')
53
+
54
+ if not args.silent:
55
+ print(f'Done!')
56
+
57
+ except AllConfError as e:
58
+ if not args.silent:
59
+ print(f'An error occurred: {e!r}')
60
+ else:
61
+ print(f'An error occurred: {e!r}', file=sys.stderr)
62
+ sys.exit(3)
63
+
64
+
65
+ if __name__ == '__main__':
66
+ main()
File without changes
@@ -0,0 +1,74 @@
1
+ import argparse
2
+
3
+ from allconf import __version__ as version
4
+ from allconf import stubber
5
+ from allconf.structs.errors import *
6
+ import sys
7
+
8
+
9
+ def main():
10
+ parser = argparse.ArgumentParser(description='Generates Python dataclass stubs based on the given allconf type descriptor file.',
11
+ epilog=f'AllConf version {version}')
12
+
13
+ parser.add_argument('file', help='The AllConf config type descriptor file to generate strubs from.')
14
+ parser.add_argument('-o', '--output', help='File to write the generated stub code to (otherwise its just printed to stdout)',
15
+ default='', nargs='?')
16
+ parser.add_argument('-f', '--force-overwrite', help='Overwrite existing output file if it exists', action='store_true')
17
+ parser.add_argument('-n', '--class-name',
18
+ help='The name of the resulting "final" stub class generated when outputting to a file (default is "AllConfConfigStub"). Set to "None" to skip generating the "final" class.',
19
+ default='AllConfConfigStub')
20
+ parser.add_argument('-x', '--export-all', help='Make all stub class names public and export via __all__ when outputting to a file.',
21
+ action='store_true')
22
+
23
+ loudness_group = parser.add_mutually_exclusive_group()
24
+ loudness_group.add_argument('-s', '--silent', action='store_true',
25
+ help='Only outputs the resulting rendered code (and errors print to stderr)')
26
+ loudness_group.add_argument('-v', '--verbose', action="store_true",
27
+ help='Spits out DEBUG level logs')
28
+
29
+ args = parser.parse_args()
30
+
31
+ if args.verbose:
32
+ import logging
33
+ logging.basicConfig(level=logging.DEBUG)
34
+
35
+ if not args.silent:
36
+ print(f'Reading and stubbing file: {args.file}...')
37
+
38
+ cls_name = 'AllConfConfigStub' if args.class_name is None else args.class_name
39
+ if cls_name.lower().strip() == 'none':
40
+ cls_name = ''
41
+
42
+ try:
43
+ if args.output:
44
+ if not args.silent:
45
+ print(f'Writing output to: {args.output}...')
46
+
47
+ stubber.SimpleStubMaker().render_stub_classes_to_file(input_file=args.file,
48
+ output_file=args.output,
49
+ overwrite_existing=args.force_overwrite,
50
+ is_private=not args.export_all,
51
+ class_name=cls_name)
52
+ else:
53
+ if not args.silent:
54
+ print(f'Printing results:')
55
+ print(f'==================================================')
56
+
57
+ print(stubber.SimpleStubMaker().render_stub_classes_from_descriptor_file(args.file, class_name=cls_name, is_private=not args.export_all))
58
+
59
+ if not args.silent:
60
+ print(f'==================================================')
61
+
62
+ if not args.silent:
63
+ print(f'Done!')
64
+
65
+ except AllConfError as e:
66
+ if not args.silent:
67
+ print(f'An error occurred: {e!r}')
68
+ else:
69
+ print(f'An error occurred: {e!r}', file=sys.stderr)
70
+ sys.exit(3)
71
+
72
+
73
+ if __name__ == '__main__':
74
+ main()
@@ -0,0 +1,4 @@
1
+ from .interface import *
2
+ from .jsonfile import *
3
+ from .yamlfile import *
4
+ from .autoloader import *
@@ -0,0 +1,93 @@
1
+ __all__ = [
2
+ 'autoload',
3
+ 'guess_loader_class',
4
+ 'raw_load',
5
+ 'render_load',
6
+ ]
7
+
8
+ import os
9
+
10
+ from allconf.structs import *
11
+ from .interface import *
12
+ from .jsonfile import *
13
+ from .yamlfile import *
14
+
15
+ _EXTENSION_LOADER_MAP = {
16
+ '.json': JsonFileConfigLoader,
17
+ '.yaml': YamlFileConfigLoader,
18
+ '.yml': YamlFileConfigLoader,
19
+ }
20
+
21
+
22
+ def guess_loader_class(file_name: str) -> Type[IAllConfLoader]:
23
+ """Returns the most probable loader class based of the given file's extension.
24
+ """
25
+ ext = os.path.splitext(file_name)[-1]
26
+ loader = _EXTENSION_LOADER_MAP.get(ext, None)
27
+ if not loader:
28
+ raise AllConfUnknownFileTypeError(f'Dont know how to autoload file extension {ext}', file_name=file_name)
29
+ return loader
30
+
31
+
32
+ def raw_load(file_name: str, skip_env_loading: bool = False, skip_fidelius: bool = False, skip_py_inject: bool = False, encoding: str = 'utf-8') -> Dict:
33
+ """Loads and parses the given config file and returns the "raw" results as a
34
+ simple python dictionary.
35
+
36
+ This is mostly intended for the testing and debugging of the configuration
37
+ files themselves if needed.
38
+
39
+ :param file_name: The file to load
40
+ :param skip_env_loading: Set to True to skip resolving environment variable tags
41
+ :param skip_fidelius: Set to True to skip resolving Fidelius tags
42
+ :param skip_py_inject: Set to True to skip injecting Python imported values
43
+ :param encoding: Encoding to use when reading the file (utf-8 by default)
44
+ :return: A dict with the results
45
+ """
46
+ loader = guess_loader_class(file_name)()
47
+ loader.load_file(file_name, no_env_load=skip_env_loading, no_fidelius=skip_fidelius,
48
+ no_py_inject=skip_py_inject, encoding=encoding)
49
+ return loader.data
50
+
51
+
52
+ def render_load(file_name: str, skip_env_loading: bool = True, skip_fidelius: bool = True, skip_py_inject: bool = True, encoding: str = 'utf-8') -> str:
53
+ """Loads and parses the given config file and returns the "render" results
54
+ as a str in the same format the original file used.
55
+
56
+ The main point of this method is to be able to load and parse an AllConf
57
+ configuration file, including all includes, extensions, internal references,
58
+ environment variables, Fidelius values etc. and render as a single
59
+ value/file of the same format.
60
+
61
+ As a use-case example, it was originally built in order to generate
62
+ Kubernetes YAML manifest files using AllConf' format to simplify the process
63
+ (i.e. includes, internal references, secret injection via Fidelius during
64
+ deployment and so on).
65
+
66
+ :param file_name: The file to load
67
+ :param skip_env_loading: Set to True to skip resolving environment variable
68
+ tags
69
+ :param skip_fidelius: Set to True to skip resolving Fidelius tags
70
+ :param skip_py_inject: Set to True to skip injecting Python imported values
71
+ :param encoding: Encoding to use when reading the file (utf-8 by default)
72
+ :return: A string representation of the configuration data loaded, in the
73
+ same format as the target file if possible
74
+ """
75
+ loader = guess_loader_class(file_name)()
76
+ loader.load_file(file_name, no_env_load=skip_env_loading, no_fidelius=skip_fidelius, no_py_inject=skip_py_inject, encoding=encoding)
77
+ return loader.rendered
78
+
79
+
80
+ def autoload(file_name: str, encoding: str = 'utf-8') -> BaseConfig:
81
+ """Loads and parses the given config file and returns as a `BaseConfig`
82
+ object.
83
+
84
+ :param file_name:
85
+ :type file_name:
86
+ :param encoding:
87
+ :type encoding:
88
+ :return:
89
+ :rtype:
90
+ """
91
+ loader = guess_loader_class(file_name)()
92
+ loader.load_file(file_name, encoding=encoding)
93
+ return BaseConfig(**raw_load(file_name))