Skip to content

实现多语言编译

python如何实现这么一个功能,可以支持多种语言代码,返回结果,下面举例python url: https://grok.com/rest/app-chat/run-code 参数:{"language":"python","code":"def add(a, b):\n return a + b\n\ndef subtract(a, b):\n return a - b\n\na = 10\nb = 5\nresult = add(a, b)\nprint(f"加法 10 + 5 = {result}")\n"} 结果:{"success":true,"stdout":"加法 10 + 5 = 15\n","stderr":"","outputFiles":

实现方案

要实现类似 https://grok.com/rest/app-chat/run-code 的功能,支持多种语言代码(以 Python 为例)并返回结果,类似于提供一个在线代码运行服务,我们需要在后端搭建一个通用的代码执行引擎,通过 API 接收代码和语言类型,执行代码后返回标准化结果(如 {"success": true, "stdout": ..., "stderr": ..., "outputFiles": {}})。以下是使用 Python(后端框架如 Flask 或 FastAPI)实现的详细方案,并确保支持扩展到多种语言。

实现方案

我们将使用 Python 的 FastAPI 框架(轻量、异步、高性能)作为后端,结合 subprocess 模块运行 Python 代码(也可扩展到其他语言)。前端仍可使用 Vue 3 调用该 API。以下是实现步骤和代码。

1. 后端实现(FastAPI)

创建一个 FastAPI 应用,接收 POST 请求,包含 languagecode 参数,执行代码并返回结果。

