fufeigemini / app /config /persistence.py
Leeflour's picture
Upload 197 files
d0dd276 verified
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