Coverage for aipyapp/exec/prun.py: 51%
45 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 12:02 +0200
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-11 12:02 +0200
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
4""" subprocess-based bash/powershell code execution """
6import traceback
7import subprocess
8from typing import Any, Dict, Optional
10from loguru import logger
12class SubprocessExecutor:
13 """使用 subprocess 执行代码块"""
14 name = None
15 command = None
16 timeout = 30 # 默认超时时间为10秒
18 def __init__(self, runtime=None):
19 self.runtime = runtime
20 self.log = logger.bind(src=f'{self.name}_executor')
22 def get_cmd(self, block) -> Optional[str]:
23 """获取执行命令"""
24 path = block.abs_path
25 if path:
26 cmd = self.command.copy()
27 cmd.append(str(path))
28 else:
29 cmd = None
30 return cmd
32 def __call__(self, block) -> Dict[str, Any]:
33 """执行代码块"""
34 cmd = self.get_cmd(block)
35 if not cmd:
36 return {'errstr': 'No file to execute'}
38 self.log.info(f"Exec: {cmd}")
40 try:
41 cp = subprocess.run(
42 cmd,
43 shell=False,
44 capture_output=True,
45 text=True,
46 encoding="utf-8",
47 errors="ignore",
48 timeout=self.timeout
49 )
50 stdout = cp.stdout.strip() if cp.stdout else None
51 stderr = cp.stderr.strip() if cp.stderr else None
53 result = {
54 'stdout': stdout,
55 'stderr': stderr,
56 'returncode': cp.returncode
57 }
58 except subprocess.TimeoutExpired:
59 result = {'errstr': f'Execution timed out after {self.timeout} seconds'}
60 except Exception as e:
61 result = {'errstr': str(e), 'traceback': str(traceback.format_exc())}
63 return result
65class BashExecutor(SubprocessExecutor):
66 name = 'bash'
67 command = ['bash']
69class PowerShellExecutor(SubprocessExecutor):
70 name = 'powershell'
71 command = ['powershell', '-Command']
73class AppleScriptExecutor(SubprocessExecutor):
74 name = 'applescript'
75 command = ['osascript']
77class NodeExecutor(SubprocessExecutor):
78 name = 'javascript'
79 command = ['node']