dynaconf 3.2.6__tar.gz → 3.2.8__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.
- {dynaconf-3.2.6 → dynaconf-3.2.8}/CHANGELOG.md +35 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/PKG-INFO +43 -11
- dynaconf-3.2.8/dynaconf/VERSION +1 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/__init__.py +2 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/base.py +114 -49
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/cli.py +129 -50
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/default_settings.py +1 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/hooking.py +32 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/__init__.py +105 -42
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/env_loader.py +29 -13
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/ini_loader.py +17 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/json_loader.py +17 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/py_loader.py +19 -3
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/redis_loader.py +9 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/toml_loader.py +17 -3
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/vault_loader.py +4 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/yaml_loader.py +17 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/__init__.py +50 -7
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/inspect.py +150 -6
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/parse_conf.py +60 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/validator.py +25 -7
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_termui_impl.py +4 -4
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_unicodefun.py +1 -1
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/core.py +3 -3
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/exceptions.py +2 -2
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/formatting.py +3 -3
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/parser.py +1 -1
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/termui.py +1 -1
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/testing.py +1 -1
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/types.py +6 -6
- dynaconf-3.2.8/dynaconf/vendor/dotenv/py.typed +1 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/error.py +6 -7
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/events.py +6 -11
- dynaconf-3.2.8/dynaconf/vendor/ruamel/yaml/py.typed +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/scalarstring.py +2 -3
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/tokens.py +18 -19
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/PKG-INFO +43 -11
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/SOURCES.txt +27 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/entry_points.txt +0 -1
- dynaconf-3.2.8/tests/test_base.py +1633 -0
- dynaconf-3.2.8/tests/test_basic.py +7 -0
- dynaconf-3.2.8/tests/test_cli.py +892 -0
- dynaconf-3.2.8/tests/test_compat.py +56 -0
- dynaconf-3.2.8/tests/test_django.py +44 -0
- dynaconf-3.2.8/tests/test_dynabox.py +103 -0
- dynaconf-3.2.8/tests/test_endtoend.py +67 -0
- dynaconf-3.2.8/tests/test_env_loader.py +523 -0
- dynaconf-3.2.8/tests/test_envvar_prefix.py +46 -0
- dynaconf-3.2.8/tests/test_feature_flag.py +34 -0
- dynaconf-3.2.8/tests/test_flask.py +165 -0
- dynaconf-3.2.8/tests/test_hooking.py +268 -0
- dynaconf-3.2.8/tests/test_ini_loader.py +208 -0
- dynaconf-3.2.8/tests/test_inspect.py +1009 -0
- dynaconf-3.2.8/tests/test_json_loader.py +230 -0
- dynaconf-3.2.8/tests/test_nested_loading.py +385 -0
- dynaconf-3.2.8/tests/test_py_loader.py +275 -0
- dynaconf-3.2.8/tests/test_redis.py +124 -0
- dynaconf-3.2.8/tests/test_settings_loader.py +167 -0
- dynaconf-3.2.8/tests/test_toml_loader.py +268 -0
- dynaconf-3.2.8/tests/test_utils.py +556 -0
- dynaconf-3.2.8/tests/test_validators.py +887 -0
- dynaconf-3.2.8/tests/test_validators_conditions.py +64 -0
- dynaconf-3.2.8/tests/test_vault.py +131 -0
- dynaconf-3.2.8/tests/test_yaml_loader.py +580 -0
- dynaconf-3.2.6/dynaconf/VERSION +0 -1
- {dynaconf-3.2.6 → dynaconf-3.2.8}/3.x-release-notes.md +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/CONTRIBUTING.md +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/CONTRIBUTORS.md +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/LICENSE +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/MANIFEST.in +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/README.md +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/constants.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/contrib/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/contrib/django_dynaconf_v2.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/contrib/flask_dynaconf.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/loaders/base.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/strategies/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/strategies/filtering.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/test_settings.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/boxing.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/files.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/utils/functional.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/validator_conditions.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/box.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/box_list.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/config_box.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/converters.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/exceptions.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/from_file.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/box/shorthand_box.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_bashcomplete.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_compat.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_textwrap.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/_winconsole.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/decorators.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/globals.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/click/utils.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/cli.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/compat.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/ipython.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/main.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/parser.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/dotenv/version.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/anchor.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/comments.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/compat.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/composer.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/configobjwalker.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/constructor.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/cyaml.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/dumper.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/emitter.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/loader.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/main.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/nodes.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/parser.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/reader.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/representer.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/resolver.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/scalarbool.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/scalarfloat.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/scalarint.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/scanner.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/serializer.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/setup.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/timestamp.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/ruamel/yaml/util.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/toml/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/toml/decoder.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/toml/encoder.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/toml/ordered.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/toml/tz.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/tomllib/__init__.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/tomllib/_parser.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/tomllib/_re.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/tomllib/_types.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf/vendor/tomllib/_writer.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/dependency_links.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/not-zip-safe +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/requires.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/dynaconf.egg-info/top_level.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/setup.cfg +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/setup.py +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/box-LICENSE.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/click-LICENSE.rst +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/licenses.sh +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/python-dotenv-LICENSE.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/ruamel.yaml-LICENSE.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/toml-LICENSE.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/tomli-LICENSE.txt +0 -0
- {dynaconf-3.2.6 → dynaconf-3.2.8}/vendor_licenses/vendor_versions.txt +0 -0
|
@@ -2,6 +2,41 @@ Changelog
|
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
4
|
<!-- insertion marker -->
|
|
5
|
+
## [3.2.8](https://github.com/dynaconf/dynaconf/releases/tag/3.2.8) - 2025-02-16
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- Parse data type on merge with comma separated value. *By Bruno Rocha*.
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- Add CLI command `debug-info` (#1251). *By Bruno Rocha*.
|
|
14
|
+
- Add support for decorated hooks on settings files (#1246). *By Bruno Rocha*.
|
|
15
|
+
- Add VAULT_TOKEN_RENEW_FOR_DYNACONF config/code (#1094) (#1242). *By Pedro Brochado*.
|
|
16
|
+
- populate_obj takes convert_to_dict (#1237). *By Bruno Rocha*.
|
|
17
|
+
- add VAULT_TOKEN_RENEW. *By Bruno Rocha*.
|
|
18
|
+
|
|
19
|
+
## [3.2.7](https://github.com/dynaconf/dynaconf/releases/tag/3.2.7) - 2025-01-21
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
- lazy validator's default value would evaluate early (#1198). *By Pedro Brochado*.
|
|
24
|
+
- Fixed an error that would raise when using get_history() with lazy values (#1184) (#1185). *By Pedro Brochado*.
|
|
25
|
+
- Fixed Redis loader when ENV prefix is `None`.
|
|
26
|
+
- Populate object method now takes `internal` attribute to filter out internal variables.
|
|
27
|
+
- On CLI `json.dumps` defaults to `repr` for types that cannot be serialized.
|
|
28
|
+
- Added an identifier to validator calls of `set` method
|
|
29
|
+
- Fix django app discovery using DJANGO_SETTINGS_MODULE variable
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
- Added `@insert` token to call `list.insert`
|
|
34
|
+
- Allow env loader to load from multiple prefixes
|
|
35
|
+
- Allow multiple composable current environments
|
|
36
|
+
- Track more data on `load_file` method
|
|
37
|
+
- Added `--json` to dynaconf list CLI
|
|
38
|
+
|
|
39
|
+
|
|
5
40
|
## [3.2.6](https://github.com/dynaconf/dynaconf/releases/tag/3.2.6) - 2024-07-19
|
|
6
41
|
|
|
7
42
|
## [3.2.5](https://github.com/pedro-psb/dynaconf/releases/tag/3.2.5) - 2024-03-18
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: dynaconf
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.8
|
|
4
4
|
Summary: The dynamic configurator for your Python Project
|
|
5
5
|
Home-page: https://github.com/dynaconf/dynaconf
|
|
6
6
|
Author: Bruno Rocha
|
|
@@ -26,14 +26,6 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
26
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
27
|
Requires-Python: >=3.8
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
|
-
Provides-Extra: redis
|
|
30
|
-
Provides-Extra: vault
|
|
31
|
-
Provides-Extra: yaml
|
|
32
|
-
Provides-Extra: toml
|
|
33
|
-
Provides-Extra: ini
|
|
34
|
-
Provides-Extra: configobj
|
|
35
|
-
Provides-Extra: all
|
|
36
|
-
Provides-Extra: test
|
|
37
29
|
License-File: LICENSE
|
|
38
30
|
License-File: vendor_licenses/box-LICENSE.txt
|
|
39
31
|
License-File: vendor_licenses/click-LICENSE.rst
|
|
@@ -43,6 +35,47 @@ License-File: vendor_licenses/ruamel.yaml-LICENSE.txt
|
|
|
43
35
|
License-File: vendor_licenses/toml-LICENSE.txt
|
|
44
36
|
License-File: vendor_licenses/tomli-LICENSE.txt
|
|
45
37
|
License-File: vendor_licenses/vendor_versions.txt
|
|
38
|
+
Provides-Extra: redis
|
|
39
|
+
Requires-Dist: redis; extra == "redis"
|
|
40
|
+
Provides-Extra: vault
|
|
41
|
+
Requires-Dist: hvac; extra == "vault"
|
|
42
|
+
Provides-Extra: yaml
|
|
43
|
+
Requires-Dist: ruamel.yaml; extra == "yaml"
|
|
44
|
+
Provides-Extra: toml
|
|
45
|
+
Requires-Dist: toml; extra == "toml"
|
|
46
|
+
Provides-Extra: ini
|
|
47
|
+
Requires-Dist: configobj; extra == "ini"
|
|
48
|
+
Provides-Extra: configobj
|
|
49
|
+
Requires-Dist: configobj; extra == "configobj"
|
|
50
|
+
Provides-Extra: all
|
|
51
|
+
Requires-Dist: redis; extra == "all"
|
|
52
|
+
Requires-Dist: ruamel.yaml; extra == "all"
|
|
53
|
+
Requires-Dist: configobj; extra == "all"
|
|
54
|
+
Requires-Dist: hvac; extra == "all"
|
|
55
|
+
Provides-Extra: test
|
|
56
|
+
Requires-Dist: pytest; extra == "test"
|
|
57
|
+
Requires-Dist: pytest-cov; extra == "test"
|
|
58
|
+
Requires-Dist: pytest-xdist; extra == "test"
|
|
59
|
+
Requires-Dist: pytest-mock; extra == "test"
|
|
60
|
+
Requires-Dist: radon; extra == "test"
|
|
61
|
+
Requires-Dist: flask>=0.12; extra == "test"
|
|
62
|
+
Requires-Dist: django; extra == "test"
|
|
63
|
+
Requires-Dist: python-dotenv; extra == "test"
|
|
64
|
+
Requires-Dist: toml; extra == "test"
|
|
65
|
+
Requires-Dist: redis; extra == "test"
|
|
66
|
+
Requires-Dist: hvac>=1.1.0; extra == "test"
|
|
67
|
+
Requires-Dist: configobj; extra == "test"
|
|
68
|
+
Dynamic: author
|
|
69
|
+
Dynamic: author-email
|
|
70
|
+
Dynamic: classifier
|
|
71
|
+
Dynamic: description
|
|
72
|
+
Dynamic: description-content-type
|
|
73
|
+
Dynamic: home-page
|
|
74
|
+
Dynamic: license
|
|
75
|
+
Dynamic: platform
|
|
76
|
+
Dynamic: provides-extra
|
|
77
|
+
Dynamic: requires-python
|
|
78
|
+
Dynamic: summary
|
|
46
79
|
|
|
47
80
|
<!-- [](http://dynaconf.com) -->
|
|
48
81
|
|
|
@@ -180,4 +213,3 @@ Main discussions happens on [Discussions Tab](https://github.com/dynaconf/dynaco
|
|
|
180
213
|
If you are looking for something similar to Dynaconf to use in your Rust projects: https://github.com/rubik/hydroconf
|
|
181
214
|
|
|
182
215
|
And a special thanks to [Caneco](https://twitter.com/caneco) for the logo.
|
|
183
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.2.8
|
|
@@ -4,6 +4,7 @@ from dynaconf.base import LazySettings
|
|
|
4
4
|
from dynaconf.constants import DEFAULT_SETTINGS_FILES
|
|
5
5
|
from dynaconf.contrib import DjangoDynaconf
|
|
6
6
|
from dynaconf.contrib import FlaskDynaconf
|
|
7
|
+
from dynaconf.hooking import post_hook
|
|
7
8
|
from dynaconf.utils.inspect import get_history
|
|
8
9
|
from dynaconf.utils.inspect import inspect_settings
|
|
9
10
|
from dynaconf.utils.parse_conf import add_converter
|
|
@@ -39,4 +40,5 @@ __all__ = [
|
|
|
39
40
|
"get_history",
|
|
40
41
|
"DynaconfFormatError",
|
|
41
42
|
"DynaconfParseError",
|
|
43
|
+
"post_hook",
|
|
42
44
|
]
|
|
@@ -968,6 +968,15 @@ class Settings:
|
|
|
968
968
|
self.store.get(key, None) if not isinstance(parsed, Lazy) else None
|
|
969
969
|
)
|
|
970
970
|
|
|
971
|
+
if getattr(parsed, "_dynaconf_insert", False):
|
|
972
|
+
# `@insert` calls insert in a list by index
|
|
973
|
+
if existing and isinstance(existing, list):
|
|
974
|
+
source_metadata = source_metadata._replace(merged=True)
|
|
975
|
+
existing.insert(parsed.index, parsed.unwrap())
|
|
976
|
+
parsed = existing
|
|
977
|
+
else:
|
|
978
|
+
parsed = [parsed.unwrap()]
|
|
979
|
+
|
|
971
980
|
if getattr(parsed, "_dynaconf_del", None):
|
|
972
981
|
self.unset(key, force=True) # `@del` in a first level var.
|
|
973
982
|
return
|
|
@@ -1152,6 +1161,10 @@ class Settings:
|
|
|
1152
1161
|
"""Clean end Execute all loaders"""
|
|
1153
1162
|
self.clean()
|
|
1154
1163
|
self._loaded_hooks.clear()
|
|
1164
|
+
for hook in self._post_hooks:
|
|
1165
|
+
with suppress(AttributeError, TypeError):
|
|
1166
|
+
hook._called = False
|
|
1167
|
+
|
|
1155
1168
|
self.execute_loaders(env, silent)
|
|
1156
1169
|
|
|
1157
1170
|
def execute_loaders(
|
|
@@ -1208,7 +1221,13 @@ class Settings:
|
|
|
1208
1221
|
last_loader.load(self, env, silent, key)
|
|
1209
1222
|
|
|
1210
1223
|
def load_file(
|
|
1211
|
-
self,
|
|
1224
|
+
self,
|
|
1225
|
+
path=None,
|
|
1226
|
+
env=None,
|
|
1227
|
+
silent=True,
|
|
1228
|
+
key=None,
|
|
1229
|
+
validate=empty,
|
|
1230
|
+
run_hooks=True,
|
|
1212
1231
|
):
|
|
1213
1232
|
"""Programmatically load files from ``path``.
|
|
1214
1233
|
|
|
@@ -1217,63 +1236,95 @@ class Settings:
|
|
|
1217
1236
|
- Directory of the last loaded file
|
|
1218
1237
|
- CWD
|
|
1219
1238
|
|
|
1220
|
-
:param path: A single filename or a file list
|
|
1239
|
+
:param path: A single filename, a glob or a file list
|
|
1221
1240
|
:param env: Which env to load from file (default current_env)
|
|
1222
1241
|
:param silent: Should raise errors?
|
|
1223
1242
|
:param key: Load a single key?
|
|
1224
1243
|
:param validate: Should trigger validation?
|
|
1244
|
+
:param run_hooks: Should run collected hooks?
|
|
1225
1245
|
"""
|
|
1246
|
+
files = ensure_a_list(path)
|
|
1247
|
+
if not files: # a glob pattern may return empty
|
|
1248
|
+
return
|
|
1249
|
+
|
|
1226
1250
|
if validate is empty:
|
|
1227
1251
|
validate = self.get("VALIDATE_ON_UPDATE_FOR_DYNACONF")
|
|
1228
1252
|
|
|
1229
1253
|
env = (env or self.current_env).upper()
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1254
|
+
|
|
1255
|
+
# Using inspect take the filename and line number of the caller
|
|
1256
|
+
# to be used in the source_metadata
|
|
1257
|
+
frame = inspect.currentframe()
|
|
1258
|
+
caller = inspect.getouterframes(frame)[1]
|
|
1259
|
+
|
|
1260
|
+
already_loaded = set()
|
|
1261
|
+
for _filename in files:
|
|
1262
|
+
# load_file() will handle validation later
|
|
1263
|
+
with suppress(ValidationError):
|
|
1264
|
+
source_metadata = SourceMetadata(
|
|
1265
|
+
loader=f"load_file@{caller.filename}:{caller.lineno}",
|
|
1266
|
+
identifier=_filename,
|
|
1267
|
+
env=env,
|
|
1268
|
+
)
|
|
1269
|
+
if py_loader.try_to_load_from_py_module_name(
|
|
1270
|
+
obj=self,
|
|
1271
|
+
name=_filename,
|
|
1272
|
+
silent=True,
|
|
1273
|
+
identifier=source_metadata,
|
|
1274
|
+
):
|
|
1275
|
+
# if it was possible to load from module name
|
|
1276
|
+
# continue the loop.
|
|
1277
|
+
continue
|
|
1278
|
+
|
|
1279
|
+
root_dir = str(self._root_path or os.getcwd())
|
|
1280
|
+
|
|
1281
|
+
# Issue #494
|
|
1282
|
+
if (
|
|
1283
|
+
isinstance(_filename, Path)
|
|
1284
|
+
and str(_filename.parent) in root_dir
|
|
1285
|
+
): # pragma: no cover
|
|
1286
|
+
filepath = str(_filename)
|
|
1287
|
+
else:
|
|
1288
|
+
filepath = os.path.join(root_dir, str(_filename))
|
|
1289
|
+
|
|
1290
|
+
paths = [p for p in sorted(glob(filepath)) if ".local." not in p]
|
|
1291
|
+
local_paths = [p for p in sorted(glob(filepath)) if ".local." in p]
|
|
1292
|
+
|
|
1293
|
+
# Handle possible *.globs sorted alphanumeric
|
|
1294
|
+
for path in paths + local_paths:
|
|
1295
|
+
if path in already_loaded: # pragma: no cover
|
|
1296
|
+
continue
|
|
1297
|
+
|
|
1234
1298
|
# load_file() will handle validation later
|
|
1235
1299
|
with suppress(ValidationError):
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
continue
|
|
1265
|
-
|
|
1266
|
-
# load_file() will handle validation later
|
|
1267
|
-
with suppress(ValidationError):
|
|
1268
|
-
settings_loader(
|
|
1269
|
-
obj=self,
|
|
1270
|
-
env=env,
|
|
1271
|
-
silent=silent,
|
|
1272
|
-
key=key,
|
|
1273
|
-
filename=path,
|
|
1274
|
-
validate=validate,
|
|
1275
|
-
)
|
|
1276
|
-
already_loaded.add(path)
|
|
1300
|
+
source_metadata = SourceMetadata(
|
|
1301
|
+
loader=f"load_file@{caller.filename}:{caller.lineno}",
|
|
1302
|
+
identifier=path,
|
|
1303
|
+
env=env,
|
|
1304
|
+
)
|
|
1305
|
+
settings_loader(
|
|
1306
|
+
obj=self,
|
|
1307
|
+
env=env,
|
|
1308
|
+
silent=silent,
|
|
1309
|
+
key=key,
|
|
1310
|
+
filename=path,
|
|
1311
|
+
validate=validate,
|
|
1312
|
+
identifier=source_metadata,
|
|
1313
|
+
)
|
|
1314
|
+
already_loaded.add(path)
|
|
1315
|
+
|
|
1316
|
+
if run_hooks:
|
|
1317
|
+
# this will call any collected hook that was not called yet
|
|
1318
|
+
execute_instance_hooks(
|
|
1319
|
+
self,
|
|
1320
|
+
"post",
|
|
1321
|
+
[
|
|
1322
|
+
_hook
|
|
1323
|
+
for _hook in self._post_hooks
|
|
1324
|
+
if getattr(_hook, "_dynaconf_hook", False) is True
|
|
1325
|
+
and not getattr(_hook, "_called", False)
|
|
1326
|
+
],
|
|
1327
|
+
)
|
|
1277
1328
|
|
|
1278
1329
|
# handle param `validate`
|
|
1279
1330
|
if validate is True:
|
|
@@ -1357,19 +1408,33 @@ class Settings:
|
|
|
1357
1408
|
value = self.get_fresh(key)
|
|
1358
1409
|
return value is True or value in true_values
|
|
1359
1410
|
|
|
1360
|
-
def populate_obj(
|
|
1411
|
+
def populate_obj(
|
|
1412
|
+
self,
|
|
1413
|
+
obj,
|
|
1414
|
+
keys=None,
|
|
1415
|
+
ignore=None,
|
|
1416
|
+
internal=False,
|
|
1417
|
+
convert_to_dict=False,
|
|
1418
|
+
):
|
|
1361
1419
|
"""Given the `obj` populate it using self.store items.
|
|
1362
1420
|
|
|
1363
1421
|
:param obj: An object to be populated, a class instance.
|
|
1364
1422
|
:param keys: A list of keys to be included.
|
|
1365
1423
|
:param ignore: A list of keys to be excluded.
|
|
1424
|
+
:param internal: Include internal keys.
|
|
1425
|
+
:param convert_to_dict: Convert the settings to a pure dict (no Box)
|
|
1426
|
+
before populating.
|
|
1366
1427
|
"""
|
|
1428
|
+
data = self.to_dict(internal=internal) if convert_to_dict else self
|
|
1367
1429
|
keys = keys or self.keys()
|
|
1368
1430
|
for key in keys:
|
|
1369
1431
|
key = upperfy(key)
|
|
1432
|
+
if not internal:
|
|
1433
|
+
if key in UPPER_DEFAULT_SETTINGS:
|
|
1434
|
+
continue
|
|
1370
1435
|
if ignore and key in ignore:
|
|
1371
1436
|
continue
|
|
1372
|
-
value =
|
|
1437
|
+
value = data.get(key, empty)
|
|
1373
1438
|
if value is not empty:
|
|
1374
1439
|
setattr(obj, key, value)
|
|
1375
1440
|
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import importlib
|
|
4
|
+
import inspect as python_inspect
|
|
4
5
|
import json
|
|
5
6
|
import os
|
|
6
7
|
import pprint
|
|
7
8
|
import sys
|
|
8
9
|
import warnings
|
|
9
10
|
import webbrowser
|
|
11
|
+
from contextlib import redirect_stdout
|
|
10
12
|
from contextlib import suppress
|
|
11
13
|
from pathlib import Path
|
|
12
|
-
from typing import TYPE_CHECKING
|
|
13
14
|
|
|
14
15
|
from dynaconf import constants
|
|
15
16
|
from dynaconf import default_settings
|
|
16
17
|
from dynaconf import LazySettings
|
|
17
18
|
from dynaconf import loaders
|
|
18
19
|
from dynaconf import settings as legacy_settings
|
|
20
|
+
from dynaconf.base import Settings
|
|
19
21
|
from dynaconf.loaders.py_loader import get_module
|
|
22
|
+
from dynaconf.utils import prepare_json
|
|
20
23
|
from dynaconf.utils import upperfy
|
|
21
24
|
from dynaconf.utils.files import read_file
|
|
22
25
|
from dynaconf.utils.functional import empty
|
|
@@ -25,6 +28,7 @@ from dynaconf.utils.inspect import EnvNotFoundError
|
|
|
25
28
|
from dynaconf.utils.inspect import inspect_settings
|
|
26
29
|
from dynaconf.utils.inspect import KeyNotFoundError
|
|
27
30
|
from dynaconf.utils.inspect import OutputFormatError
|
|
31
|
+
from dynaconf.utils.inspect import print_debug_info
|
|
28
32
|
from dynaconf.utils.parse_conf import parse_conf_data
|
|
29
33
|
from dynaconf.utils.parse_conf import unparse_conf_data
|
|
30
34
|
from dynaconf.validator import ValidationError
|
|
@@ -33,9 +37,6 @@ from dynaconf.vendor import click
|
|
|
33
37
|
from dynaconf.vendor import toml
|
|
34
38
|
from dynaconf.vendor import tomllib
|
|
35
39
|
|
|
36
|
-
if TYPE_CHECKING: # pragma: no cover
|
|
37
|
-
from dynaconf.base import Settings # noqa: F401
|
|
38
|
-
|
|
39
40
|
os.environ["PYTHONIOENCODING"] = "utf-8"
|
|
40
41
|
|
|
41
42
|
CWD = None
|
|
@@ -54,7 +55,14 @@ def set_settings(ctx, instance=None):
|
|
|
54
55
|
|
|
55
56
|
settings = None
|
|
56
57
|
|
|
57
|
-
_echo_enabled = ctx.invoked_subcommand not in [
|
|
58
|
+
_echo_enabled = ctx.invoked_subcommand not in [
|
|
59
|
+
"get",
|
|
60
|
+
"inspect",
|
|
61
|
+
"debug-info",
|
|
62
|
+
None,
|
|
63
|
+
]
|
|
64
|
+
if "--json" in click.get_os_args():
|
|
65
|
+
_echo_enabled = False
|
|
58
66
|
|
|
59
67
|
if instance is not None:
|
|
60
68
|
if ctx.invoked_subcommand in ["init"]:
|
|
@@ -79,19 +87,16 @@ def set_settings(ctx, instance=None):
|
|
|
79
87
|
)
|
|
80
88
|
elif "DJANGO_SETTINGS_MODULE" in os.environ: # pragma: no cover
|
|
81
89
|
sys.path.insert(0, os.path.abspath(os.getcwd()))
|
|
82
|
-
|
|
83
|
-
# Django extension v2
|
|
84
|
-
from django.conf import settings # noqa
|
|
85
|
-
import dynaconf # noqa: F401
|
|
86
|
-
import django
|
|
87
|
-
|
|
88
|
-
# see https://docs.djangoproject.com/en/4.2/ref/applications/
|
|
89
|
-
# at #troubleshooting
|
|
90
|
-
django.setup()
|
|
90
|
+
import django # noqa
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
django.setup() # ensure django is setup to avoid AppRegistryNotReady
|
|
93
|
+
settings_module = import__django_settings(
|
|
94
|
+
os.environ["DJANGO_SETTINGS_MODULE"]
|
|
95
|
+
)
|
|
96
|
+
for member in python_inspect.getmembers(settings_module):
|
|
97
|
+
if isinstance(member[1], (LazySettings, Settings)):
|
|
98
|
+
settings = member[1]
|
|
99
|
+
break
|
|
95
100
|
|
|
96
101
|
if settings is not None and _echo_enabled:
|
|
97
102
|
click.echo(
|
|
@@ -117,6 +122,18 @@ def set_settings(ctx, instance=None):
|
|
|
117
122
|
settings = LazySettings()
|
|
118
123
|
|
|
119
124
|
|
|
125
|
+
def import__django_settings(django_settings_module):
|
|
126
|
+
"""Import the Django settings module from the string importable path."""
|
|
127
|
+
try:
|
|
128
|
+
with redirect_stdout(None):
|
|
129
|
+
module = importlib.import_module(django_settings_module)
|
|
130
|
+
except ImportError as e:
|
|
131
|
+
raise click.UsageError(e)
|
|
132
|
+
except FileNotFoundError:
|
|
133
|
+
return
|
|
134
|
+
return module
|
|
135
|
+
|
|
136
|
+
|
|
120
137
|
def import_settings(dotted_path):
|
|
121
138
|
"""Import settings instance from python dotted path.
|
|
122
139
|
|
|
@@ -130,8 +147,10 @@ def import_settings(dotted_path):
|
|
|
130
147
|
raise click.UsageError(
|
|
131
148
|
f"invalid path to settings instance: {dotted_path}"
|
|
132
149
|
)
|
|
150
|
+
|
|
133
151
|
try:
|
|
134
|
-
|
|
152
|
+
with redirect_stdout(None):
|
|
153
|
+
module = importlib.import_module(module)
|
|
135
154
|
except ImportError as e:
|
|
136
155
|
raise click.UsageError(e)
|
|
137
156
|
except FileNotFoundError:
|
|
@@ -485,7 +504,7 @@ def get(key, default, env, unparse):
|
|
|
485
504
|
result = unparse_conf_data(result)
|
|
486
505
|
|
|
487
506
|
if isinstance(result, (dict, list, tuple)):
|
|
488
|
-
result = json.dumps(result, sort_keys=True)
|
|
507
|
+
result = json.dumps(prepare_json(result), sort_keys=True, default=repr)
|
|
489
508
|
|
|
490
509
|
click.echo(result, nl=False)
|
|
491
510
|
|
|
@@ -530,7 +549,24 @@ def get(key, default, env, unparse):
|
|
|
530
549
|
default=False,
|
|
531
550
|
help="Output file is flat (do not include [env] name)",
|
|
532
551
|
)
|
|
533
|
-
|
|
552
|
+
@click.option(
|
|
553
|
+
"--json",
|
|
554
|
+
"_json",
|
|
555
|
+
"-j",
|
|
556
|
+
is_flag=True,
|
|
557
|
+
default=False,
|
|
558
|
+
help="Prints out data serialized as JSON",
|
|
559
|
+
)
|
|
560
|
+
def _list(
|
|
561
|
+
env,
|
|
562
|
+
key,
|
|
563
|
+
more,
|
|
564
|
+
loader,
|
|
565
|
+
_all=False,
|
|
566
|
+
output=None,
|
|
567
|
+
flat=False,
|
|
568
|
+
_json=False,
|
|
569
|
+
):
|
|
534
570
|
"""
|
|
535
571
|
Lists user defined settings or all (including internal configs).
|
|
536
572
|
|
|
@@ -552,14 +588,15 @@ def _list(env, key, more, loader, _all=False, output=None, flat=False):
|
|
|
552
588
|
if cur_env == "main":
|
|
553
589
|
flat = True
|
|
554
590
|
|
|
555
|
-
|
|
556
|
-
click.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
591
|
+
if not _json:
|
|
592
|
+
click.echo(
|
|
593
|
+
click.style(
|
|
594
|
+
f"Working in {cur_env} environment ",
|
|
595
|
+
bold=True,
|
|
596
|
+
bg="bright_blue",
|
|
597
|
+
fg="bright_white",
|
|
598
|
+
)
|
|
561
599
|
)
|
|
562
|
-
)
|
|
563
600
|
|
|
564
601
|
if not loader:
|
|
565
602
|
data = settings.as_dict(env=env, internal=_all)
|
|
@@ -585,14 +622,20 @@ def _list(env, key, more, loader, _all=False, output=None, flat=False):
|
|
|
585
622
|
return f"{key}{data_type} {value}"
|
|
586
623
|
|
|
587
624
|
if not key:
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
625
|
+
if not _json:
|
|
626
|
+
datalines = "\n".join(
|
|
627
|
+
format_setting(k, v)
|
|
628
|
+
for k, v in data.items()
|
|
629
|
+
if k not in data.get("RENAMED_VARS", [])
|
|
630
|
+
)
|
|
631
|
+
(click.echo_via_pager if more else click.echo)(datalines)
|
|
594
632
|
if output:
|
|
595
|
-
loaders.write(output, data, env=not flat and cur_env)
|
|
633
|
+
loaders.write(output, prepare_json(data), env=not flat and cur_env)
|
|
634
|
+
if _json:
|
|
635
|
+
json_data = json.dumps(
|
|
636
|
+
prepare_json(data), sort_keys=True, default=repr
|
|
637
|
+
)
|
|
638
|
+
click.echo(json_data, nl=False)
|
|
596
639
|
else:
|
|
597
640
|
key = upperfy(key)
|
|
598
641
|
|
|
@@ -605,9 +648,16 @@ def _list(env, key, more, loader, _all=False, output=None, flat=False):
|
|
|
605
648
|
click.secho("Key not found", bg="red", fg="white", err=True)
|
|
606
649
|
return
|
|
607
650
|
|
|
608
|
-
|
|
651
|
+
if not _json:
|
|
652
|
+
click.echo(format_setting(key, value))
|
|
609
653
|
if output:
|
|
610
|
-
loaders.write(
|
|
654
|
+
loaders.write(
|
|
655
|
+
output, prepare_json({key: value}), env=not flat and cur_env
|
|
656
|
+
)
|
|
657
|
+
if _json:
|
|
658
|
+
click.echo(
|
|
659
|
+
json.dumps(prepare_json({key: value}), default=repr), nl=True
|
|
660
|
+
)
|
|
611
661
|
|
|
612
662
|
if env:
|
|
613
663
|
settings.setenv()
|
|
@@ -813,7 +863,10 @@ INSPECT_FORMATS = list(builtin_dumpers.keys())
|
|
|
813
863
|
@main.command()
|
|
814
864
|
@click.option("--key", "-k", help="Filters result by key.")
|
|
815
865
|
@click.option(
|
|
816
|
-
"--env",
|
|
866
|
+
"--env",
|
|
867
|
+
"-e",
|
|
868
|
+
help="Filters result by environment on --report-mode=inspect.",
|
|
869
|
+
default=None,
|
|
817
870
|
)
|
|
818
871
|
@click.option(
|
|
819
872
|
"--format",
|
|
@@ -826,7 +879,7 @@ INSPECT_FORMATS = list(builtin_dumpers.keys())
|
|
|
826
879
|
"--old-first",
|
|
827
880
|
"new_first",
|
|
828
881
|
"-s",
|
|
829
|
-
help="Invert history sorting to 'old-first'",
|
|
882
|
+
help="Invert history sorting to 'old-first' on --report-mode=inspect.",
|
|
830
883
|
default=True,
|
|
831
884
|
is_flag=True,
|
|
832
885
|
)
|
|
@@ -836,7 +889,7 @@ INSPECT_FORMATS = list(builtin_dumpers.keys())
|
|
|
836
889
|
"-n",
|
|
837
890
|
default=None,
|
|
838
891
|
type=int,
|
|
839
|
-
help="Limits how many history entries are shown.",
|
|
892
|
+
help="Limits how many history entries are shown on --report-mode=inspect.",
|
|
840
893
|
)
|
|
841
894
|
@click.option(
|
|
842
895
|
"--all",
|
|
@@ -846,28 +899,54 @@ INSPECT_FORMATS = list(builtin_dumpers.keys())
|
|
|
846
899
|
is_flag=True,
|
|
847
900
|
help="Show dynaconf internal settings?",
|
|
848
901
|
)
|
|
902
|
+
@click.option(
|
|
903
|
+
"--report-mode",
|
|
904
|
+
"report_mode",
|
|
905
|
+
"-m",
|
|
906
|
+
default="inspect",
|
|
907
|
+
type=click.Choice(["inspect", "debug"]),
|
|
908
|
+
)
|
|
909
|
+
@click.option(
|
|
910
|
+
"-v",
|
|
911
|
+
"--verbose",
|
|
912
|
+
count=True,
|
|
913
|
+
help="Increase verbosity of the output on --report-mode=debug.",
|
|
914
|
+
)
|
|
849
915
|
def inspect(
|
|
850
|
-
key, env, format, new_first, history_limit, _all
|
|
916
|
+
key, env, format, new_first, history_limit, _all, report_mode, verbose
|
|
851
917
|
): # pragma: no cover
|
|
852
918
|
"""
|
|
853
919
|
Inspect the loading history of the given settings instance.
|
|
854
920
|
|
|
855
921
|
Filters by key and environment, otherwise shows all.
|
|
856
922
|
"""
|
|
857
|
-
|
|
858
|
-
|
|
923
|
+
|
|
924
|
+
if report_mode == "debug":
|
|
925
|
+
print_debug_info(
|
|
859
926
|
settings,
|
|
860
|
-
key=key,
|
|
861
|
-
env=env or None,
|
|
862
927
|
dumper=format,
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
history_limit=history_limit,
|
|
866
|
-
print_report=True,
|
|
928
|
+
verbosity=verbose,
|
|
929
|
+
key=key,
|
|
867
930
|
)
|
|
868
931
|
click.echo()
|
|
869
|
-
|
|
870
|
-
|
|
932
|
+
elif report_mode == "inspect":
|
|
933
|
+
try:
|
|
934
|
+
inspect_settings(
|
|
935
|
+
settings,
|
|
936
|
+
key=key,
|
|
937
|
+
env=env or None,
|
|
938
|
+
dumper=format,
|
|
939
|
+
new_first=new_first,
|
|
940
|
+
include_internal=_all,
|
|
941
|
+
history_limit=history_limit,
|
|
942
|
+
print_report=True,
|
|
943
|
+
)
|
|
944
|
+
click.echo()
|
|
945
|
+
except (KeyNotFoundError, EnvNotFoundError, OutputFormatError) as err:
|
|
946
|
+
click.echo(err)
|
|
947
|
+
sys.exit(1)
|
|
948
|
+
else:
|
|
949
|
+
click.echo("Invalid report mode")
|
|
871
950
|
sys.exit(1)
|
|
872
951
|
|
|
873
952
|
|
|
@@ -191,6 +191,7 @@ VAULT_ROLE_ID_FOR_DYNACONF = get("VAULT_ROLE_ID_FOR_DYNACONF", None)
|
|
|
191
191
|
VAULT_SECRET_ID_FOR_DYNACONF = get("VAULT_SECRET_ID_FOR_DYNACONF", None)
|
|
192
192
|
VAULT_USERNAME_FOR_DYNACONF = get("VAULT_USERNAME_FOR_DYNACONF", None)
|
|
193
193
|
VAULT_PASSWORD_FOR_DYNACONF = get("VAULT_PASSWORD_FOR_DYNACONF", None)
|
|
194
|
+
VAULT_TOKEN_RENEW_FOR_DYNACONF = get("VAULT_TOKEN_RENEW_FOR_DYNACONF", False)
|
|
194
195
|
|
|
195
196
|
# Only core loaders defined on this list will be invoked
|
|
196
197
|
core_loaders = ["YAML", "TOML", "INI", "JSON", "PY"]
|