ASPPY.ExecutePython

Run real CPython code directly from your Classic ASP / VBScript pages and get a string result back. This bridges the gap between your legacy VBScript web application and the full Python ecosystem — psutil, numpy, pandas, requests, Pillow, or any other package installed in your Python environment.

Security: This feature is disabled by default. You must explicitly enable it by setting the ASP_PY_ALLOW_PYTHON=1 environment variable before starting the server. Without it, any call to ASPPY.ExecutePython raises an error.

How It Works

Each call to ASPPY.ExecutePython spawns an isolated subprocess running the same Python interpreter that hosts ASPPY. Your VBScript code sends a Python source string to execute, and the Python snippet uses ASPPY_RETURN(value) to send a string result back to VBScript.

The flow is:

  1. VBScript calls ASPPY.ExecutePython(pyCode).
  2. ASPPY wraps the code with a runtime prelude that defines ASPPY_RETURN.
  3. A fresh python subprocess runs the combined script.
  4. The first ASPPY_RETURN(value) writes the payload to stdout and halts execution.
  5. ASPPY captures the payload and returns it as a VBScript string.

Methods

Method Description
ASPPY.ExecutePython(code) Execute inline Python source. The code parameter is a VBScript string containing valid Python. Returns the value passed to ASPPY_RETURN as a string, or "" if ASPPY_RETURN is never called.
ASPPY.ExecutePythonFile(path) Execute a .py file. Relative paths resolve against the web root (docroot). The file must be inside the ASP_PY_PYTHON_ROOT sandbox. Uses the same ASPPY_RETURN convention.

The ASPPY_RETURN Convention

Inside every Python snippet or file, use the built-in ASPPY_RETURN(value) function to return a string to VBScript:

import json

# Do some computation
data = {"status": "ok", "count": 42}

# Return the result as a JSON string
ASPPY_RETURN(json.dumps(data))

Environment Variables

Variable Default Description
ASP_PY_ALLOW_PYTHON (disabled) Set to 1 to enable ASPPY.ExecutePython. Without this, calls raise an error.
ASP_PY_PYTHON_TIMEOUT 30 Maximum seconds a Python snippet may run before it is killed and an error is returned.
ASP_PY_PYTHON_ROOT (docroot) Sandbox root for ExecutePythonFile. Files outside this path are rejected.

Sample: Inline Python

Embed Python directly in your ASP page. Use VBScript string concatenation (& and & vbCrLf) to build multi-line Python source:

<%
Dim pyCode, result

pyCode = "import platform" & vbCrLf & _
         "ASPPY_RETURN(f'Python {platform.python_version()} on {platform.system()}')"

result = ASPPY.ExecutePython(pyCode)
Response.Write("System: " & result)
%>

Sample: ExecutePythonFile

Place your Python code in a .py file under the web root and call it by relative path:

# www/scripts/status.py
import psutil, json

cpu = psutil.cpu_percent(interval=1)
mem = psutil.virtual_memory()

ASPPY_RETURN(json.dumps({
    "cpu_percent": cpu,
    "memory_used_gb": round(mem.used / (1024**3), 1),
    "memory_total_gb": round(mem.total / (1024**3), 1)
}))
<%
Dim jsonStr, stats
jsonStr = ASPPY.ExecutePythonFile("scripts/status.py")
Set stats = ASPPY.json.Decode(jsonStr)

Response.Write "CPU: " & stats("cpu_percent") & "%<br>"
Response.Write "RAM: " & stats("memory_used_gb") & " / " & stats("memory_total_gb") & " GB"
%>

Sample: Full Page — Python Processes

A complete working example that lists all running Python processes, sorted by memory usage:

<%@ Language="VBScript" %>
<%
Dim pyCode, jsonResult, procs

pyCode = _
    "import json, psutil"                                              & vbCrLf & _
    "rows = []"                                                        & vbCrLf & _
    "for p in psutil.process_iter(['pid', 'name', 'username', 'memory_info']):" & vbCrLf & _
    "    try:"                                                         & vbCrLf & _
    "        name = (p.info.get('name') or '')"                        & vbCrLf & _
    "        if 'python' in name.lower():"                             & vbCrLf & _
    "            mem = p.info.get('memory_info')"                      & vbCrLf & _
    "            mb = round(mem.rss / (1024 * 1024), 1) if mem else 0" & vbCrLf & _
    "            rows.append({"                                        & vbCrLf & _
    "                'pid': p.info.get('pid'),"                        & vbCrLf & _
    "                'name': name,"                                    & vbCrLf & _
    "                'user': p.info.get('username') or '',"           & vbCrLf & _
    "                'mem_mb': mb"                                     & vbCrLf & _
    "            })"                                                   & vbCrLf & _
    "    except (psutil.NoSuchProcess, psutil.AccessDenied):"          & vbCrLf & _
    "        continue"                                                 & vbCrLf & _
    "rows.sort(key=lambda r: r['mem_mb'], reverse=True)"               & vbCrLf & _
    "ASPPY_RETURN(json.dumps(rows))"

On Error Resume Next
jsonResult = ASPPY.ExecutePython(pyCode)

If Err.Number <> 0 Then
    Response.Write "<p style='color:#b00'>Error: " & _
        Server.HTMLEncode(Err.Description) & "</p>"
    Err.Clear
    Response.End
End If
On Error Goto 0

procs = ASPPY.json.Decode(jsonResult)
%>
<table>
    <tr><th>PID</th><th>Name</th><th>User</th><th>Memory (MB)</th></tr>
<%
Dim i, proc
For i = 0 To UBound(procs)
    Set proc = procs(i)
    Response.Write "<tr><td>" & proc("pid") & "</td><td>" & _
        proc("name") & "</td><td>" & proc("user") & _
        "</td><td>" & proc("mem_mb") & "</td></tr>"
Next
%>
</table>

Error Handling

Wrap ASPPY.ExecutePython calls in On Error Resume Next to handle failures gracefully. Common errors include:

<%
On Error Resume Next
Dim result
result = ASPPY.ExecutePython("ASPPY_RETURN('hello')")

If Err.Number <> 0 Then
    Response.Write "Python error: " & Server.HTMLEncode(Err.Description)
    Err.Clear
Else
    Response.Write "Result: " & result
End If
On Error Goto 0
%>

Setting Up Under NSSM

If you run ASPPY as a Windows service via NSSM, set the environment variable in the service configuration:

nssm set YourServiceName AppEnvironmentExtra ASP_PY_ALLOW_PYTHON=1
nssm restart YourServiceName
Do not type set ASP_PY_ALLOW_PYTHON=1 in the NSSM Environment box. The set prefix is a CMD command, not part of the variable. NSSM expects raw NAME=VALUE lines.

Why Use This?

Use cases for running Python from ASP:
  • System monitoring — list processes, check disk usage, query hardware via psutil
  • Data processing — run pandas, numpy, or scipy computations and return results
  • Machine learning — call scikit-learn, TensorFlow, or PyTorch for inference
  • Report generation — create charts with matplotlib, PDFs with reportlab
  • API integrations — use requests to call external REST APIs with full SSL/TLS support
  • Image processing — manipulate images with Pillow or OpenCV
  • Service management — manage Windows services via subprocess (see the Sample Apps)
  • Legacy modernization — incrementally rewrite VBScript logic in Python without a full rewrite