Coverage for pydaconf/utils/file.py: 71.68%
77 statements
« prev ^ index » next coverage.py v7.6.11, created at 2025-02-16 17:46 +0000
« prev ^ index » next coverage.py v7.6.11, created at 2025-02-16 17:46 +0000
1import os
2import sys
4from pydaconf.utils.exceptions import UnknownFormat
7def guess_content_format(content: str) -> str | None:
8 """Guess file format based on the first line. This is much faster for big config files than using the parsers."""
10 first_line = next(iter(content.splitlines()), None)
11 if first_line is None: 11 ↛ 12line 11 didn't jump to line 12 because the condition on line 11 was never true
12 raise UnknownFormat("Config file first line is empty. Unable to identify the format")
14 if first_line.startswith("{") or (first_line.startswith("[") and "]" in first_line and "=" not in first_line):
15 return 'json'
17 elif ":" in first_line and not first_line.startswith("["):
18 return 'yaml'
20 elif first_line.startswith("[") and "=" not in first_line: 20 ↛ 21line 20 didn't jump to line 21 because the condition on line 20 was never true
21 return 'toml'
23 elif "=" in first_line: 23 ↛ 27line 23 didn't jump to line 27 because the condition on line 23 was always true
24 return 'toml'
26 else:
27 return None
29def load_yaml_content(content: str) -> dict:
30 try:
31 import yaml
32 except ImportError as e:
33 raise ImportError('PyYAML is not installed, run `pip install pydaconf[yaml]`') from e
35 result: dict | None = yaml.load(content, Loader=yaml.FullLoader)
36 if result is None: 36 ↛ 37line 36 didn't jump to line 37 because the condition on line 36 was never true
37 raise ValueError("Empty yaml content")
39 return result
42def load_json_content(content: str) -> dict:
43 import json
44 result: dict | None = json.loads(content)
45 if result is None: 45 ↛ 46line 45 didn't jump to line 46 because the condition on line 45 was never true
46 raise ValueError("Empty Json content")
48 return result
51def load_toml_content(content: str) -> dict:
52 if sys.version_info < (3, 11): 52 ↛ 53line 52 didn't jump to line 53 because the condition on line 52 was never true
53 try:
54 import tomli
55 toml_module = tomli
56 except ImportError as e:
57 raise ImportError('Toml is not installed, run `pip install pydaconf[toml]`') from e
58 else:
59 import tomllib
60 toml_module = tomllib
62 return toml_module.loads(content)
64def load_config_file(file_path: str) -> dict:
65 if not os.path.exists(file_path): 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true
66 raise FileNotFoundError(f"Configuration file '{file_path}' doesn't exist")
68 with open(file_path) as f:
69 content = f.read()
71 # Guess the file based on extension
72 _, extension = os.path.splitext(file_path)
73 if extension.lower() in {'.yaml', '.yml'}:
74 return load_yaml_content(content)
76 elif extension.lower() == '.json':
77 return load_json_content(content)
79 elif extension.lower() == '.toml':
80 return load_toml_content(content)
81 else:
82 discovered_format = guess_content_format(content)
83 if discovered_format == 'json':
84 return load_json_content(content)
85 elif discovered_format == 'yaml':
86 return load_yaml_content(content)
87 elif discovered_format == 'toml': 87 ↛ 90line 87 didn't jump to line 90 because the condition on line 87 was always true
88 return load_toml_content(content)
89 else:
90 raise UnknownFormat("Unknown config file format. Valid formats are json, yaml and toml.")
93def load_from_url(url: str, headers: dict | None = None) -> dict:
94 try:
95 import requests
96 except ImportError as e:
97 raise ImportError('requests is not installed, run `pip install pydaconf[requests]`') from e
99 response = requests.get(url, headers=headers)
100 response.raise_for_status()
101 content = response.text
102 discovered_format = guess_content_format(content)
103 if discovered_format == 'json': 103 ↛ 104line 103 didn't jump to line 104 because the condition on line 103 was never true
104 return load_json_content(content)
105 elif discovered_format == 'yaml': 105 ↛ 107line 105 didn't jump to line 107 because the condition on line 105 was always true
106 return load_yaml_content(content)
107 elif discovered_format == 'toml':
108 return load_toml_content(content)
109 else:
110 raise UnknownFormat("Unknown config file format")