Skip to content

Commit 48c0bea

Browse files
committed
Add YAML include support for modular configuration
1 parent 7a5a5fd commit 48c0bea

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

config.yaml.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#include:
2+
# - config/example.yaml
3+
14
server:
25
host: "0.0.0.0"
36
port: 8080

pyproxy/utils/args.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ def parse_args() -> argparse.Namespace:
9595
return parser.parse_args()
9696

9797

98+
def deep_merge_dicts(base: dict[str, Any], new: dict[str, Any]) -> dict[str, Any]:
99+
"""
100+
Merge two dictionaries recursively.
101+
"""
102+
for key, value in new.items():
103+
if isinstance(value, dict) and isinstance(base.get(key), dict):
104+
base[key] = deep_merge_dicts(base[key], value)
105+
else:
106+
base[key] = value
107+
return base
108+
109+
98110
def load_config(config_path: str) -> dict[str, Any]:
99111
"""
100112
Loads the YAML configuration file and returns it as a dictionary.
@@ -106,9 +118,19 @@ def load_config(config_path: str) -> dict[str, Any]:
106118
dict[str, Any]: Parsed YAML configuration
107119
"""
108120
with open(config_path, "r", encoding="utf-8") as f:
109-
config = yaml.safe_load(f)
110-
if not isinstance(config, dict):
111-
raise ValueError("Invalid YAML configuration format.")
121+
config = yaml.safe_load(f) or {}
122+
123+
includes = config.pop("include", [])
124+
if not isinstance(includes, list):
125+
raise ValueError("'include' must be a list of file paths.")
126+
127+
for inc_path in includes:
128+
inc_abs_path = os.path.join(os.path.dirname(config_path), inc_path)
129+
if os.path.exists(inc_abs_path):
130+
with open(inc_abs_path, "r", encoding="utf-8") as f:
131+
sub_config = yaml.safe_load(f) or {}
132+
config = deep_merge_dicts(config, sub_config)
133+
112134
return config
113135

114136

0 commit comments

Comments
 (0)