Add internal KVM switch dashboard and service
This commit is contained in:
+71
@@ -0,0 +1,71 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import asynccontextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.responses import FileResponse, HTMLResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.service import KvmSwitcherService
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||
STATIC_DIR = PROJECT_ROOT / "static"
|
||||
INDEX_PATH = STATIC_DIR / "index.html"
|
||||
|
||||
|
||||
class SettingsPayload(BaseModel):
|
||||
device_role: str
|
||||
device_port: str
|
||||
|
||||
|
||||
def create_app(
|
||||
service: KvmSwitcherService | None = None,
|
||||
manage_lifecycle: bool = True,
|
||||
) -> FastAPI:
|
||||
active_service = service or KvmSwitcherService()
|
||||
|
||||
lifespan = None
|
||||
if manage_lifecycle:
|
||||
@asynccontextmanager
|
||||
async def lifespan(app_instance: FastAPI):
|
||||
del app_instance
|
||||
active_service.start()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
active_service.stop()
|
||||
|
||||
app = FastAPI(title="Internal KVM Switch", version="0.1.0", lifespan=lifespan)
|
||||
app.state.kvm_service = active_service
|
||||
|
||||
if STATIC_DIR.exists():
|
||||
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
|
||||
|
||||
@app.get("/")
|
||||
async def root() -> Any:
|
||||
if INDEX_PATH.exists():
|
||||
return FileResponse(INDEX_PATH)
|
||||
return HTMLResponse("<h1>Internal KVM Switch</h1><p>Dashboard file not found.</p>")
|
||||
|
||||
@app.get("/api/status")
|
||||
async def get_status() -> dict[str, Any]:
|
||||
return active_service.get_status()
|
||||
|
||||
@app.post("/api/settings")
|
||||
async def post_settings(payload: SettingsPayload) -> dict[str, Any]:
|
||||
try:
|
||||
return active_service.save_settings(
|
||||
device_role=payload.device_role,
|
||||
device_port=payload.device_port,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
return app
|
||||
|
||||
|
||||
app = create_app()
|
||||
Reference in New Issue
Block a user