x
This commit is contained in:
+25
-20
@@ -28,6 +28,7 @@ def create_app(
|
||||
service_name: str,
|
||||
version: str = "4.0.0",
|
||||
mount_html: bool = False,
|
||||
serve_frontend_static: bool = False,
|
||||
startup_hooks: Optional[List[Callable[[], Awaitable[None]]]] = None,
|
||||
register_routers: Optional[Callable[[FastAPI], None]] = None,
|
||||
) -> FastAPI:
|
||||
@@ -38,6 +39,7 @@ def create_app(
|
||||
service_name: 服务名(用于 /health 响应)
|
||||
version: 版本号
|
||||
mount_html: 是否挂载 /html 静态目录(moldinsight 需要)
|
||||
serve_frontend_static: 是否由后端托管 /static 与 SPA fallback(默认关闭,前端独立部署)
|
||||
startup_hooks: 额外的 startup 钩子列表(在数据库/RustFS/Redis 初始化后执行)
|
||||
register_routers: 回调函数,用于注册业务路由
|
||||
"""
|
||||
@@ -70,7 +72,7 @@ def create_app(
|
||||
|
||||
# 跳过静态资源和健康检查的详细日志
|
||||
path = request.url.path
|
||||
is_static = path.startswith("/static") or path == "/health"
|
||||
is_static = (serve_frontend_static and path.startswith("/static")) or path == "/health"
|
||||
|
||||
if not is_static:
|
||||
log_level = "warning" if response.status_code >= 400 else "info"
|
||||
@@ -92,16 +94,18 @@ def create_app(
|
||||
|
||||
# ── 目录准备 ─────────────────────────────────────────────────
|
||||
Path("uploads").mkdir(exist_ok=True)
|
||||
Path("static").mkdir(exist_ok=True)
|
||||
if serve_frontend_static:
|
||||
Path("static").mkdir(exist_ok=True)
|
||||
if mount_html:
|
||||
Path("html_output").mkdir(exist_ok=True)
|
||||
|
||||
# ── 静态文件挂载 ─────────────────────────────────────────────
|
||||
app.mount(
|
||||
"/static",
|
||||
StaticFiles(directory=os.path.join(os.getcwd(), "static")),
|
||||
name="static",
|
||||
)
|
||||
if serve_frontend_static:
|
||||
app.mount(
|
||||
"/static",
|
||||
StaticFiles(directory=os.path.join(os.getcwd(), "static")),
|
||||
name="static",
|
||||
)
|
||||
if mount_html:
|
||||
app.mount(
|
||||
"/html",
|
||||
@@ -189,19 +193,20 @@ def create_app(
|
||||
"database_error": db_error,
|
||||
}
|
||||
|
||||
# ── SPA fallback(排除 /api 前缀,避免吞掉 API 404)────────
|
||||
@app.get("/{full_path:path}")
|
||||
async def spa_fallback(full_path: str):
|
||||
# API 路径不走 SPA fallback,让 FastAPI 正常返回 404 JSON
|
||||
if full_path.startswith("api/") or full_path.startswith("api"):
|
||||
raise _api_not_found(full_path)
|
||||
# 健康检查 / 文档路径也排除
|
||||
if full_path.startswith("docs") or full_path.startswith("openapi"):
|
||||
raise _api_not_found(full_path)
|
||||
static_index = os.path.join(os.getcwd(), "static", "index.html")
|
||||
if os.path.exists(static_index):
|
||||
return FileResponse(static_index)
|
||||
return JSONResponse({"detail": "SPA index not found"}, status_code=404)
|
||||
# ── SPA fallback(独立前端部署时默认关闭)────────────────────
|
||||
if serve_frontend_static:
|
||||
@app.get("/{full_path:path}")
|
||||
async def spa_fallback(full_path: str):
|
||||
# API 路径不走 SPA fallback,让 FastAPI 正常返回 404 JSON
|
||||
if full_path.startswith("api/") or full_path.startswith("api"):
|
||||
raise _api_not_found(full_path)
|
||||
# 健康检查 / 文档路径也排除
|
||||
if full_path.startswith("docs") or full_path.startswith("openapi"):
|
||||
raise _api_not_found(full_path)
|
||||
static_index = os.path.join(os.getcwd(), "static", "index.html")
|
||||
if os.path.exists(static_index):
|
||||
return FileResponse(static_index)
|
||||
return JSONResponse({"detail": "SPA index not found"}, status_code=404)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
Reference in New Issue
Block a user