feat: proxy nas live recorder controls
This commit is contained in:
@@ -51,6 +51,7 @@ ORCHESTRATOR_SHARED_SECRET = os.getenv("ORCHESTRATOR_SHARED_SECRET", "")
|
||||
CUTVIDEO_BASE_URL = os.getenv("CUTVIDEO_BASE_URL", "http://192.168.31.18:7860")
|
||||
CUTVIDEO_API_KEY = os.getenv("CUTVIDEO_API_KEY", "")
|
||||
HUOBAO_BASE_URL = os.getenv("HUOBAO_BASE_URL", "http://127.0.0.1:5678")
|
||||
LIVE_RECORDER_BASE_URL = os.getenv("LIVE_RECORDER_BASE_URL", "http://192.168.31.188:19106")
|
||||
CUTVIDEO_BASE_CONFIG = os.getenv("CUTVIDEO_BASE_CONFIG", "example.job.yaml")
|
||||
CUTVIDEO_POLL_INTERVAL_SEC = int(os.getenv("CUTVIDEO_POLL_INTERVAL_SEC", "10"))
|
||||
CUTVIDEO_MAX_WAIT_SEC = int(os.getenv("CUTVIDEO_MAX_WAIT_SEC", "1800"))
|
||||
@@ -279,6 +280,15 @@ class ReviewUpdateRequest(BaseModel):
|
||||
highlights: str | None = None
|
||||
next_actions: str | None = None
|
||||
notes: str | None = None
|
||||
|
||||
|
||||
class LiveRecorderImportRequest(BaseModel):
|
||||
raw: str
|
||||
|
||||
|
||||
class LiveRecorderEnabledRequest(BaseModel):
|
||||
line_no: int
|
||||
enabled: bool
|
||||
assistant_id: str | None = None
|
||||
|
||||
|
||||
@@ -1659,6 +1669,33 @@ def probe_http(url: str, path: str = "", timeout: float = 3.0) -> dict[str, Any]
|
||||
return tcp
|
||||
|
||||
|
||||
def live_recorder_request(method: str, path: str, payload: dict[str, Any] | None = None, timeout: float = 20.0) -> Any:
|
||||
if not LIVE_RECORDER_BASE_URL:
|
||||
raise HTTPException(status_code=503, detail="LIVE_RECORDER_BASE_URL is not configured")
|
||||
target_url = urljoin(LIVE_RECORDER_BASE_URL if LIVE_RECORDER_BASE_URL.endswith("/") else f"{LIVE_RECORDER_BASE_URL}/", path.lstrip("/"))
|
||||
try:
|
||||
response = httpx.request(
|
||||
method=method.upper(),
|
||||
url=target_url,
|
||||
json=payload,
|
||||
timeout=timeout,
|
||||
follow_redirects=True,
|
||||
)
|
||||
response.raise_for_status()
|
||||
if "application/json" in (response.headers.get("content-type") or ""):
|
||||
return response.json()
|
||||
return {"ok": True, "text": response.text, "url": target_url}
|
||||
except httpx.HTTPStatusError as exc:
|
||||
detail: Any
|
||||
try:
|
||||
detail = exc.response.json()
|
||||
except Exception:
|
||||
detail = exc.response.text.strip() or f"http_{exc.response.status_code}"
|
||||
raise HTTPException(status_code=exc.response.status_code, detail=detail)
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=502, detail=f"live recorder request failed: {exc}")
|
||||
|
||||
|
||||
def local_model_public_base_url() -> str:
|
||||
if not LOCAL_OPENAI_BASE_URL:
|
||||
return ""
|
||||
@@ -1726,6 +1763,7 @@ def healthz() -> dict[str, Any]:
|
||||
"cutvideoBaseUrl": CUTVIDEO_BASE_URL,
|
||||
"cutvideoUploadTimeoutSec": CUTVIDEO_UPLOAD_TIMEOUT_SEC,
|
||||
"huobaoBaseUrl": HUOBAO_BASE_URL,
|
||||
"liveRecorderBaseUrl": LIVE_RECORDER_BASE_URL,
|
||||
}
|
||||
|
||||
|
||||
@@ -1764,6 +1802,10 @@ def integrations_health(account: dict[str, Any] = Depends(require_approved)) ->
|
||||
"base_url": ASR_HTTP_BASE_URL,
|
||||
**probe_tcp(ASR_HTTP_BASE_URL),
|
||||
},
|
||||
"live_recorder": {
|
||||
"base_url": LIVE_RECORDER_BASE_URL,
|
||||
**probe_http(LIVE_RECORDER_BASE_URL, "/api/healthz"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -1773,6 +1815,53 @@ def integrations_local_models(account: dict[str, Any] = Depends(require_approved
|
||||
return fetch_local_model_catalog()
|
||||
|
||||
|
||||
@app.get("/v2/live-recorder/health")
|
||||
def live_recorder_health(account: dict[str, Any] = Depends(require_approved)) -> dict[str, Any]:
|
||||
_ = account
|
||||
return live_recorder_request("GET", "/api/healthz", timeout=8.0)
|
||||
|
||||
|
||||
@app.get("/v2/live-recorder/status")
|
||||
def live_recorder_status(account: dict[str, Any] = Depends(require_approved)) -> Any:
|
||||
_ = account
|
||||
return live_recorder_request("GET", "/api/status-lite", timeout=8.0)
|
||||
|
||||
|
||||
@app.post("/v2/live-recorder/url-config/import")
|
||||
def live_recorder_import_urls(
|
||||
request: LiveRecorderImportRequest,
|
||||
account: dict[str, Any] = Depends(require_approved),
|
||||
) -> Any:
|
||||
_ = account
|
||||
return live_recorder_request("POST", "/api/url-config/import", {"raw": request.raw}, timeout=20.0)
|
||||
|
||||
|
||||
@app.post("/v2/live-recorder/url-config/set-enabled")
|
||||
def live_recorder_set_enabled(
|
||||
request: LiveRecorderEnabledRequest,
|
||||
account: dict[str, Any] = Depends(require_approved),
|
||||
) -> Any:
|
||||
_ = account
|
||||
return live_recorder_request(
|
||||
"POST",
|
||||
"/api/url-config/set-enabled",
|
||||
{"line_no": request.line_no, "enabled": request.enabled},
|
||||
timeout=20.0,
|
||||
)
|
||||
|
||||
|
||||
@app.post("/v2/live-recorder/recorder/start")
|
||||
def live_recorder_start(account: dict[str, Any] = Depends(require_approved)) -> Any:
|
||||
_ = account
|
||||
return live_recorder_request("POST", "/api/recorder/start", timeout=30.0)
|
||||
|
||||
|
||||
@app.post("/v2/live-recorder/recorder/stop")
|
||||
def live_recorder_stop(account: dict[str, Any] = Depends(require_approved)) -> Any:
|
||||
_ = account
|
||||
return live_recorder_request("POST", "/api/recorder/stop", timeout=30.0)
|
||||
|
||||
|
||||
def seed_defaults() -> None:
|
||||
if not db.fetch_one("SELECT id FROM model_profiles WHERE is_default = 1 LIMIT 1"):
|
||||
profile_id = make_id("model")
|
||||
|
||||
Reference in New Issue
Block a user