triflix commited on
Commit
7429e74
·
verified ·
1 Parent(s): 8a0a337

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -25
app.py CHANGED
@@ -7,76 +7,75 @@ 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 package to a temporary directory and executes a Python script.
19
-
20
- This endpoint addresses permission errors in restricted environments like
21
- Hugging Face Spaces by:
22
- 1. Creating a temporary directory for the request.
23
- 2. Installing the specified pip package into this temporary directory using `pip install --target`.
24
- 3. Setting the PYTHONPATH environment variable to include this directory.
25
- 4. Executing the provided script, which can now import the installed package.
26
-
27
- The temporary directory and its contents are automatically removed after the
28
- request is complete.
29
  """
30
- # Use a temporary directory that will be automatically cleaned up
31
  with tempfile.TemporaryDirectory() as temp_dir:
32
  pip_output = ""
33
  script_output = ""
34
  error = ""
35
 
36
  try:
37
- # 1. Install the package to the temporary directory
38
  install_path = os.path.join(temp_dir, "packages")
39
  os.makedirs(install_path)
40
 
 
 
 
 
41
  pip_output = subprocess.check_output(
42
  [
43
  sys.executable,
44
  "-m",
45
  "pip",
46
  "install",
47
- request.package_name,
48
  "--target",
49
- install_path, # Install here
50
  ],
51
  stderr=subprocess.STDOUT,
52
  text=True
53
  )
54
 
55
- # 2. Create a temporary file for the user's script
56
  script_path = os.path.join(temp_dir, "script.py")
57
  with open(script_path, 'w') as temp_script:
58
  temp_script.write(request.script_content)
59
 
60
- # 3. Prepare the environment for the script execution
61
- # This ensures the script can find the package in `install_path`
62
  exec_env = os.environ.copy()
63
- # Add the install path to the Python Path
64
  exec_env["PYTHONPATH"] = install_path + os.pathsep + exec_env.get("PYTHONPATH", "")
65
 
66
- # 4. Execute the Python script using the modified environment
67
  script_output = subprocess.check_output(
68
  [sys.executable, script_path],
69
  stderr=subprocess.STDOUT,
70
  text=True,
71
- env=exec_env # Use the modified environment
72
  )
73
 
74
  except subprocess.CalledProcessError as e:
75
- # If any command fails, capture its output as an error
76
  error = e.output
77
 
78
  return {
79
  "pip_install_output": pip_output,
80
  "script_execution_output": script_output,
81
  "error_output": error
82
- }
 
7
 
8
  # Defines the structure of the request body
9
  class ExecutionRequest(BaseModel):
10
+ package_name: str = Field(
11
+ ...,
12
+ example="numpy requests beautifulsoup4",
13
+ description="One or more pip packages to install (space or comma separated)."
14
+ )
15
+ script_content: str = Field(
16
+ ...,
17
+ example="import numpy as np; print(np.array([1, 2, 3]))",
18
+ description="The Python script content to execute."
19
+ )
20
 
21
  app = FastAPI()
22
 
23
  @app.post("/execute/")
24
  def install_and_execute(request: ExecutionRequest):
25
  """
26
+ Installs one or more packages into a temporary directory and executes a Python script.
27
+ Supports multiple packages separated by spaces or commas.
 
 
 
 
 
 
 
 
 
28
  """
 
29
  with tempfile.TemporaryDirectory() as temp_dir:
30
  pip_output = ""
31
  script_output = ""
32
  error = ""
33
 
34
  try:
35
+ # 1. Create the install directory
36
  install_path = os.path.join(temp_dir, "packages")
37
  os.makedirs(install_path)
38
 
39
+ # 2. Split package names by space or comma
40
+ packages = [pkg.strip() for pkg in request.package_name.replace(",", " ").split() if pkg.strip()]
41
+
42
+ # 3. Install the packages to the temporary directory
43
  pip_output = subprocess.check_output(
44
  [
45
  sys.executable,
46
  "-m",
47
  "pip",
48
  "install",
49
+ *packages, # multiple packages supported
50
  "--target",
51
+ install_path,
52
  ],
53
  stderr=subprocess.STDOUT,
54
  text=True
55
  )
56
 
57
+ # 4. Create a temporary script file
58
  script_path = os.path.join(temp_dir, "script.py")
59
  with open(script_path, 'w') as temp_script:
60
  temp_script.write(request.script_content)
61
 
62
+ # 5. Prepare the environment with custom PYTHONPATH
 
63
  exec_env = os.environ.copy()
 
64
  exec_env["PYTHONPATH"] = install_path + os.pathsep + exec_env.get("PYTHONPATH", "")
65
 
66
+ # 6. Execute the Python script
67
  script_output = subprocess.check_output(
68
  [sys.executable, script_path],
69
  stderr=subprocess.STDOUT,
70
  text=True,
71
+ env=exec_env
72
  )
73
 
74
  except subprocess.CalledProcessError as e:
 
75
  error = e.output
76
 
77
  return {
78
  "pip_install_output": pip_output,
79
  "script_execution_output": script_output,
80
  "error_output": error
81
+ }