71 lines
2.1 KiB
Python
71 lines
2.1 KiB
Python
"""vps-manager 后端入口
|
|
|
|
- 注册资产 CRUD 与统计路由
|
|
- 挂载本地静态资源(Vue/Tailwind/前端逻辑)
|
|
- 渲染前端 SPA 入口页面
|
|
- 启用 CORS(便于外部程序/其他 AI 跨域调用写入接口)
|
|
"""
|
|
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.staticfiles import StaticFiles
|
|
from jinja2 import Environment, FileSystemLoader
|
|
from sqlmodel import Session
|
|
|
|
from app.core.config import settings
|
|
from app.core.seed import seed_providers
|
|
from app.database import assets_engine, init_db
|
|
from app.routers import agent, assets, monitor, providers, stats
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
STATIC_DIR = BASE_DIR / "static"
|
|
TEMPLATE_DIR = BASE_DIR / "app" / "templates"
|
|
STATIC_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
# 直接使用 Jinja2 Environment 渲染(规避 Starlette Jinja2Templates 在 Python 3.14 下的缓存兼容问题)
|
|
jinja_env = Environment(loader=FileSystemLoader(TEMPLATE_DIR), autoescape=True)
|
|
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(_: FastAPI):
|
|
"""应用启动时自动建表并初始化预设平台"""
|
|
init_db()
|
|
with Session(assets_engine) as session:
|
|
seed_providers(session)
|
|
yield
|
|
|
|
|
|
app = FastAPI(title=settings.APP_NAME, version="0.2.0", lifespan=lifespan)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
app.include_router(assets.router)
|
|
app.include_router(providers.router)
|
|
app.include_router(stats.router)
|
|
app.include_router(agent.router)
|
|
app.include_router(monitor.router)
|
|
|
|
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
|
|
|
|
|
@app.get("/", include_in_schema=False)
|
|
def index() -> HTMLResponse:
|
|
"""前端 SPA 入口"""
|
|
html = jinja_env.get_template("index.html").render(app_name=settings.APP_NAME)
|
|
return HTMLResponse(html)
|
|
|
|
|
|
@app.get("/health")
|
|
def health_check() -> dict:
|
|
"""健康检查(version 动态读取,便于验证自动更新)"""
|
|
return {"status": "ok", "app": "vps-manager", "version": app.version}
|