summaryrefslogtreecommitdiffhomepage
path: root/libs/dynaconf/loaders/json_loader.py
diff options
context:
space:
mode:
Diffstat (limited to 'libs/dynaconf/loaders/json_loader.py')
-rw-r--r--libs/dynaconf/loaders/json_loader.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/libs/dynaconf/loaders/json_loader.py b/libs/dynaconf/loaders/json_loader.py
new file mode 100644
index 000000000..72c1e340e
--- /dev/null
+++ b/libs/dynaconf/loaders/json_loader.py
@@ -0,0 +1,80 @@
+from __future__ import annotations
+
+import io
+import json
+from pathlib import Path
+
+from dynaconf import default_settings
+from dynaconf.constants import JSON_EXTENSIONS
+from dynaconf.loaders.base import BaseLoader
+from dynaconf.utils import object_merge
+from dynaconf.utils.parse_conf import try_to_encode
+
+try: # pragma: no cover
+ import commentjson
+except ImportError: # pragma: no cover
+ commentjson = None
+
+
+def load(obj, env=None, silent=True, key=None, filename=None):
+ """
+ Reads and loads in to "obj" a single key or all keys from source file.
+
+ :param obj: the settings instance
+ :param env: settings current env default='development'
+ :param silent: if errors should raise
+ :param key: if defined load a single key, else load all in env
+ :param filename: Optional custom filename to load
+ :return: None
+ """
+ if (
+ obj.get("COMMENTJSON_ENABLED_FOR_DYNACONF") and commentjson
+ ): # pragma: no cover # noqa
+ file_reader = commentjson.load
+ string_reader = commentjson.loads
+ else:
+ file_reader = json.load
+ string_reader = json.loads
+
+ loader = BaseLoader(
+ obj=obj,
+ env=env,
+ identifier="json",
+ extensions=JSON_EXTENSIONS,
+ file_reader=file_reader,
+ string_reader=string_reader,
+ )
+ loader.load(
+ filename=filename,
+ key=key,
+ silent=silent,
+ )
+
+
+def write(settings_path, settings_data, merge=True):
+ """Write data to a settings file.
+
+ :param settings_path: the filepath
+ :param settings_data: a dictionary with data
+ :param merge: boolean if existing file should be merged with new data
+ """
+ settings_path = Path(settings_path)
+ if settings_path.exists() and merge: # pragma: no cover
+ with open(
+ str(settings_path), encoding=default_settings.ENCODING_FOR_DYNACONF
+ ) as open_file:
+ object_merge(json.load(open_file), settings_data)
+
+ with open(
+ str(settings_path),
+ "w",
+ encoding=default_settings.ENCODING_FOR_DYNACONF,
+ ) as open_file:
+ json.dump(settings_data, open_file, cls=DynaconfEncoder)
+
+
+class DynaconfEncoder(json.JSONEncoder):
+ """Transform Dynaconf custom types instances to json representation"""
+
+ def default(self, o):
+ return try_to_encode(o, callback=super().default)