# --- main.py --- import os from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.responses import HTMLResponse from contextlib import asynccontextmanager from starlette.middleware.base import BaseHTTPMiddleware # 🌟 新增引入 import database # 引入我們剛剛拆分出來的路由模組 from routers import query, config, terminal, lock, leaf_options, backup, diagnostics, auth @asynccontextmanager async def lifespan(app: FastAPI): # Startup await database.init_db_pool() yield # Shutdown await database.close_db_pool() app = FastAPI(title="Harmonic CMTS Manager", version="2.0", lifespan=lifespan) # 🌟 新增:全域安全與快取 Middleware class SecurityAndCacheMiddleware(BaseHTTPMiddleware): async def dispatch(self, request, call_next): response = await call_next(request) # 1. 補上安全性標頭 (圖片 7 的警告) response.headers["X-Content-Type-Options"] = "nosniff" # 2. 針對靜態檔案補上 Cache-Control (圖片 2 的警告) # 讓 JS/CSS 快取 1 小時 (3600秒),提升前端載入效能 if request.url.path.startswith("/static/"): response.headers["Cache-Control"] = "public, max-age=3600" else: # API 請求不快取,確保拿到最新資料 response.headers["Cache-Control"] = "no-store" return response app.add_middleware(SecurityAndCacheMiddleware) # 🌟 掛載 Middleware # 掛載靜態檔案目錄 (對應 static/style.css 與 static/app.js) app.mount("/static", StaticFiles(directory="static"), name="static") # 🌟 統一標準:所有 REST API 都在這裡掛載 /api/v1 前綴 app.include_router(query.router, prefix="/api/v1") app.include_router(config.router, prefix="/api/v1") app.include_router(leaf_options.router, prefix="/api/v1") app.include_router(lock.router, prefix="/api/v1") app.include_router(backup.router, prefix="/api/v1") app.include_router(diagnostics.router, prefix="/api/v1") app.include_router(auth.router, prefix="/api/v1") # WebSocket 通常獨立於 API 版本之外,所以不加前綴 app.include_router(terminal.router) # 根目錄路由:回傳前端 UI @app.get("/", response_class=HTMLResponse, tags=["UI"]) async def read_root(): # 讀取同層級的 index.html html_path = os.path.join(os.path.dirname(__file__), "index.html") with open(html_path, "r", encoding="utf-8") as f: return f.read() if __name__ == "__main__": import uvicorn # 啟動伺服器 uvicorn.run("main:app", host="0.0.0.0", port=8001, reload=True)