triflix commited on
Commit
f531709
·
verified ·
1 Parent(s): cc2b540

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -51
app.py CHANGED
@@ -1,66 +1,65 @@
1
- from fastapi import FastAPI, Form
2
  import subprocess
3
  import sys
4
- import tempfile
5
  import os
6
- import importlib.util
7
-
8
- CACHE_DIR = "/tmp/.cache_packages"
9
-
10
- # Ensure the cache dir exists
11
- os.makedirs(CACHE_DIR, exist_ok=True)
12
 
13
- # Add cache dir to Python path
14
- if CACHE_DIR not in sys.path:
15
- sys.path.insert(0, CACHE_DIR)
 
16
 
17
  app = FastAPI()
18
 
19
- def install_package_if_needed(package_name: str):
20
- """Install a package to CACHE_DIR only if not already installed."""
21
- if importlib.util.find_spec(package_name) is None:
22
- subprocess.check_call([
23
- sys.executable, "-m", "pip", "install",
24
- "--target", CACHE_DIR, package_name
25
- ])
26
 
27
- @app.post("/run")
28
- def run_code(code: str = Form(...)):
29
- try:
30
- lines = code.strip().split("\n")
31
-
32
- # Separate pip installs from Python code
33
- pip_commands = [line.strip() for line in lines if line.strip().startswith("pip install")]
34
- python_code_lines = [line for line in lines if not line.strip().startswith("pip install")]
35
-
36
- # Handle pip installs
37
- for cmd in pip_commands:
38
- parts = cmd.split()
39
- for pkg in parts[2:]: # Skip 'pip' and 'install'
40
- try:
41
- install_package_if_needed(pkg)
42
- except subprocess.CalledProcessError as e:
43
- return {"stdout": "", "stderr": f"Error installing: {pkg}\n{str(e)}"}
44
 
45
- # Save Python code to temp file
46
- python_code = "\n".join(python_code_lines)
47
- with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as temp_file:
48
- temp_file.write(python_code.encode())
49
- temp_path = temp_file.name
 
 
50
 
51
- # Run Python code
52
- result = subprocess.run(
53
- [sys.executable, temp_path],
54
- capture_output=True,
 
55
  text=True
56
  )
57
 
58
- os.unlink(temp_path) # Clean up
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- return {
61
- "stdout": result.stdout,
62
- "stderr": result.stderr
63
- }
64
 
65
- except Exception as e:
66
- return {"error": str(e)}
 
 
 
 
 
1
  import subprocess
2
  import sys
 
3
  import os
4
+ import tempfile
5
+ from fastapi import FastAPI
6
+ from pydantic import BaseModel, Field
 
 
 
7
 
8
+ # Defines the structure of the request body
9
+ class ExecutionRequest(BaseModel):
10
+ package_name: str = Field(..., example="numpy", description="The name of the pip package to install.")
11
+ script_content: str = Field(..., example="import numpy as np; print(np.array([1, 2, 3]))", description="The Python script content to execute.")
12
 
13
  app = FastAPI()
14
 
15
+ @app.post("/execute/")
16
+ def install_and_execute(request: ExecutionRequest):
17
+ """
18
+ Installs a specified pip package and then executes a provided Python script.
 
 
 
19
 
20
+ This endpoint first uses pip to install the package named in the `package_name`
21
+ field. It then writes the `script_content` to a temporary file and
22
+ executes it using the same Python interpreter that is running the FastAPI
23
+ application.
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ The output from both the pip installation and the script execution is
26
+ captured and returned in the JSON response. Any errors during the process
27
+ are also captured and returned.
28
+ """
29
+ pip_output = ""
30
+ script_output = ""
31
+ error = ""
32
 
33
+ try:
34
+ # Execute the pip install command
35
+ pip_output = subprocess.check_output(
36
+ [sys.executable, "-m", "pip", "install", request.package_name],
37
+ stderr=subprocess.STDOUT,
38
  text=True
39
  )
40
 
41
+ # Create a temporary file with a .py extension to save the script content
42
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".py", mode='w') as temp_script:
43
+ temp_script.write(request.script_content)
44
+ temp_script_path = temp_script.name
45
+
46
+ try:
47
+ # Execute the Python script
48
+ script_output = subprocess.check_output(
49
+ [sys.executable, temp_script_path],
50
+ stderr=subprocess.STDOUT,
51
+ text=True
52
+ )
53
+ finally:
54
+ # Clean up the temporary file
55
+ os.remove(temp_script_path)
56
 
57
+ except subprocess.CalledProcessError as e:
58
+ # If any command fails, capture the output as an error
59
+ error = e.output
 
60
 
61
+ return {
62
+ "pip_install_output": pip_output,
63
+ "script_execution_output": script_output,
64
+ "error_output": error
65
+ }