mirror of
https://github.com/countbot-ai/CountBot.git
synced 2026-09-14 20:46:47 +08:00
138 lines
4.1 KiB
Python
138 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
CountBot 应用启动脚本
|
|
生产模式启动,自动打开浏览器
|
|
支持本地网络 IP 监控,类似 Vue3 启动模式
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import webbrowser
|
|
import threading
|
|
from pathlib import Path
|
|
from backend.utils.network import get_local_ips
|
|
from backend.utils.runtime_env import (
|
|
apply_bind_env,
|
|
get_local_client_host,
|
|
is_public_bind_host,
|
|
resolve_bind_address,
|
|
)
|
|
|
|
# 添加项目根目录到 Python 路径
|
|
# Windows UTF-8 编码
|
|
if sys.platform == "win32":
|
|
os.environ["PYTHONIOENCODING"] = "utf-8"
|
|
try:
|
|
import ctypes
|
|
kernel32 = ctypes.windll.kernel32
|
|
kernel32.SetConsoleCP(65001)
|
|
kernel32.SetConsoleOutputCP(65001)
|
|
except Exception:
|
|
pass
|
|
|
|
# 项目根目录
|
|
project_root = Path(__file__).parent
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
|
|
def open_browser_delayed(url: str, delay: float = 15.0) -> None:
|
|
"""
|
|
延迟打开浏览器
|
|
|
|
Args:
|
|
url: 要打开的 URL 地址
|
|
delay: 延迟时间(秒),默认 15 秒,确保服务器完全启动
|
|
"""
|
|
def _open():
|
|
import time
|
|
time.sleep(delay)
|
|
try:
|
|
webbrowser.open(url)
|
|
except Exception:
|
|
pass
|
|
|
|
threading.Thread(target=_open, daemon=True).start()
|
|
|
|
|
|
def main() -> None:
|
|
"""
|
|
启动应用(生产模式)
|
|
|
|
功能:
|
|
- 启动 FastAPI 应用服务器
|
|
- 自动打开浏览器(延迟 15 秒)
|
|
- 显示本地和网络访问地址
|
|
- 支持优雅关闭
|
|
"""
|
|
import uvicorn
|
|
from backend.utils.logger import build_uvicorn_log_config, setup_logger
|
|
from backend.utils.process_manager import setup_graceful_shutdown
|
|
from loguru import logger
|
|
|
|
# 初始化日志系统
|
|
setup_logger()
|
|
|
|
# 设置优雅关闭处理
|
|
process_manager = setup_graceful_shutdown(logger=logger)
|
|
|
|
# 读取配置
|
|
host, port = resolve_bind_address()
|
|
apply_bind_env(host, port)
|
|
|
|
# 获取本地 IP 地址
|
|
local_ips = get_local_ips()
|
|
|
|
# 打印启动信息
|
|
logger.info("=" * 60)
|
|
logger.info("CountBot 启动中...")
|
|
logger.info("=" * 60)
|
|
|
|
try:
|
|
# 启动服务器前显示"服务器启动完成"消息和访问地址
|
|
# 这样地址会在视觉上显示在启动完成之后
|
|
logger.info("服务器启动完成!")
|
|
logger.info("=" * 60)
|
|
|
|
# 显示本地访问地址
|
|
logger.info(f"Local: http://localhost:{port}")
|
|
|
|
# 显示网络访问地址(如果监听了所有接口)
|
|
if is_public_bind_host(host):
|
|
if local_ips:
|
|
for ip in local_ips:
|
|
logger.info(f"Network: http://{ip}:{port}")
|
|
else:
|
|
logger.info("Network: (无法检测到本地 IP 地址)")
|
|
logger.info(f"提示: 请检查网络连接或手动访问 http://<your-ip>:{port}")
|
|
else:
|
|
logger.info(f"Network: http://{host}:{port}")
|
|
logger.info("提示: 如需从其他设备访问,请设置 COUNTBOT_HOST=0.0.0.0")
|
|
|
|
logger.info("-" * 60)
|
|
logger.info("浏览器将在 15 秒后自动打开")
|
|
logger.info("按下 Ctrl+C 停止服务器")
|
|
logger.info("=" * 60)
|
|
|
|
# 延迟 15 秒打开浏览器,确保服务器完全启动
|
|
open_browser_delayed(f"http://{get_local_client_host(host)}:{port}")
|
|
|
|
# 启动服务器(生产模式)
|
|
uvicorn.run(
|
|
"backend.app:app",
|
|
host=host,
|
|
port=port,
|
|
reload=False, # 生产模式禁用热重载
|
|
log_level="info",
|
|
log_config=build_uvicorn_log_config(),
|
|
)
|
|
except KeyboardInterrupt:
|
|
logger.info("Received keyboard interrupt")
|
|
except Exception as e:
|
|
logger.error(f"Server error: {e}")
|
|
raise
|
|
finally:
|
|
process_manager.remove_pid_file()
|
|
logger.info("Application shutdown complete")
|
|
if __name__ == "__main__":
|
|
main()
|