64 lines
1.8 KiB
Python
64 lines
1.8 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, WebSocket, status
|
|
from starlette.websockets import WebSocketDisconnect
|
|
|
|
from app.core.security import (
|
|
InvalidTokenError,
|
|
authenticate_token,
|
|
require_authenticated_user,
|
|
)
|
|
from app.services.editor import python_lsp
|
|
|
|
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")
|