mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2026-01-12 17:34:12 +00:00
- 添加演练场(Playground)文档导航区到主 README - 新增 Python 解析器文档链接(开发指南、测试报告、LSP集成) - 更新前端版本号至 0.1.9b19p - 补充 Python 解析器 requests 库使用章节和官方文档链接 - 添加 JavaScript 和 Python 解析器的语言版本和官方文档 - 优化文档结构,分类为项目文档和外部资源
216 lines
7.3 KiB
Markdown
216 lines
7.3 KiB
Markdown
# Python Playground pylsp WebSocket 集成指南
|
||
|
||
## 概述
|
||
|
||
本文档说明了如何将 jedi 的 pylsp (python-lsp-server) 通过 WebSocket 集成到 Python Playground 中,实现实时代码检查、自动完成和悬停提示等功能。
|
||
|
||
## 架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 前端 (Vue + Monaco) │
|
||
│ ┌─────────────────────────────────────────────────────────┐│
|
||
│ │ PylspClient.js ││
|
||
│ │ - 通过 WebSocket 发送 LSP JSON-RPC 消息 ││
|
||
│ │ - 接收诊断信息并转换为 Monaco markers ││
|
||
│ └─────────────────────────────────────────────────────────┘│
|
||
└──────────────────────────┬──────────────────────────────────┘
|
||
│ WebSocket (SockJS)
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ 后端 (Vert.x + SockJS) │
|
||
│ ┌─────────────────────────────────────────────────────────┐│
|
||
│ │ PylspWebSocketHandler.java ││
|
||
│ │ - @SockRouteMapper("/pylsp/") ││
|
||
│ │ - 管理 pylsp 子进程 ││
|
||
│ │ - 转发 LSP 消息 ││
|
||
│ └─────────────────────────────────────────────────────────┘│
|
||
└──────────────────────────┬──────────────────────────────────┘
|
||
│ stdio (LSP协议)
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ pylsp (python-lsp-server) │
|
||
│ - jedi: 代码补全、定义跳转 │
|
||
│ - pyflakes: 语法错误检查 │
|
||
│ - pycodestyle: PEP8 风格检查 │
|
||
│ - mccabe: 复杂度检查 │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 文件清单
|
||
|
||
### 后端 (Java)
|
||
|
||
1. **PylspWebSocketHandler.java**
|
||
- 路径: `web-service/src/main/java/cn/qaiu/lz/web/controller/PylspWebSocketHandler.java`
|
||
- 功能: WebSocket 端点,桥接前端与 pylsp 子进程
|
||
- 端点: `/ws/pylsp/*`
|
||
|
||
### 前端 (JavaScript/Vue)
|
||
|
||
1. **pylspClient.js**
|
||
- 路径: `web-front/src/utils/pylspClient.js`
|
||
- 功能: LSP WebSocket 客户端,封装 LSP 协议
|
||
|
||
### 测试
|
||
|
||
1. **RequestsIntegrationTest.java**
|
||
- 路径: `web-service/src/test/java/cn/qaiu/lz/web/playground/RequestsIntegrationTest.java`
|
||
- 功能: requests 库集成测试
|
||
|
||
2. **test_playground_api.py**
|
||
- 路径: `web-service/src/test/python/test_playground_api.py`
|
||
- 功能: API 接口的 pytest 测试脚本
|
||
|
||
## 使用方法
|
||
|
||
### 1. 安装 pylsp
|
||
|
||
```bash
|
||
pip install python-lsp-server[all]
|
||
```
|
||
|
||
或者只安装核心功能:
|
||
|
||
```bash
|
||
pip install python-lsp-server jedi
|
||
```
|
||
|
||
### 2. 前端集成示例
|
||
|
||
```javascript
|
||
import PylspClient from '@/utils/pylspClient';
|
||
|
||
// 创建客户端
|
||
const pylsp = new PylspClient({
|
||
onDiagnostics: (uri, markers) => {
|
||
// 设置 Monaco Editor markers
|
||
monaco.editor.setModelMarkers(model, 'pylsp', markers);
|
||
},
|
||
onConnected: () => {
|
||
console.log('pylsp 已连接');
|
||
},
|
||
onError: (error) => {
|
||
console.error('pylsp 错误:', error);
|
||
}
|
||
});
|
||
|
||
// 连接
|
||
await pylsp.connect();
|
||
|
||
// 打开文档
|
||
pylsp.openDocument(pythonCode);
|
||
|
||
// 更新文档(当代码改变时)
|
||
pylsp.updateDocument(newCode);
|
||
|
||
// 获取补全
|
||
const completions = await pylsp.getCompletions(line, column);
|
||
|
||
// 获取悬停信息
|
||
const hover = await pylsp.getHover(line, column);
|
||
|
||
// 断开连接
|
||
pylsp.disconnect();
|
||
```
|
||
|
||
### 3. 与 Monaco Editor 集成
|
||
|
||
```javascript
|
||
// 监听代码变化
|
||
editor.onDidChangeModelContent((e) => {
|
||
const content = editor.getValue();
|
||
pylsp.updateDocument(content);
|
||
});
|
||
|
||
// 注册补全提供者
|
||
monaco.languages.registerCompletionItemProvider('python', {
|
||
provideCompletionItems: async (model, position) => {
|
||
const items = await pylsp.getCompletions(
|
||
position.lineNumber - 1,
|
||
position.column - 1
|
||
);
|
||
return { suggestions: items.map(convertToMonacoItem) };
|
||
}
|
||
});
|
||
```
|
||
|
||
## 已知限制
|
||
|
||
### GraalPy requests 库限制
|
||
|
||
由于 GraalPy 的 `unicodedata/LLVM` 限制,`requests` 库在后续创建的 Context 中无法正常导入(会抛出 `PolyglotException: null`)。
|
||
|
||
**错误链**:
|
||
```
|
||
requests → encodings.idna → stringprep → from unicodedata import ucd_3_2_0
|
||
```
|
||
|
||
**解决方案**:
|
||
1. 在代码顶层导入 requests(不要在函数内部导入)
|
||
2. 使用标准库的 `urllib.request` 作为替代
|
||
3. 首次执行时预热 requests 导入
|
||
|
||
### 测试注意事项
|
||
|
||
1. PyPlaygroundFullTest 中的测试2和测试5被标记为跳过(已知限制)
|
||
2. 测试13(前端模板代码)使用不依赖 requests 的版本
|
||
3. requests 功能在实际运行时通过首个 Context 可以正常使用
|
||
|
||
## 测试命令
|
||
|
||
### 运行 Java 单元测试
|
||
|
||
```bash
|
||
# PyPlaygroundFullTest (13 个测试)
|
||
cd parser && mvn exec:java \
|
||
-Dexec.mainClass="cn.qaiu.parser.custompy.PyPlaygroundFullTest" \
|
||
-Dexec.classpathScope=test -q
|
||
|
||
# RequestsIntegrationTest
|
||
cd web-service && mvn exec:java \
|
||
-Dexec.mainClass="cn.qaiu.lz.web.playground.RequestsIntegrationTest" \
|
||
-Dexec.classpathScope=test -q
|
||
```
|
||
|
||
### 运行 Python API 测试
|
||
|
||
```bash
|
||
# 需要后端服务运行
|
||
cd web-service/src/test/python
|
||
pip install pytest requests
|
||
pytest test_playground_api.py -v
|
||
```
|
||
|
||
## 配置
|
||
|
||
### 后端配置
|
||
|
||
`PylspWebSocketHandler.java` 中可以配置:
|
||
- pylsp 启动命令
|
||
- 心跳间隔
|
||
- 进程超时
|
||
|
||
### 前端配置
|
||
|
||
`pylspClient.js` 中可以配置:
|
||
- WebSocket URL
|
||
- 重连次数
|
||
- 重连延迟
|
||
- 请求超时
|
||
|
||
## 安全考虑
|
||
|
||
1. pylsp 进程在沙箱环境中运行
|
||
2. 每个 WebSocket 连接对应一个独立的 pylsp 进程
|
||
3. 连接关闭时自动清理进程
|
||
4. Playground 访问需要认证(如果配置了密码)
|
||
|
||
## 未来改进
|
||
|
||
1. 支持多文件项目分析
|
||
2. 添加 pyright 类型检查
|
||
3. 支持代码格式化(black/autopep8)
|
||
4. 添加重构功能
|
||
5. 支持虚拟环境选择
|