from core.security import ( InvalidTokenError, authenticate_token, require_authenticated_user, ) from fastapi import APIRouter, Depends, HTTPException, WebSocket, status from services.editor import python_lsp from starlette.websockets import WebSocketDisconnect router = APIRouter(prefix="/proxy/editor/python", tags=["Editor"]) @router.get("/session", dependencies=[Depends(require_authenticated_user)]) async def python_editor_session(): if python_lsp.lsp_binary() is None: raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="basedpyright-langserver is not installed", ) session = python_lsp.get_session() return { "root_uri": session.root_uri, "file_uri": session.file_uri, } async def authenticate_editor_socket(websocket: WebSocket) -> None: token = websocket.query_params.get("token") if token is None: authorization = websocket.headers.get("authorization", "") scheme, _, value = authorization.partition(" ") if scheme.lower() == "bearer" and value: token = value if not token: raise InvalidTokenError await authenticate_token(token) @router.websocket("/ws") async def python_editor_socket(websocket: WebSocket): try: await authenticate_editor_socket(websocket) except InvalidTokenError: await websocket.close(code=4401) return if python_lsp.lsp_binary() is None: await websocket.close(code=1011, reason="basedpyright unavailable") return session = python_lsp.get_session() await websocket.accept() try: await python_lsp.bridge(websocket, session) except WebSocketDisconnect: return except RuntimeError: await websocket.close(code=1011, reason="language server failed")