安装依赖
bash
pip install fastapi uvicorn
后端代码(main.py
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import subprocess
import tempfile
import os
from fastapi.middleware.cors import CORS

app = FastAPI()

# 允许跨域请求(以便 Vue 前端调用)
app.add_middleware(
    CORS,
    allow_origins=["http://localhost:5173"],  # Vue 默认端口
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 定义请求体模型
class CodeRequest(BaseModel):
    language: str
    code: str

@app.post("/run-code")
async def run_code(request: CodeRequest):
    """
    执行代码并返回结果,格式为 {"success": bool, "stdout": str, "stderr": str, "outputFiles": dict}
    """
    if request.language != "python":
        raise HTTPException(status_code=400, detail="目前仅支持 Python 语言")

    # 创建临时文件来存储代码
    with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as temp_file:
        temp_file.write(request.code.encode('utf-8'))
        temp_file_path = temp_file.name

    result = {
        "success": True,
        "stdout": "",
        "stderr": "",
        "outputFiles": {}
    }

    try:
        # 执行 Python 代码
        process = subprocess.run(
            ["python", temp_file_path],
            capture_output=True,
            text=True,
            timeout=5  # 设置 5 秒超时
        )
        result["stdout"] = process.stdout
        result["stderr"] = process.stderr
        result["success"] = process.returncode == 0
    except subprocess.TimeoutExpired:
        result["success"] = False
        result["stderr"] = "代码执行超时"
    except Exception as e:
        result["success"] = False
        result["stderr"] = str(e)
    finally:
        # 删除临时文件
        os.unlink(temp_file_path)

    return result
运行后端
bash
uvicorn main:app --host 0.0.0.0 --port 8000

后端将在 http://localhost:8000 运行,API 端点为 /run-code

2. Vue 3 前端(调用 API)

修改之前的 PythonRunner.vue,让用户输入代码和选择语言(当前仅支持 Python),调用后端 API 并显示结果。

vue
<template>
  <div>
    <h2>多语言代码执行器</h2>
    <div>
      <label>选择语言:</label>
      <select v-model="language">
        <option value="python">Python</option>
        <!-- 未来可扩展其他语言 -->
      </select>
    </div>
    <div>
      <label>输入代码:</label>
      <textarea v-model="code" placeholder="输入代码" rows="10" cols="50"></textarea>
    </div>
    <button @click="runCode">运行</button>
    <div v-if="output">
      <h3>输出:</h3>
      <pre>{{ output.stdout }}</pre>
    </div>
    <div v-if="output?.stderr" style="color: red;">
      <h3>错误:</h3>
      <pre>{{ output.stderr }}</pre>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import axios from 'axios';

// 默认代码(与问题示例一致)
const language = ref('python');
const code = ref(`def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

a = 10
b = 5
result = add(a, b)
print(f"加法 10 + 5 = {result}")
`);
const output = ref(null);

const runCode = async () => {
  try {
    const response = await axios.post('http://localhost:8000/run-code', {
      language: language.value,
      code: code.value
    });
    output.value = response.data;
  } catch (err) {
    output.value = {
      success: false,
      stdout: '',
      stderr: err.response?.data?.detail || '请求失败',
      outputFiles: {}
    };
  }
};
</script>

<style scoped>
div {
  margin: 10px 0;
}
textarea, select, button {
  padding: 5px;
  margin-left: 10px;
}
pre {
  font-family: monospace;
  background: #f4f4f4;
  padding: 10px;
  border-radius: 5px;
}
</style>

3. 运行项目

  • 确保环境
    • 系统已安装 Python 3.x。
    • 后端安装了 fastapiuvicornpip install fastapi uvicorn)。
    • Vue 项目安装了 axiosnpm install axios)。
  • 启动
    • 后端:uvicorn main:app --host 0.0.0.0 --port 8000
    • Vue 前端:cd vue-project && npm run dev
  • 访问:打开浏览器,访问 Vue 应用(默认 http://localhost:5173)。
  • 测试
    • 输入示例代码(如问题中的加法代码)。
    • 选择语言(当前为 Python)。
    • 点击“运行”,查看结果。

4. 测试示例

  • 请求
    json
    {
      "language": "python",
      "code": "def add(a, b):\n    return a + b\n\ndef subtract(a, b):\n    return a - b\n\na = 10\nb = 5\nresult = add(a, b)\nprint(f\"加法 10 + 5 = {result}\")\n"
    }
  • 响应(在 Vue 前端显示):
    json
    {
      "success": true,
      "stdout": "加法 10 + 5 = 15\n",
      "stderr": "",
      "outputFiles": {}
    }
  • 前端显示
    输出:
    加法 10 + 5 = 15

5. 错误示例

  • 输入代码(包含错误):
    python
    print(undefined_var)
  • 响应
    json
    {
      "success": false,
      "stdout": "",
      "stderr": "NameError: name 'undefined_var' is not defined\n",
      "outputFiles": {}
    }
  • 前端显示(红色错误):
    错误:
    NameError: name 'undefined_var' is not defined

支持多种语言

要扩展支持其他语言(如 JavaScript、C++ 等),需要在后端添加逻辑:

  1. 检测语言:在 run_code 函数中,根据 request.language 选择对应的解释器或编译器(如 node 运行 JavaScript,g++ 编译 C++)。
  2. 执行逻辑
    • JavaScript:用 subprocess.run(["node", "-e", code]) 执行。
    • C++:将代码保存为 .cpp 文件,编译后运行(需安装 g++)。
    • 示例(扩展 run_code):
      python
      if request.language == "javascript":
          process = subprocess.run(
              ["node", "-e", request.code],
              capture_output=True,
              text=True,
              timeout=5
          )
      elif request.language == "python":
          # 已有 Python 逻辑
          ...
      else:
          raise HTTPException(status_code=400, detail="不支持的语言")
  3. 前端更新:在 <select> 中添加更多语言选项(如 <option value="javascript">JavaScript</option>)。

注意事项

  • 安全性
    • 当前代码直接执行用户输入,可能导致安全风险(如运行 os.system("rm -rf /"))。
    • 生产环境中,使用沙箱(如 Docker)隔离代码执行,或限制 Python 功能(用 restrictedpython)。
    • 验证输入代码,避免恶意代码注入。
  • 超时控制:已设置 5 秒超时,防止无限循环。可根据需要调整。
  • 文件输出:当前 outputFiles 为空。若需支持生成文件(如图像),可在 Python 代码中生成文件并返回路径。
  • 依赖:确保系统安装了目标语言的运行时(如 Python、Node.js)。
  • 性能:使用临时文件适合简单场景。高并发场景可考虑进程池或专用执行引擎。

扩展

  • 实时输出:使用 WebSocket 或 Server-Sent Events (SSE) 流式传输 stdout
  • 文件支持:扩展 API 接收输入文件,保存到临时目录,供代码读取。
  • 多语言示例:如果需要具体实现 JavaScript 或 C++ 支持,请提供语言要求,我可以补充代码。

如果需要进一步优化(如添加 WebSocket、支持其他语言、或处理特定错误),请告诉我!

实现意义不大

  1. bash 执行

alt bash执行

  1. ts 语法执行

alt ts执行

Released under the MIT License.