feat: 重构环境变量加载器 并 增加提供商扫描功能,简化后续 config 加载后的替换工作
This commit is contained in:
93
bot.py
93
bot.py
@@ -5,7 +5,18 @@ from nonebot.adapters.onebot.v11 import Adapter
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
'''彩蛋'''
|
# 获取所有环境变量
|
||||||
|
env_config = {key: os.getenv(key) for key in os.environ}
|
||||||
|
|
||||||
|
# 设置基础配置
|
||||||
|
base_config = {
|
||||||
|
"websocket_port": int(env_config.get("PORT", 8080)),
|
||||||
|
"host": env_config.get("HOST", "127.0.0.1"),
|
||||||
|
"log_level": "INFO",
|
||||||
|
}
|
||||||
|
|
||||||
|
def easter_egg():
|
||||||
|
# 彩蛋
|
||||||
from colorama import init, Fore
|
from colorama import init, Fore
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@@ -15,8 +26,8 @@ rainbow_text = ""
|
|||||||
for i, char in enumerate(text):
|
for i, char in enumerate(text):
|
||||||
rainbow_text += rainbow_colors[i % len(rainbow_colors)] + char
|
rainbow_text += rainbow_colors[i % len(rainbow_colors)] + char
|
||||||
print(rainbow_text)
|
print(rainbow_text)
|
||||||
'''彩蛋'''
|
|
||||||
|
|
||||||
|
def init_config():
|
||||||
# 初次启动检测
|
# 初次启动检测
|
||||||
if not os.path.exists("config/bot_config.toml"):
|
if not os.path.exists("config/bot_config.toml"):
|
||||||
logger.warning("检测到bot_config.toml不存在,正在从模板复制")
|
logger.warning("检测到bot_config.toml不存在,正在从模板复制")
|
||||||
@@ -29,6 +40,7 @@ if not os.path.exists("config/bot_config.toml"):
|
|||||||
shutil.copy("template/bot_config_template.toml", "config/bot_config.toml")
|
shutil.copy("template/bot_config_template.toml", "config/bot_config.toml")
|
||||||
logger.info("复制完成,请修改config/bot_config.toml和.env.prod中的配置后重新启动")
|
logger.info("复制完成,请修改config/bot_config.toml和.env.prod中的配置后重新启动")
|
||||||
|
|
||||||
|
def init_env():
|
||||||
# 初始化.env 默认ENVIRONMENT=prod
|
# 初始化.env 默认ENVIRONMENT=prod
|
||||||
if not os.path.exists(".env"):
|
if not os.path.exists(".env"):
|
||||||
with open(".env", "w") as f:
|
with open(".env", "w") as f:
|
||||||
@@ -39,41 +51,69 @@ if not os.path.exists(".env"):
|
|||||||
logger.error("检测到.env.prod文件不存在")
|
logger.error("检测到.env.prod文件不存在")
|
||||||
shutil.copy("template.env", "./.env.prod")
|
shutil.copy("template.env", "./.env.prod")
|
||||||
|
|
||||||
|
else:
|
||||||
# 首先加载基础环境变量.env
|
# 首先加载基础环境变量.env
|
||||||
if os.path.exists(".env"):
|
|
||||||
load_dotenv(".env")
|
load_dotenv(".env")
|
||||||
logger.success("成功加载基础环境变量配置")
|
logger.success("成功加载基础环境变量配置")
|
||||||
|
|
||||||
# 根据 ENVIRONMENT 加载对应的环境配置
|
def load_env():
|
||||||
if os.getenv("ENVIRONMENT") == "prod":
|
# 使用闭包实现对加载器的横向扩展,避免大量重复判断
|
||||||
|
def prod():
|
||||||
logger.success("加载生产环境变量配置")
|
logger.success("加载生产环境变量配置")
|
||||||
load_dotenv(".env.prod", override=True) # override=True 允许覆盖已存在的环境变量
|
load_dotenv(".env.prod", override=True) # override=True 允许覆盖已存在的环境变量
|
||||||
elif os.getenv("ENVIRONMENT") == "dev":
|
|
||||||
|
def dev():
|
||||||
logger.success("加载开发环境变量配置")
|
logger.success("加载开发环境变量配置")
|
||||||
load_dotenv(".env.dev", override=True) # override=True 允许覆盖已存在的环境变量
|
load_dotenv(".env.dev", override=True) # override=True 允许覆盖已存在的环境变量
|
||||||
elif os.path.exists(f".env.{os.getenv('ENVIRONMENT')}"):
|
|
||||||
logger.success(f"加载{os.getenv('ENVIRONMENT')}环境变量配置")
|
|
||||||
load_dotenv(f".env.{os.getenv('ENVIRONMENT')}", override=True) # override=True 允许覆盖已存在的环境变量
|
|
||||||
else:
|
|
||||||
logger.error(f"ENVIRONMENT配置错误,请检查.env文件中的ENVIRONMENT变量对应的.env.{os.getenv('ENVIRONMENT')}是否存在")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
# 检测Key是否存在
|
fn_map = {
|
||||||
if not os.getenv("SILICONFLOW_KEY"):
|
"prod": prod,
|
||||||
logger.error("缺失必要的API KEY")
|
"dev": dev
|
||||||
logger.error(f"请至少在.env.{os.getenv('ENVIRONMENT')}文件中填写SILICONFLOW_KEY后重新启动")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
# 获取所有环境变量
|
|
||||||
env_config = {key: os.getenv(key) for key in os.environ}
|
|
||||||
|
|
||||||
# 设置基础配置
|
|
||||||
base_config = {
|
|
||||||
"websocket_port": int(env_config.get("PORT", 8080)),
|
|
||||||
"host": env_config.get("HOST", "127.0.0.1"),
|
|
||||||
"log_level": "INFO",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
env = os.getenv("ENVIRONMENT")
|
||||||
|
if env in fn_map:
|
||||||
|
fn_map[env]() # 根据映射执行闭包函数
|
||||||
|
|
||||||
|
elif os.path.exists(f".env.{env}"):
|
||||||
|
logger.success(f"加载{env}环境变量配置")
|
||||||
|
load_dotenv(f".env.{env}", override=True) # override=True 允许覆盖已存在的环境变量
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.error(f"ENVIRONMENT 配置错误,请检查 .env 文件中的 ENVIRONMENT 变量及对应 .env.{env} 是否存在")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
provider = {}
|
||||||
|
|
||||||
|
def scan_provider():
|
||||||
|
# 遍历 env_config 的所有键
|
||||||
|
for key in env_config:
|
||||||
|
# 检查键是否符合 {provider}_BASE_URL 或 {provider}_KEY 的格式
|
||||||
|
if key.endswith("_BASE_URL") or key.endswith("_KEY"):
|
||||||
|
# 提取 provider 名称
|
||||||
|
provider_name = key.rsplit("_", 1)[0] # 从右边分割一次,取第一部分
|
||||||
|
|
||||||
|
# 初始化 provider 的字典(如果尚未初始化)
|
||||||
|
if provider_name not in provider:
|
||||||
|
provider[provider_name] = {"url": None, "key": None}
|
||||||
|
|
||||||
|
# 根据键的类型填充 url 或 key
|
||||||
|
if key.endswith("_BASE_URL"):
|
||||||
|
provider[provider_name]["url"] = env_config[key]
|
||||||
|
elif key.endswith("_KEY"):
|
||||||
|
provider[provider_name]["key"] = env_config[key]
|
||||||
|
|
||||||
|
# 检查每个 provider 是否同时存在 url 和 key
|
||||||
|
for provider_name, config in provider.items():
|
||||||
|
if config["url"] is None or config["key"] is None:
|
||||||
|
raise ValueError(f"请检查 '{provider_name}' 提供商配置是否丢失 BASE_URL 或 KEY 环境变量")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
easter_egg()
|
||||||
|
init_config()
|
||||||
|
init_env()
|
||||||
|
scan_provider()
|
||||||
|
|
||||||
# 合并配置
|
# 合并配置
|
||||||
nonebot.init(**base_config, **env_config)
|
nonebot.init(**base_config, **env_config)
|
||||||
|
|
||||||
@@ -84,5 +124,4 @@ driver.register_adapter(Adapter)
|
|||||||
# 加载插件
|
# 加载插件
|
||||||
nonebot.load_plugins("src/plugins")
|
nonebot.load_plugins("src/plugins")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
nonebot.run()
|
nonebot.run()
|
||||||
|
|||||||
Reference in New Issue
Block a user