|
|
import subprocess |
|
|
import sys |
|
|
import os |
|
|
import tempfile |
|
|
from fastapi import FastAPI |
|
|
from pydantic import BaseModel, Field |
|
|
|
|
|
|
|
|
class ExecutionRequest(BaseModel): |
|
|
package_name: str = Field( |
|
|
..., |
|
|
example="numpy requests beautifulsoup4", |
|
|
description="One or more pip packages to install (space or comma separated)." |
|
|
) |
|
|
script_content: str = Field( |
|
|
..., |
|
|
example="import numpy as np; print(np.array([1, 2, 3]))", |
|
|
description="The Python script content to execute." |
|
|
) |
|
|
|
|
|
app = FastAPI() |
|
|
|
|
|
@app.post("/execute/") |
|
|
def install_and_execute(request: ExecutionRequest): |
|
|
""" |
|
|
Installs one or more packages into a temporary directory and executes a Python script. |
|
|
Supports multiple packages separated by spaces or commas. |
|
|
""" |
|
|
with tempfile.TemporaryDirectory() as temp_dir: |
|
|
pip_output = "" |
|
|
script_output = "" |
|
|
error = "" |
|
|
|
|
|
try: |
|
|
|
|
|
install_path = os.path.join(temp_dir, "packages") |
|
|
os.makedirs(install_path) |
|
|
|
|
|
|
|
|
packages = [pkg.strip() for pkg in request.package_name.replace(",", " ").split() if pkg.strip()] |
|
|
|
|
|
|
|
|
pip_output = subprocess.check_output( |
|
|
[ |
|
|
sys.executable, |
|
|
"-m", |
|
|
"pip", |
|
|
"install", |
|
|
*packages, |
|
|
"--target", |
|
|
install_path, |
|
|
], |
|
|
stderr=subprocess.STDOUT, |
|
|
text=True |
|
|
) |
|
|
|
|
|
|
|
|
script_path = os.path.join(temp_dir, "script.py") |
|
|
with open(script_path, 'w') as temp_script: |
|
|
temp_script.write(request.script_content) |
|
|
|
|
|
|
|
|
exec_env = os.environ.copy() |
|
|
exec_env["PYTHONPATH"] = install_path + os.pathsep + exec_env.get("PYTHONPATH", "") |
|
|
|
|
|
|
|
|
script_output = subprocess.check_output( |
|
|
[sys.executable, script_path], |
|
|
stderr=subprocess.STDOUT, |
|
|
text=True, |
|
|
env=exec_env |
|
|
) |
|
|
|
|
|
except subprocess.CalledProcessError as e: |
|
|
error = e.output |
|
|
|
|
|
return { |
|
|
"pip_install_output": pip_output, |
|
|
"script_execution_output": script_output, |
|
|
"error_output": error |
|
|
} |
|
|
|