# 🚀 通用Python执行器进度支持系统 一个完全重构的通用Python执行器,支持实时进度回调、JSON-RPC通信和简化的命令创建。 ## ✨ 新特性 - 🎯 **通用进度支持**:一次实现,到处使用 - 🔧 **简化的API**:多种便利函数和宏 - 📊 **实时进度更新**:支持Tauri事件和自定义回调 - 🛠️ **命令构建器**:简化Python命令构造 - 📝 **丰富的示例**:涵盖各种使用场景 ## 功能特性 - ✅ 支持多种Python命令 (python, python3, py) - ✅ UTF-8编码处理 - ✅ 并发stdout/stderr读取 - ✅ JSON-RPC消息解析 - ✅ 实时进度回调 - ✅ Tauri事件发射 - ✅ 超时处理 - ✅ 错误处理 ## 🎯 核心API ### 1. 通用进度执行函数 ```rust // 最通用的函数 - 推荐使用 execute_python_action_with_progress( app: AppHandle, module: &str, // Python模块路径 action: &str, // 要执行的动作 params: &[(&str, &str)], // 参数键值对 event_name: &str, // 前端事件名称 config: Option ) -> Result ``` ### 2. 便利函数 ```rust // Tauri事件进度(推荐用于前端集成) execute_python_with_events(app, &args, config, "event-name") // 函数回调进度(用于自定义处理) execute_python_with_callback(app, &args, config, callback) // 基本执行(无进度) execute_python_command(app, &args, config) ``` ### 3. 宏支持 ```rust // 简单命令宏 python_action_command! { name: my_simple_command, module: "python_core.my_module", action: "my_action", event: "my-progress-event" } ``` ## 📋 使用方法 ### 1. 基本用法(无进度) ```rust use crate::python_executor::execute_python_command; #[tauri::command] pub async fn my_command(app: AppHandle) -> Result { let args = vec![ "-m".to_string(), "my_python_module".to_string(), "--action".to_string(), "do_something".to_string(), ]; execute_python_command(app, &args, None).await } ``` ### 2. 使用Tauri事件进度回调 ```rust use crate::python_executor::execute_python_with_events; #[tauri::command] pub async fn my_command_with_progress(app: AppHandle) -> Result { let args = vec![ "-m".to_string(), "my_python_module".to_string(), "--action".to_string(), "long_running_task".to_string(), ]; // 进度将通过 "my-task-progress" 事件发送到前端 execute_python_with_events(app, &args, None, "my-task-progress").await } ``` ### 3. 使用函数回调 ```rust use crate::python_executor::{execute_python_with_callback, PythonProgress}; #[tauri::command] pub async fn my_command_with_callback(app: AppHandle) -> Result { let args = vec![ "-m".to_string(), "my_python_module".to_string(), "--action".to_string(), "process_data".to_string(), ]; // 自定义进度处理 let progress_callback = |progress: PythonProgress| { println!("Progress: {}% - {}", progress.progress, progress.message); // 可以在这里添加自定义逻辑,如数据库记录、日志等 }; execute_python_with_callback(app, &args, None, progress_callback).await } ``` ### 4. 高级用法(自定义回调) ```rust use crate::python_executor::{execute_python_command_with_progress, ProgressCallback, PythonProgress}; struct CustomProgressHandler { task_id: String, } impl ProgressCallback for CustomProgressHandler { fn on_progress(&self, progress: PythonProgress) { // 自定义进度处理逻辑 println!("Task {}: {}% - {}", self.task_id, progress.progress, progress.message); // 可以发送到数据库、文件、其他服务等 if progress.step == "complete" { println!("Task {} completed!", self.task_id); } } } #[tauri::command] pub async fn my_advanced_command(app: AppHandle, task_id: String) -> Result { let args = vec![ "-m".to_string(), "my_python_module".to_string(), "--task-id".to_string(), task_id.clone(), ]; let progress_handler = CustomProgressHandler { task_id }; execute_python_command_with_progress(app, &args, None, Some(progress_handler)).await } ``` ## Python端实现 Python脚本需要使用JSON-RPC协议发送进度信息: ```python from python_core.utils.jsonrpc import create_response_handler, create_progress_reporter def my_long_running_task(): rpc = create_response_handler("task_id") progress = create_progress_reporter() try: # 报告开始 progress.step("start", "开始处理任务...") # 处理步骤1 progress.report("step1", 25.0, "正在处理步骤1...") # ... 实际处理逻辑 ... # 处理步骤2 progress.report("step2", 50.0, "正在处理步骤2...") # ... 实际处理逻辑 ... # 处理步骤3 progress.report("step3", 75.0, "正在处理步骤3...") # ... 实际处理逻辑 ... # 完成 progress.complete("任务完成!") # 发送最终结果 result = { "status": True, "message": "任务成功完成", "data": {...} } rpc.success(result) except Exception as e: progress.error(f"任务失败: {str(e)}") rpc.error(-32603, "任务执行失败", str(e)) if __name__ == "__main__": my_long_running_task() ``` ## 前端使用 ```typescript import { listen } from '@tauri-apps/api/event' // 监听进度事件 const unlisten = await listen('my-task-progress', (event) => { const progress = event.payload as { step: string progress: number message: string details?: any timestamp: number } console.log(`Progress: ${progress.progress}% - ${progress.message}`) // 更新UI updateProgressBar(progress.progress) updateStatusMessage(progress.message) }) // 执行命令 try { const result = await invoke('my_command_with_progress') console.log('Task completed:', result) } finally { unlisten() // 清理监听器 } ``` ## 进度数据结构 ```rust pub struct PythonProgress { pub step: String, // 当前步骤名称 pub progress: f64, // 进度百分比 (0-100, -1表示不确定) pub message: String, // 进度消息 pub details: Option, // 额外详情 pub timestamp: f64, // 时间戳 } ``` ## 配置选项 ```rust pub struct PythonExecutorConfig { pub timeout_seconds: u64, // 超时时间(秒) pub working_directory: Option, // 工作目录 } // 默认配置:10分钟超时,当前目录 let config = PythonExecutorConfig::default(); // 自定义配置 let config = PythonExecutorConfig { timeout_seconds: 1800, // 30分钟 working_directory: Some("/path/to/workdir".into()), }; ``` ## 最佳实践 1. **选择合适的回调方式**: - 简单任务:使用 `execute_python_command` - 需要前端进度显示:使用 `execute_python_with_events` - 需要自定义处理:使用 `execute_python_with_callback` 2. **Python端进度报告**: - 使用有意义的步骤名称 - 提供清晰的进度消息 - 合理设置进度百分比 - 在关键节点报告进度 3. **错误处理**: - Python端使用try-catch包装 - 通过JSON-RPC发送错误信息 - Rust端处理超时和进程错误 4. **性能考虑**: - 不要过于频繁地报告进度 - 避免在进度回调中执行耗时操作 - 合理设置超时时间