Spaces:
Running
Running
import json | |
import os | |
import inspect | |
import pathlib | |
from app.config import settings | |
from app.utils.logging import log | |
# 定义不应该被保存或加载的配置项 | |
EXCLUDED_SETTINGS = [ | |
"STORAGE_DIR", | |
"ENABLE_STORAGE", | |
"BASE_DIR", | |
"PASSWORD", | |
"WEB_PASSWORD", | |
"WHITELIST_MODELS", | |
"BLOCKED_MODELS", | |
"DEFAULT_BLOCKED_MODELS", | |
"PUBLIC_MODE", | |
"DASHBOARD_URL", | |
"version" | |
] | |
def save_settings(): | |
""" | |
将settings中所有的从os.environ.get获取的配置保存到JSON文件中, | |
但排除特定的配置项 | |
""" | |
if settings.ENABLE_STORAGE: | |
# 确保存储目录存在 | |
storage_dir = pathlib.Path(settings.STORAGE_DIR) | |
storage_dir.mkdir(parents=True, exist_ok=True) | |
# 设置JSON文件路径 | |
settings_file = storage_dir / "settings.json" | |
# 获取settings模块中的所有变量 | |
settings_dict = {} | |
for name, value in inspect.getmembers(settings): | |
# 跳过内置和私有变量,以及函数/模块/类,以及排除列表中的配置项 | |
if (not name.startswith('_') and | |
not inspect.isfunction(value) and | |
not inspect.ismodule(value) and | |
not inspect.isclass(value) and | |
name not in EXCLUDED_SETTINGS): | |
# 尝试将可序列化的值添加到字典中 | |
try: | |
json.dumps({name: value}) # 测试是否可序列化 | |
settings_dict[name] = value | |
except (TypeError, OverflowError): | |
# 如果不可序列化,则跳过 | |
continue | |
log('info', f"保存设置到JSON文件: {settings_file}") | |
# 保存到JSON文件 | |
with open(settings_file, 'w', encoding='utf-8') as f: | |
json.dump(settings_dict, f, ensure_ascii=False, indent=4) | |
return settings_file | |
def load_settings(): | |
""" | |
从JSON文件中加载设置并更新settings模块, | |
排除特定的配置项,并合并GEMINI_API_KEYS | |
""" | |
if settings.ENABLE_STORAGE: | |
# 设置JSON文件路径 | |
storage_dir = pathlib.Path(settings.STORAGE_DIR) | |
settings_file = storage_dir / "settings.json" | |
# 如果文件不存在,则返回 | |
if not settings_file.exists(): | |
return False | |
# 从JSON文件中加载设置 | |
try: | |
with open(settings_file, 'r', encoding='utf-8') as f: | |
loaded_settings = json.load(f) | |
# 保存当前环境变量中的GEMINI_API_KEYS | |
current_api_keys = [] | |
if hasattr(settings, 'GEMINI_API_KEYS') and settings.GEMINI_API_KEYS: | |
current_api_keys = settings.GEMINI_API_KEYS.split(',') | |
current_api_keys = [key.strip() for key in current_api_keys if key.strip()] | |
# 保存当前环境变量中的GOOGLE_CREDENTIALS_JSON和VERTEX_EXPRESS_API_KEY | |
current_google_credentials_json = settings.GOOGLE_CREDENTIALS_JSON if hasattr(settings, 'GOOGLE_CREDENTIALS_JSON') else "" | |
current_vertex_express_api_key = settings.VERTEX_EXPRESS_API_KEY if hasattr(settings, 'VERTEX_EXPRESS_API_KEY') else "" | |
# 更新settings模块中的变量,但排除特定配置项 | |
for name, value in loaded_settings.items(): | |
if hasattr(settings, name) and name not in EXCLUDED_SETTINGS: | |
# 特殊处理GEMINI_API_KEYS,进行合并去重 | |
if name == "GEMINI_API_KEYS": | |
loaded_api_keys = value.split(',') if value else [] | |
loaded_api_keys = [key.strip() for key in loaded_api_keys if key.strip()] | |
all_keys = list(set(current_api_keys + loaded_api_keys)) | |
setattr(settings, name, ','.join(all_keys)) | |
# 特殊处理GOOGLE_CREDENTIALS_JSON,如果当前环境变量中有值,则优先使用环境变量中的值 | |
elif name == "GOOGLE_CREDENTIALS_JSON": | |
# 检查当前值是否为空(None、空字符串、只有空白字符,或者是"''"这样的空引号) | |
is_empty = (not current_google_credentials_json or | |
not current_google_credentials_json.strip() or | |
current_google_credentials_json.strip() in ['""', "''"]) | |
log('debug', f"is_empty检查结果: {is_empty}") | |
if is_empty: | |
log('debug', f"当前GOOGLE_CREDENTIALS_JSON为空,将使用持久化的值") | |
setattr(settings, name, value) | |
# 更新环境变量,确保其他模块能够访问到 | |
if value: # 只有当value不为空时才设置环境变量 | |
os.environ["GOOGLE_CREDENTIALS_JSON"] = value | |
log('info', f"从持久化存储加载了GOOGLE_CREDENTIALS_JSON配置") | |
else: | |
log('warning', f"持久化的GOOGLE_CREDENTIALS_JSON值为空") | |
else: | |
log('debug', f"当前GOOGLE_CREDENTIALS_JSON不为空,保持现有值") | |
# 特殊处理VERTEX_EXPRESS_API_KEY,如果当前环境变量中有值,则优先使用环境变量中的值 | |
elif name == "VERTEX_EXPRESS_API_KEY": | |
# 检查当前值是否为空(None、空字符串或只有空白字符) | |
if not current_vertex_express_api_key or not current_vertex_express_api_key.strip(): | |
setattr(settings, name, value) | |
# 更新环境变量,确保其他模块能够访问到 | |
if value: # 只有当value不为空时才设置环境变量 | |
os.environ["VERTEX_EXPRESS_API_KEY"] = value | |
log('info', f"从持久化存储加载了VERTEX_EXPRESS_API_KEY配置") | |
else: | |
setattr(settings, name, value) | |
# 在加载完设置后,检查是否需要刷新模型配置 | |
try: | |
# 如果加载了Google Credentials JSON或Vertex Express API Key,需要刷新模型配置 | |
if (hasattr(settings, 'GOOGLE_CREDENTIALS_JSON') and settings.GOOGLE_CREDENTIALS_JSON) or \ | |
(hasattr(settings, 'VERTEX_EXPRESS_API_KEY') and settings.VERTEX_EXPRESS_API_KEY): | |
log('info', "检测到Google Credentials JSON或Vertex Express API Key,准备更新配置") | |
# 更新配置 | |
import app.vertex.config as app_config | |
# 重新加载vertex配置 | |
app_config.reload_config() | |
# 更新app_config中的GOOGLE_CREDENTIALS_JSON | |
if hasattr(settings, 'GOOGLE_CREDENTIALS_JSON') and settings.GOOGLE_CREDENTIALS_JSON: | |
app_config.GOOGLE_CREDENTIALS_JSON = settings.GOOGLE_CREDENTIALS_JSON | |
# 同时更新环境变量,确保其他模块能够访问到 | |
os.environ["GOOGLE_CREDENTIALS_JSON"] = settings.GOOGLE_CREDENTIALS_JSON | |
log('info', "已更新app_config和环境变量中的GOOGLE_CREDENTIALS_JSON") | |
# 更新app_config中的VERTEX_EXPRESS_API_KEY_VAL | |
if hasattr(settings, 'VERTEX_EXPRESS_API_KEY') and settings.VERTEX_EXPRESS_API_KEY: | |
app_config.VERTEX_EXPRESS_API_KEY_VAL = [key.strip() for key in settings.VERTEX_EXPRESS_API_KEY.split(',') if key.strip()] | |
# 同时更新环境变量 | |
os.environ["VERTEX_EXPRESS_API_KEY"] = settings.VERTEX_EXPRESS_API_KEY | |
log('info', f"已更新app_config和环境变量中的VERTEX_EXPRESS_API_KEY_VAL,共{len(app_config.VERTEX_EXPRESS_API_KEY_VAL)}个有效密钥") | |
log('info', "配置更新完成,Vertex AI将在下次请求时重新初始化") | |
except Exception as e: | |
log('error', f"更新配置时出错: {str(e)}") | |
log('info', f"加载设置成功") | |
return True | |
except Exception as e: | |
log('error', f"加载设置时出错: {e}") | |
return False |