Files
qiming/qiming-run_code_rmcp/.cursor/rules/python-execution.mdc
2026-06-01 13:43:09 +08:00

144 lines
3.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description:
globs:
alwaysApply: false
---
# Python代码执行
本项目使用`uv`在隔离环境中执行Python代码提供安全可靠的执行环境。以下是Python代码执行的详细流程
## Python运行器
Python代码通过[PythonRunner](mdc:src/python_runner/python_runner.rs)执行,实现了`RunCode`特性:
```rust
pub struct PythonRunner;
impl RunCode for PythonRunner {
async fn run(&self, code: &str) -> Result<CodeScriptExecutionResult> {
// 实现代码...
}
async fn run_with_params(&self, code: &str, params: Option<serde_json::Value>) -> Result<CodeScriptExecutionResult> {
// 实现代码...
}
}
```
## 依赖解析
Python代码的依赖通过[python_dependencies.rs](mdc:src/python_runner/dependencies/python_dependencies.rs)解析:
1. 使用Pest解析器分析Python代码中的import语句
2. 支持常规import语句和importlib动态导入
3. 提取所有导入的模块名称
```rust
pub fn parse_import(python_code: &str) -> Result<Vec<String>> {
// 使用Pest解析器分析Python代码
let pairs = ImportParser::parse(Rule::file, &input)?;
// 提取模块名称
let mut imported_modules = Vec::new();
// 处理各种import语句...
Ok(imported_modules)
}
```
## 代码准备
Python代码在执行前需要进行包装添加日志捕获和函数执行逻辑
```rust
fn prepare_python_code(&self, code: &str, show_logs: bool) -> String {
// 创建包装代码,包括:
// 1. 日志捕获
// 2. 参数解析
// 3. 执行handler或main函数
// 4. 结果格式化
}
```
包装代码主要功能:
1. 捕获标准输出作为日志
2. 从环境变量`INPUT_JSON`解析参数
3. 优先执行`handler`函数,如果不存在则执行`main`函数
4. 将执行结果和日志格式化为JSON
## 参数传递
参数通过环境变量`INPUT_JSON`传递给Python脚本
```rust
// 将参数序列化为JSON字符串
let params_json = match params {
Some(p) => serde_json::to_string(&p)?,
None => "{}".to_string(),
};
// 通过环境变量传递参数
execute_command.env("INPUT_JSON", &params_json);
```
在Python脚本中参数通过以下方式获取
```python
# 从环境变量获取输入参数
args = {}
try:
input_json = os.environ.get('INPUT_JSON')
if input_json:
args = json.loads(input_json)
except Exception as e:
print(f"解析输入参数失败: {e}")
```
## 执行流程
1. 计算代码哈希值,检查缓存
2. 如果缓存存在,直接使用;否则:
- 分析代码依赖
- 准备包装后的代码
- 保存到缓存
3. 使用`uv`命令在隔离环境中执行代码:
```rust
let mut execute_command = Command::new("uv");
execute_command
.arg("run")
.arg("-s") // 明确指定作为脚本运行
.arg("--isolated") // 在隔离环境中运行
.arg("-p")
.arg("python3") // 指定Python解释器
.env("INPUT_JSON", &params_json) // 通过环境变量传递参数
.arg(&temp_path)
```
4. 解析执行结果,提取日志和返回值
## 结果处理
执行结果通过JSON格式返回包含三个字段
- `logs`: 执行过程中的日志数组
- `result`: 执行结果(可能是字符串、数字、布尔值、对象等)
- `error`: 执行错误(如果有)
```json
{
"logs": ["日志1", "日志2", ...],
"result": "执行结果",
"error": null
}
```
## 支持的返回类型
Python脚本可以返回多种类型的值
1. 字符串
2. 数字
3. 布尔值
4. 列表/数组
5. 字典/对象
6. None/null
所有复杂类型列表、字典都会被序列化为JSON字符串。