| 109 | } |
| 110 | |
| 111 | func (r *PythonRuntime) Execute(ctx context.Context, code string, input map[string]any) (*ExecutionResult, error) { |
| 112 | start := time.Now() |
| 113 | |
| 114 | // 创建临时文件 |
| 115 | tmpFile, err := os.CreateTemp(r.config.WorkDir, "aster_*.py") |
| 116 | if err != nil { |
| 117 | return nil, fmt.Errorf("create temp file: %w", err) |
| 118 | } |
| 119 | defer func() { _ = os.Remove(tmpFile.Name()) }() |
| 120 | |
| 121 | // 包装代码以处理输入和输出 |
| 122 | wrappedCode := r.wrapCode(code, input) |
| 123 | if _, err := tmpFile.WriteString(wrappedCode); err != nil { |
| 124 | return nil, fmt.Errorf("write code: %w", err) |
| 125 | } |
| 126 | _ = tmpFile.Close() |
| 127 | |
| 128 | // 创建带超时的 context |
| 129 | execCtx, cancel := context.WithTimeout(ctx, r.config.Timeout) |
| 130 | defer cancel() |
| 131 | |
| 132 | // 执行 Python |
| 133 | cmd := exec.CommandContext(execCtx, r.pythonPath, tmpFile.Name()) |
| 134 | cmd.Dir = r.config.WorkDir |
| 135 | |
| 136 | // 设置环境变量 |
| 137 | cmd.Env = os.Environ() |
| 138 | for k, v := range r.config.Env { |
| 139 | cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v)) |
| 140 | } |
| 141 | |
| 142 | var stdout, stderr bytes.Buffer |
| 143 | cmd.Stdout = &stdout |
| 144 | cmd.Stderr = &stderr |
| 145 | |
| 146 | err = cmd.Run() |
| 147 | duration := time.Since(start).Milliseconds() |
| 148 | |
| 149 | result := &ExecutionResult{ |
| 150 | Stdout: truncateOutput(stdout.String(), r.config.MaxOutput), |
| 151 | Stderr: truncateOutput(stderr.String(), r.config.MaxOutput), |
| 152 | Duration: duration, |
| 153 | } |
| 154 | |
| 155 | if err != nil { |
| 156 | if execCtx.Err() == context.DeadlineExceeded { |
| 157 | result.Error = "execution timeout" |
| 158 | result.ExitCode = -1 |
| 159 | } else if exitErr := (&exec.ExitError{}); errors.As(err, &exitErr) { |
| 160 | result.ExitCode = exitErr.ExitCode() |
| 161 | result.Error = stderr.String() |
| 162 | } else { |
| 163 | result.Error = err.Error() |
| 164 | result.ExitCode = -1 |
| 165 | } |
| 166 | return result, nil |
| 167 | } |
| 168 | |