to / scripts /generate_config.py
hequ's picture
Upload 11 files
456cef9 verified
#!/usr/bin/env python3
"""基于环境变量生成 Toolify 配置文件。"""
import os
import sys
from pathlib import Path
from typing import Any, List
import yaml
def _str_to_bool(value: str | None, default: bool) -> bool:
"""将字符串环境变量解析为布尔值。"""
if value is None:
return default
normalized = value.strip().lower()
if normalized in {"1", "true", "yes", "y", "on"}:
return True
if normalized in {"0", "false", "no", "n", "off"}:
return False
return default
def _parse_list(env_value: str | None) -> List[str]:
"""将逗号分隔的环境变量解析为字符串列表。"""
if not env_value:
return []
return [item.strip() for item in env_value.split(",") if item.strip()]
def _load_config_from_env() -> Any:
"""尝试从直接提供的 YAML 或 JSON 环境变量加载配置。"""
direct_yaml = os.getenv("TOOLIFY_CONFIG_YAML")
if direct_yaml:
return yaml.safe_load(direct_yaml)
direct_json = os.getenv("TOOLIFY_CONFIG_JSON")
if direct_json:
return yaml.safe_load(direct_json)
return None
def _build_default_config() -> dict:
"""根据基础环境变量构造最小可用配置。"""
openai_api_key = os.getenv("OPENAI_API_KEY")
allowed_keys = _parse_list(os.getenv("CLIENT_ALLOWED_KEYS"))
if not openai_api_key:
raise RuntimeError("缺少 OPENAI_API_KEY 环境变量,无法生成配置。")
if not allowed_keys:
raise RuntimeError("缺少 CLIENT_ALLOWED_KEYS 环境变量,无法生成配置。")
base_url = os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1").rstrip("/")
models = _parse_list(os.getenv("OPENAI_MODELS", "gpt-4o-mini,gpt-4o"))
if not models:
raise RuntimeError("OPENAI_MODELS 环境变量解析为空,请至少指定一个模型。")
server_port = int(os.getenv("SERVER_PORT", os.getenv("PORT", "8000")))
server_host = os.getenv("SERVER_HOST", "0.0.0.0")
server_timeout = int(os.getenv("SERVER_TIMEOUT", "180"))
features_log_level = os.getenv("FEATURE_LOG_LEVEL", "INFO").upper()
prompt_template = os.getenv("FEATURE_PROMPT_TEMPLATE")
if prompt_template:
prompt_template = prompt_template.replace("\\n", "\n")
return {
"server": {
"port": server_port,
"host": server_host,
"timeout": server_timeout,
},
"upstream_services": [
{
"name": os.getenv("OPENAI_NAME", "openai"),
"base_url": base_url,
"api_key": openai_api_key,
"description": os.getenv("OPENAI_DESCRIPTION", "OpenAI Service"),
"is_default": True,
"models": models,
}
],
"client_authentication": {
"allowed_keys": allowed_keys,
},
"features": {
"enable_function_calling": _str_to_bool(os.getenv("FEATURE_ENABLE_FUNCTION_CALLING"), True),
"log_level": features_log_level if features_log_level else "INFO",
"convert_developer_to_system": _str_to_bool(os.getenv("FEATURE_CONVERT_DEVELOPER_TO_SYSTEM"), True),
"prompt_template": prompt_template,
"key_passthrough": _str_to_bool(os.getenv("FEATURE_KEY_PASSTHROUGH"), False),
"model_passthrough": _str_to_bool(os.getenv("FEATURE_MODEL_PASSTHROUGH"), False),
},
}
def main() -> None:
"""入口函数:生成配置文件。"""
config_path = Path(os.getenv("CONFIG_PATH", "/app/config.yaml"))
if config_path.exists():
print(f"配置文件已存在,跳过生成: {config_path}")
return
config_obj = _load_config_from_env()
if config_obj is None:
config_obj = _build_default_config()
if not isinstance(config_obj, dict):
raise ValueError("环境变量提供的配置必须是字典结构。")
config_path.parent.mkdir(parents=True, exist_ok=True)
config_yaml = yaml.safe_dump(config_obj, sort_keys=False, allow_unicode=True)
config_path.write_text(config_yaml, encoding="utf-8")
print(f"已生成配置文件: {config_path}")
if __name__ == "__main__":
try:
main()
except Exception as exc: # noqa: BLE001
print(f"生成配置文件时出现错误: {exc}", file=sys.stderr)
sys.exit(1)