63 lines
1.5 KiB
Python
63 lines
1.5 KiB
Python
import copy
|
|
import json
|
|
import os
|
|
|
|
DEFAULT_CONFIG = {
|
|
"api": {
|
|
"api_key": None,
|
|
"model": "deepseek-v4-flash",
|
|
"base_url": "https://api.deepseek.com/chat/completions",
|
|
"timeout": 120,
|
|
"max_retries": 3,
|
|
"max_tokens": 32768,
|
|
}
|
|
}
|
|
|
|
ENV_OVERRIDES = {
|
|
"api_key": "DEEPSEEK_API_KEY",
|
|
"model": "DEEPSEEK_MODEL",
|
|
"base_url": "DEEPSEEK_BASE_URL",
|
|
"timeout": "DEEPSEEK_TIMEOUT",
|
|
"max_retries": "DEEPSEEK_MAX_RETRIES",
|
|
"max_tokens": "DEEPSEEK_MAX_TOKENS",
|
|
}
|
|
|
|
_INT_KEYS = {"timeout", "max_retries", "max_tokens"}
|
|
|
|
|
|
def _project_root() -> str:
|
|
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
def _default_config_path() -> str:
|
|
return os.path.join(_project_root(), 'config.json')
|
|
|
|
|
|
def load_config(path: str = None) -> dict:
|
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
|
|
|
if path is None:
|
|
path = _default_config_path()
|
|
|
|
if os.path.exists(path):
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
user_config = json.load(f)
|
|
_deep_merge(config, user_config)
|
|
|
|
for key, env_name in ENV_OVERRIDES.items():
|
|
value = os.environ.get(env_name)
|
|
if value is not None:
|
|
if key in _INT_KEYS:
|
|
value = int(value)
|
|
config['api'][key] = value
|
|
|
|
return config
|
|
|
|
|
|
def _deep_merge(base: dict, override: dict) -> None:
|
|
for key, value in override.items():
|
|
if isinstance(value, dict) and isinstance(base.get(key), dict):
|
|
_deep_merge(base[key], value)
|
|
else:
|
|
base[key] = value
|