#!/usr/bin/env python3 """ LQMDRetrieval 服务启动脚本 """ import sys import os import socket project_root = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, project_root) sys.path.insert(0, os.path.join(project_root, 'src')) from src.app.core.config import config_handler def check_port(host: str, port: int) -> bool: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: try: s.bind((host, port)) return True except OSError: return False def find_available_port(host: str, start_port: int = 8000, max_port: int = 8010) -> int: for port in range(start_port, max_port + 1): if check_port(host, port): return port return None def main(): import uvicorn host = config_handler.get("retrieval_app", "HOST", "0.0.0.0") port = config_handler.get_int("retrieval_app", "PORT", 8000) reload = config_handler.get_bool("retrieval_app", "RELOAD", True) debug = config_handler.get_bool("retrieval_app", "DEBUG", True) print(f"host={host}, port={port}") if not check_port(host, port): print(f"⚠️ 端口 {port} 已被占用,正在查找可用端口...") available_port = find_available_port(host, port, port + 10) if available_port: port = available_port print(f"✅ 找到可用端口: {port}") else: print(f"❌ 未找到可用端口 (尝试范围: {port}-{port+10})") sys.exit(1) print("=" * 70) print(f"🚀 正在启动 {config_handler.get('retrieval_app', 'APP_NAME', '多维度检索')} v{config_handler.get('retrieval_app', 'APP_VERSION', '1.0.0')}") print("=" * 70) print(f"📍 服务地址: http://{host}:{port}") print(f" API文档: http://{host}:{port}/docs") print(f"🔧 调试模式: {'开启' if debug else '关闭'}") print(f"🔄 热重载: {'开启' if reload else '关闭'}") print("=" * 70) try: reload_dirs = [os.path.join(project_root, "src")] if reload else None uvicorn.run( "src.app.server.app:app", host=host, port=port, reload=reload, reload_dirs=reload_dirs, log_level=config_handler.get("retrieval_app", "LOG_LEVEL", "INFO").lower(), access_log=True, use_colors=True ) except KeyboardInterrupt: print("\n👋 服务已停止") except Exception as e: print(f"❌ 服务启动失败: {e}") import traceback traceback.print_exc() sys.exit(1) if __name__ == "__main__": main()