From 920a94bad519ab0cff145d26f0c83af9b22e601f Mon Sep 17 00:00:00 2001 From: Upstream Data Date: Mon, 25 Nov 2024 16:03:45 -0700 Subject: [PATCH] Use get request for logs instead of websocket --- goosebit/__init__.py | 3 +- goosebit/api/v1/devices/device/responses.py | 1 + goosebit/api/v1/devices/device/routes.py | 2 +- goosebit/realtime/__init__.py | 1 - goosebit/realtime/logs.py | 41 --------------------- goosebit/realtime/routes.py | 13 ------- goosebit/ui/bff/devices/device/__init__.py | 1 + goosebit/ui/bff/devices/device/routes.py | 16 ++++++++ goosebit/ui/bff/devices/routes.py | 2 + goosebit/ui/static/js/logs.js | 29 ++++----------- 10 files changed, 29 insertions(+), 80 deletions(-) delete mode 100644 goosebit/realtime/__init__.py delete mode 100644 goosebit/realtime/logs.py delete mode 100644 goosebit/realtime/routes.py create mode 100644 goosebit/ui/bff/devices/device/__init__.py create mode 100644 goosebit/ui/bff/devices/device/routes.py diff --git a/goosebit/__init__.py b/goosebit/__init__.py index ee64a28a..ccfeff7b 100644 --- a/goosebit/__init__.py +++ b/goosebit/__init__.py @@ -13,7 +13,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException from tortoise.exceptions import ValidationError -from goosebit import api, db, realtime, ui, updater +from goosebit import api, db, ui, updater from goosebit.api.telemetry import metrics from goosebit.auth import get_user_from_request, login_user, redirect_if_authenticated from goosebit.settings import config @@ -57,7 +57,6 @@ async def lifespan(_: FastAPI): app.include_router(updater.router) app.include_router(ui.router) app.include_router(api.router) -app.include_router(realtime.router) app.mount("/static", static, name="static") Instrumentor.instrument_app(app) diff --git a/goosebit/api/v1/devices/device/responses.py b/goosebit/api/v1/devices/device/responses.py index 1b03945f..b252936d 100644 --- a/goosebit/api/v1/devices/device/responses.py +++ b/goosebit/api/v1/devices/device/responses.py @@ -7,6 +7,7 @@ class DeviceLogResponse(BaseModel): log: str | None + progress: int | None class DeviceResponse(DeviceSchema): diff --git a/goosebit/api/v1/devices/device/routes.py b/goosebit/api/v1/devices/device/routes.py index 3ef4c33c..b0cc4c46 100644 --- a/goosebit/api/v1/devices/device/routes.py +++ b/goosebit/api/v1/devices/device/routes.py @@ -29,4 +29,4 @@ async def device_get(_: Request, device: Device = Depends(get_device)) -> Device async def device_logs(_: Request, device: Device = Depends(get_device)) -> DeviceLogResponse: if device is None: raise HTTPException(404) - return DeviceLogResponse(log=device.last_log) + return DeviceLogResponse(log=device.last_log, progress=device.progress) diff --git a/goosebit/realtime/__init__.py b/goosebit/realtime/__init__.py deleted file mode 100644 index 2c102012..00000000 --- a/goosebit/realtime/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .routes import router # noqa: F401 diff --git a/goosebit/realtime/logs.py b/goosebit/realtime/logs.py deleted file mode 100644 index 287ad900..00000000 --- a/goosebit/realtime/logs.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import annotations - -from fastapi import APIRouter, Security -from fastapi.websockets import WebSocket, WebSocketDisconnect -from pydantic import BaseModel -from websockets.exceptions import ConnectionClosed - -from goosebit.auth import validate_user_permissions -from goosebit.device_manager import DeviceManager, get_device - -router = APIRouter(prefix="/logs") - - -class RealtimeLogModel(BaseModel): - log: str | None - progress: int | None - clear: bool = False - - -@router.websocket( - "/{dev_id}", - dependencies=[Security(validate_user_permissions, scopes=["device.read"])], -) -async def device_logs(websocket: WebSocket, dev_id: str): - await websocket.accept() - - device = await get_device(dev_id) - - async def callback(log_update): - data = RealtimeLogModel(log=log_update, progress=device.progress) - if log_update is None: - data.clear = True - data.log = "" - await websocket.send_json(dict(data)) - - async with DeviceManager.subscribe_log(device, callback): - try: - while True: - await websocket.receive() - except (WebSocketDisconnect, ConnectionClosed, RuntimeError): - pass diff --git a/goosebit/realtime/routes.py b/goosebit/realtime/routes.py deleted file mode 100644 index eab0a24f..00000000 --- a/goosebit/realtime/routes.py +++ /dev/null @@ -1,13 +0,0 @@ -from fastapi import APIRouter, Depends - -from goosebit.auth import validate_current_user - -from . import logs - -router = APIRouter( - prefix="/realtime", - dependencies=[Depends(validate_current_user)], - tags=["realtime"], -) - -router.include_router(logs.router) diff --git a/goosebit/ui/bff/devices/device/__init__.py b/goosebit/ui/bff/devices/device/__init__.py new file mode 100644 index 00000000..6096e388 --- /dev/null +++ b/goosebit/ui/bff/devices/device/__init__.py @@ -0,0 +1 @@ +from .routes import router # noqa : F401 diff --git a/goosebit/ui/bff/devices/device/routes.py b/goosebit/ui/bff/devices/device/routes.py new file mode 100644 index 00000000..54f73ce6 --- /dev/null +++ b/goosebit/ui/bff/devices/device/routes.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +from fastapi import APIRouter, Security + +from goosebit.api.v1.devices.device import routes +from goosebit.auth import validate_user_permissions + +router = APIRouter(prefix="/{dev_id}") + +router.add_api_route( + "/log", + routes.device_logs, + methods=["GET"], + dependencies=[Security(validate_user_permissions, scopes=["device.read"])], + name="bff_device_logs", +) diff --git a/goosebit/ui/bff/devices/routes.py b/goosebit/ui/bff/devices/routes.py index bb8d2e94..b802487e 100644 --- a/goosebit/ui/bff/devices/routes.py +++ b/goosebit/ui/bff/devices/routes.py @@ -19,10 +19,12 @@ from goosebit.ui.bff.common.util import parse_datatables_query from ..common.responses import DTColumnDescription, DTColumns +from . import device from .requests import DevicesPatchRequest from .responses import BFFDeviceResponse router = APIRouter(prefix="/devices") +router.include_router(device.router) @router.get( diff --git a/goosebit/ui/static/js/logs.js b/goosebit/ui/static/js/logs.js index 963c7c2c..7808aa64 100644 --- a/goosebit/ui/static/js/logs.js +++ b/goosebit/ui/static/js/logs.js @@ -1,25 +1,10 @@ -document.addEventListener("DOMContentLoaded", () => { - const logs_ws = create_ws(`/realtime/logs/${device}`); +document.addEventListener("DOMContentLoaded", async () => { + const res = await get_request(`/ui/bff/devices/${device}/log`); - logs_ws.addEventListener("message", (event) => { - const res = JSON.parse(event.data); + const logElem = document.getElementById("device-log"); + logElem.textContent = res.log; - const logElem = document.getElementById("device-log"); - if (res.clear) { - logElem.textContent = ""; - } - logElem.textContent += res.log; - - const progressElem = document.getElementById("install-progress"); - progressElem.style.width = `${res.progress}%`; - progressElem.innerHTML = `${res.progress}%`; - }); + const progressElem = document.getElementById("install-progress"); + progressElem.style.width = `${res.progress}%`; + progressElem.innerHTML = `${res.progress}%`; }); - -function create_ws(s) { - const l = window.location; - const protocol = l.protocol === "https:" ? "wss://" : "ws://"; - const port = l.port !== "80" || l.port !== "443" ? l.port : ""; - const url = `${protocol}${l.hostname}:${port}${s}`; - return new WebSocket(url); -}