启动 Web UI
()
| 136 | |
| 137 | |
| 138 | def start_webui(): |
| 139 | """启动 Web UI""" |
| 140 | # 设置应用程序 |
| 141 | settings = setup_application() |
| 142 | |
| 143 | # 导入 FastAPI 应用(延迟导入以避免循环依赖) |
| 144 | from src.web.app import app |
| 145 | |
| 146 | # 端口占用时自动切换到可用端口,避免启动失败 |
| 147 | bind_host = settings.webui_host |
| 148 | bind_port = int(settings.webui_port) |
| 149 | selected_port = _find_available_port(bind_host, bind_port, max_scan=100) |
| 150 | display_host = _get_display_host(bind_host) |
| 151 | |
| 152 | logger = logging.getLogger(__name__) |
| 153 | if selected_port != bind_port: |
| 154 | logger.warning( |
| 155 | "检测到端口占用,自动切换: %s:%s -> %s:%s", |
| 156 | bind_host, |
| 157 | bind_port, |
| 158 | bind_host, |
| 159 | selected_port, |
| 160 | ) |
| 161 | |
| 162 | # 配置 uvicorn |
| 163 | uvicorn_config = { |
| 164 | "app": "src.web.app:app", |
| 165 | "host": bind_host, |
| 166 | "port": selected_port, |
| 167 | "reload": settings.debug, |
| 168 | "log_level": "info" if settings.debug else "warning", |
| 169 | "access_log": settings.debug, |
| 170 | "ws": "websockets", |
| 171 | } |
| 172 | |
| 173 | logger.info(f"Web UI 已就位,请走这边: http://{display_host}:{selected_port}") |
| 174 | logger.info(f"调试模式: {settings.debug}") |
| 175 | |
| 176 | # 启动服务器 |
| 177 | uvicorn.run(**uvicorn_config) |
| 178 | |
| 179 | |
| 180 | def main(): |
no test coverage detected