From bf9701365f2d68e8c1fdaf083139e58cc8f27118 Mon Sep 17 00:00:00 2001
From: AL76 <735756072@qq.com>
Date: Tue, 11 Mar 2025 02:46:13 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E7=B2=BE=E7=AE=80=E6=97=A5=E5=BF=97?=
=?UTF-8?q?=EF=BC=8C=E7=A6=81=E7=94=A8Uvicorn/NoneBot=E9=BB=98=E8=AE=A4?=
=?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9B=E5=90=AF=E5=8A=A8=E6=96=B9=E5=BC=8F?=
=?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=98=BE=E7=A4=BA=E5=8A=A0=E8=BD=BDuvicorn?=
=?UTF-8?q?=EF=BC=8C=E4=BB=A5=E4=BE=BF=E4=BC=98=E9=9B=85shutdown?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
bot.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 62 insertions(+), 3 deletions(-)
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("进程终止完毕,麦麦开始休眠......下次再见哦!")