from fastapi import FastAPI from starlette.responses import HTMLResponse from fastapi.middleware.cors import CORSMiddleware from speakers.server.utils import MakeFastAPIOffline from speakers.server.model.result import BaseResponse from speakers.server.servlet.document import page_index, document from speakers.server.servlet.runner import (submit_async, get_task_async, post_task_update_async, result_async) from speakers.server.bootstrap.bootstrap_register import bootstrap_register from speakers.server.bootstrap.base import Bootstrap from speakers.common.registry import registry from fastapi.staticfiles import StaticFiles import uvicorn import threading @bootstrap_register.register_bootstrap("runner_bootstrap_web") class RunnerBootstrapBaseWeb(Bootstrap): """ Bootstrap Server Lifecycle """ app: FastAPI server_thread: threading def __init__(self, host: str, port: int): super().__init__() self.host = host self.port = port @classmethod def from_config(cls, cfg=None): host = cfg.get("host") port = cfg.get("port") return cls(host=host, port=port) async def run(self): self.app = FastAPI( title="API Server", version=self.version ) MakeFastAPIOffline(self.app) self.app.mount("/static", StaticFiles(directory=f"{registry.get_path('server_library_root')}/static/static"), name="static") # Add CORS middleware to allow all origins # 在config.py中设置OPEN_DOMAIN=True,允许跨域 # set OPEN_DOMAIN=True in config.py to allow cross-domain self.app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) self.app.get("/", response_model=BaseResponse, summary="演示首页")(page_index) self.app.get("/docs", response_model=BaseResponse, summary="swagger 文档")(document) self.app.post("/runner/submit", tags=["Runner"], summary="提交调度Runner")(submit_async) self.app.get("/runner/task-internal", tags=["Runner"], summary="内部获取调度Runner")(get_task_async) self.app.post("/runner/task-update-internal", tags=["Runner"], summary="内部同步调度RunnerStat")(post_task_update_async) self.app.get("/runner/result", tags=["Runner"], summary="获取任务结果")(result_async) app = self.app def run_server(): uvicorn.run(app, host=self.host, port=self.port) self.server_thread = threading.Thread(target=run_server) self.server_thread.start() async def destroy(self): server_thread = self.server_thread app = self.app @app.on_event("shutdown") def shutdown_event(): server_thread.join() # 等待服务器线程结束