FreeLLMAPI / config.py
javaeeduke's picture
Update config.py
9841f0b verified
import os
import sqlite3
import uuid
import datetime
# 1. 定位原项目在 Docker 容器内生成的 SQLite 数据库路径
# 原项目默认存放在 server/prisma/dev.db 或类似路径下,根据容器内实际路径做安全兼容
DB_PATHS = [
"/app/server/prisma/dev.db",
"server/prisma/dev.db",
"prisma/dev.db"
]
def get_active_db():
for path in DB_PATHS:
if os.path.exists(path):
return path
# 如果还没生成,尝试初始化一个路径
return "/app/server/prisma/dev.db"
def inject_secrets_to_sqlite():
db_path = get_active_db()
print(f"📦 正在连接 FreeLLMAPI 核心数据库: {db_path}")
# 对齐你配置的 HF Secrets 名字与项目数据库里的 Provider 标识
secrets_map = {
"GOOGLE_API_KEY": "google",
"GROQ_API_KEY": "groq",
"GITHUB_TOKEN": "github",
"OPENROUTER_API_KEY": "openrouter",
"MISTRAL_API_KEY": "mistral",
"TOGETHER_API_KEY": "together",
"NVIDIA_API_KEY": "nvidia",
"COHERE_API_KEY": "cohere",
"HF_TOKEN": "huggingface",
"CEREBRAS_API_KEY": "cerebras",
"SAMBANOVA_API_KEY": "sambanova",
"CLOUDFLARE_API_TOKEN": "cloudflare",
"ZHIPU_API_KEY": "zhipu"
}
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# 2. 检查原项目内 Provider 或者是 Keys 表的结构
# 原项目的表名通常叫 Provider 或者 Credentials
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = [t[0] for t in cursor.fetchall()]
print(f"📊 探测到系统当前表结构: {tables}")
# 寻找存储渠道的表(通常包含 'Provider' 或 'Credential' 关键字)
target_table = "Provider" if "Provider" in tables else None
if not target_table:
for t in tables:
if "key" in t.lower() or "provider" in t.lower():
target_table = t
break
if not target_table:
print("❌ 未能识别到原项目的密钥存储表,请先在前端随便手动添加任意一个Key以初始化数据库。")
return
# 3. 遍历并强行注入 Secrets
success_count = 0
now = datetime.datetime.utcnow().isoformat()
for secret_name, provider_id in secrets_map.items():
actual_key = os.getenv(secret_name)
if not actual_key:
continue
# 检查数据库中是否已存在该渠道,防止重复插入
cursor.execute(f"SELECT id FROM {target_table} WHERE name = ? OR provider = ?", (provider_id, provider_id))
exists = cursor.fetchone()
if not exists:
# 动态生成符合 Prisma 规范的记录
# 💡 注意:原版采用了不加密或自加密,这里直接存入(如果原版带加密,脚本运行后前端会显示加密格式)
record_id = str(uuid.uuid4())
try:
# 根据标准的 Prisma 字段结构进行弹性插入
cursor.execute(f"""
INSERT INTO {target_table} (id, name, provider, apiKey, status, createdAt, updatedAt)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (record_id, provider_id, provider_id, actual_key, "active", now, now))
success_count += 1
except sqlite3.OperationalError:
# 如果字段不完全对齐,尝试最简化插入
cursor.execute(f"""
INSERT INTO {target_table} (id, name, apiKey)
VALUES (?, ?, ?)
""", (record_id, provider_id, actual_key))
success_count += 1
conn.commit()
conn.close()
print(f"🏁 注入成功!已将 {success_count} 个云端 Secrets 强制同步到本地 SQLite。")
except Exception as e:
print(f"⚠️ 自动注入过程中发生意外,正在等待系统原生初始化: {str(e)}")
if __name__ == "__main__":
inject_secrets_to_sqlite()