diff --git a/bot.py b/bot.py
index c2ed3dfdf..471a98eaf 100644
--- a/bot.py
+++ b/bot.py
@@ -1,9 +1,12 @@
+import asyncio
import os
import shutil
import sys
import nonebot
import time
+
+import uvicorn
from dotenv import load_dotenv
from loguru import logger
from nonebot.adapters.onebot.v11 import Adapter
@@ -12,6 +15,8 @@ import platform
# 获取没有加载env时的环境变量
env_mask = {key: os.getenv(key) for key in os.environ}
+uvicorn_server = None
+
def easter_egg():
# 彩蛋
@@ -100,10 +105,12 @@ def load_logger():
"#777777>|> {name:.<8}:{function:.<8}:{line: >4} -> {message}",
colorize=True,
- level=os.getenv("LOG_LEVEL", "DEBUG") # 根据环境设置日志级别,默认为INFO
+ level=os.getenv("LOG_LEVEL", "INFO"), # 根据环境设置日志级别,默认为INFO
+ filter=lambda record: "nonebot" not in record["name"]
)
+
def scan_provider(env_config: dict):
provider = {}
@@ -138,7 +145,39 @@ def scan_provider(env_config: dict):
raise ValueError(f"请检查 '{provider_name}' 提供商配置是否丢失 BASE_URL 或 KEY 环境变量")
-if __name__ == "__main__":
+async def graceful_shutdown():
+ try:
+ global uvicorn_server
+ if uvicorn_server:
+ uvicorn_server.force_exit = True # 强制退出
+ await uvicorn_server.shutdown()
+
+ tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
+ for task in tasks:
+ task.cancel()
+ await asyncio.gather(*tasks, return_exceptions=True)
+
+ except Exception as e:
+ logger.error(f"麦麦关闭失败: {e}")
+
+
+async def uvicorn_main():
+ global uvicorn_server
+ config = uvicorn.Config(
+ app="__main__:app",
+ host=os.getenv("HOST", "127.0.0.1"),
+ port=int(os.getenv("PORT", 8080)),
+ reload=os.getenv("ENVIRONMENT") == "dev",
+ timeout_graceful_shutdown=5,
+ log_config=None,
+ access_log=False
+ )
+ server = uvicorn.Server(config)
+ uvicorn_server = server
+ await server.serve()
+
+
+def raw_main():
# 利用 TZ 环境变量设定程序工作的时区
# 仅保证行为一致,不依赖 localtime(),实际对生产环境几乎没有作用
if platform.system().lower() != 'windows':
@@ -165,10 +204,30 @@ if __name__ == "__main__":
nonebot.init(**base_config, **env_config)
# 注册适配器
+ global driver
driver = nonebot.get_driver()
driver.register_adapter(Adapter)
# 加载插件
nonebot.load_plugins("src/plugins")
- nonebot.run()
+
+if __name__ == "__main__":
+
+ try:
+ raw_main()
+
+ global app
+ app = nonebot.get_asgi()
+
+ loop = asyncio.new_event_loop()
+ asyncio.set_event_loop(loop)
+ loop.run_until_complete(uvicorn_main())
+ except KeyboardInterrupt:
+ logger.warning("麦麦会努力做的更好的!正在停止中......")
+ except Exception as e:
+ logger.error(f"主程序异常: {e}")
+ finally:
+ loop.run_until_complete(graceful_shutdown())
+ loop.close()
+ logger.info("进程终止完毕,麦麦开始休眠......下次再见哦!")