111 lines
3.6 KiB
Python
111 lines
3.6 KiB
Python
"""
|
|
应用启动器
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from app.core.env_checker import check_environment
|
|
from app.core.venv_manager import check_virtualenv
|
|
from app.core.dependency_manager import check_dependencies
|
|
|
|
|
|
class AppLauncher:
|
|
"""应用启动器"""
|
|
|
|
def __init__(self, project_root: Path):
|
|
"""
|
|
初始化启动器
|
|
|
|
Args:
|
|
project_root: 项目根目录路径
|
|
"""
|
|
self.project_root = project_root
|
|
# 延迟导入logger
|
|
from app.utils.logger import get_logger
|
|
self.logger = get_logger()
|
|
|
|
def run(self):
|
|
"""执行完整的启动流程"""
|
|
try:
|
|
# 检查系统和Python版本
|
|
if not check_environment():
|
|
sys.exit(1)
|
|
|
|
# 检查虚拟环境
|
|
check_virtualenv(self.project_root)
|
|
|
|
# 检查是否正在使用虚拟环境运行
|
|
import platform
|
|
import sys
|
|
venv_path = self.project_root / ".venv"
|
|
os_name = platform.system()
|
|
|
|
if os_name == 'Windows':
|
|
venv_python = venv_path / "Scripts" / "python.exe"
|
|
else: # Linux/Mac
|
|
venv_python = venv_path / "bin" / "python3"
|
|
|
|
# 如果当前不是使用虚拟环境的Python,则重新启动
|
|
current_python = Path(sys.executable).resolve()
|
|
venv_python_resolved = venv_python.resolve()
|
|
|
|
if current_python != venv_python_resolved:
|
|
print("\n" + "=" * 50)
|
|
print("检测到未使用虚拟环境,正在切换到虚拟环境...")
|
|
print("=" * 50)
|
|
|
|
# 使用虚拟环境的Python重新启动应用(不传递参数避免重复检查)
|
|
import subprocess
|
|
cmd = [str(venv_python)] + sys.argv
|
|
subprocess.run(cmd, check=True)
|
|
return
|
|
|
|
# 以下代码仅在虚拟环境中执行
|
|
# 检查安装依赖(只执行一次)
|
|
check_dependencies(self.project_root)
|
|
|
|
# 启动应用
|
|
print("\n" + "=" * 50)
|
|
print("✓ 所有检查通过,准备启动应用...")
|
|
print("=" * 50)
|
|
self.logger.info("系统环境检查通过,开始执行主程序...")
|
|
start()
|
|
|
|
except Exception as e:
|
|
self.logger.error(f"启动失败: {e}")
|
|
sys.exit(1)
|
|
|
|
|
|
def start():
|
|
"""启动应用服务"""
|
|
import threading
|
|
from config import settings
|
|
from app.core.rainfall_manager import rainfall_manager
|
|
from app.utils.logger import get_logger
|
|
from app.utils.thread_pool_manager import block_main_thread, thread_pool_manager
|
|
|
|
logger = get_logger()
|
|
|
|
# 启动 FastAPI 服务(守护线程)
|
|
def run_api_server():
|
|
import uvicorn
|
|
from app.core.server import create_app
|
|
api_app = create_app()
|
|
uvicorn.run(
|
|
api_app,
|
|
host=getattr(settings, "API_HOST", "127.0.0.1"),
|
|
port=int(getattr(settings, "API_PORT", 8082)),
|
|
log_level="info",
|
|
)
|
|
|
|
api_thread = threading.Thread(target=run_api_server, daemon=True, name="api-server")
|
|
api_thread.start()
|
|
logger.info(f"FastAPI 服务已启动: http://{getattr(settings, 'API_HOST', '127.0.0.1')}:{getattr(settings, 'API_PORT', 8082)}")
|
|
|
|
# 启动降雨站点监测
|
|
logger.info("启动降雨站点监测服务...")
|
|
rainfall_manager.monitoring_rainfall_station_id('2025-09-16 20:00:00')
|
|
|
|
# 阻塞主线程,防止程序立即退出
|
|
block_main_thread()
|