Run JavaScript code from Python with automatic runtime selection
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Management of JavaScript runtime environments and automatic runtime selection.
PyExecJS supports multiple JavaScript runtime engines and automatically selects the best available one. You can also manually specify which runtime to use or register custom runtime implementations.
Get a JavaScript runtime instance by name or automatically select the best available one.
def get(name=None):
"""
Get a JavaScript runtime by name or automatically select one.
Args:
name (str, optional): Name of specific runtime to get. If None, automatically selects best available runtime.
Returns:
AbstractRuntime: JavaScript runtime instance
Raises:
RuntimeUnavailableError: When specified runtime is not available or no runtimes are available
"""Get a dictionary of all supported JavaScript runtimes.
def runtimes():
"""
Return dictionary of all supported JavaScript runtimes.
Returns:
OrderedDict: Ordered dictionary mapping runtime names to runtime instances
"""Get the runtime specified by the EXECJS_RUNTIME environment variable.
def get_from_environment():
"""
Get runtime specified by EXECJS_RUNTIME environment variable.
Returns:
AbstractRuntime or None: Runtime instance specified by environment variable, or None if unavailable
"""Register a new JavaScript runtime implementation.
def register(name, runtime):
"""
Register a new JavaScript runtime.
Args:
name (str): Name to register the runtime under
runtime (AbstractRuntime): Runtime implementation instance
"""Use these constants to specify specific runtime engines:
import execjs.runtime_names as runtime_names
# First-class supported runtimes (tested)
runtime_names.PyV8 # "PyV8" - Google V8 engine wrapper
runtime_names.Node # "Node" - Node.js runtime
runtime_names.PhantomJS # "PhantomJS" - Headless WebKit browser
runtime_names.Nashorn # "Nashorn" - Java 8 JavaScript engine
# Second-class supported runtimes (provided but not tested)
runtime_names.JavaScriptCore # "JavaScriptCore" - Apple's JavaScript engine (Mac OS X)
runtime_names.JScript # "JScript" - Microsoft Windows Script Host
runtime_names.SlimerJS # "SlimerJS" - Gecko-based browser engine
runtime_names.SpiderMonkey # "SpiderMonkey" - Mozilla JavaScript engineimport execjs
# Get best available runtime automatically
runtime = execjs.get()
print(runtime.name) # e.g., "Node" or "PyV8"
# Use the runtime directly
result = runtime.eval("2 + 2") # 4import execjs
from execjs import runtime_names
# Get specific runtime
try:
node_runtime = execjs.get(runtime_names.Node)
result = node_runtime.eval("process.version")
print(f"Node.js version: {result}")
except execjs.RuntimeUnavailableError:
print("Node.js not available")
# Try multiple runtimes in preference order
preferred_runtimes = [runtime_names.Node, runtime_names.PyV8, runtime_names.PhantomJS]
runtime = None
for runtime_name in preferred_runtimes:
try:
runtime = execjs.get(runtime_name)
print(f"Using runtime: {runtime.name}")
break
except execjs.RuntimeUnavailableError:
continue
if runtime is None:
print("No preferred runtime available")import os
import execjs
# Set environment variable to specify default runtime
os.environ['EXECJS_RUNTIME'] = 'Node'
# Get runtime from environment
runtime = execjs.get_from_environment()
print(runtime.name) # "Node"
# This also affects the default behavior of execjs.eval(), execjs.exec_(), etc.
result = execjs.eval("2 + 2") # Will use Node.js runtimeimport execjs
# Get all runtime instances
all_runtimes = execjs.runtimes()
print("All runtimes:", list(all_runtimes.keys()))
# Check which runtimes are actually available
available_runtimes = []
for name, runtime in all_runtimes.items():
if runtime.is_available():
available_runtimes.append(name)
print("Available runtimes:", available_runtimes)Base class for all JavaScript runtime implementations.
class AbstractRuntime:
"""Abstract base class for runtime implementations."""
def eval(self, source, cwd=None):
"""
Evaluate source in JavaScript runtime.
Args:
source (str): JavaScript source code to evaluate
cwd (str, optional): Working directory for execution
Returns:
any: Result of JavaScript evaluation
"""
def exec_(self, source, cwd=None):
"""
Execute source and return stdout output.
Args:
source (str): JavaScript source code to execute
cwd (str, optional): Working directory for execution
Returns:
str: Standard output from JavaScript execution
"""
def compile(self, source, cwd=None):
"""
Compile source as a context object.
Args:
source (str): JavaScript source code to compile
cwd (str, optional): Working directory for compilation
Returns:
Context object: Compiled JavaScript execution context
"""
def is_available(self):
"""
Check if runtime is available on the system.
Returns:
bool: True if runtime is available, False otherwise
"""Runtime implementation for executing JavaScript via external commands.
class ExternalRuntime(AbstractRuntime):
"""Runtime class for executing JavaScript via external commands."""
@property
def name(self):
"""
Name of the runtime.
Returns:
str: Runtime name
"""
def is_available(self):
"""
Check if external runtime is available.
Returns:
bool: True if external runtime command is available, False otherwise
"""import execjs
# Create custom runtime (hypothetical example)
# AbstractRuntime must be imported from the internal module
from execjs._abstract_runtime import AbstractRuntime
class CustomRuntime(AbstractRuntime):
def __init__(self):
self.name = "CustomJS"
def is_available(self):
# Check if custom runtime is available
return True
def eval(self, source, cwd=None):
# Custom evaluation logic
pass
# Register the custom runtime
custom_runtime = CustomRuntime()
execjs.register("CustomJS", custom_runtime)
# Now it's available
runtime = execjs.get("CustomJS")PyExecJS automatically selects runtimes in this priority order:
The first available runtime in this order is selected automatically.
Install with Tessl CLI
npx tessl i tessl/pypi-pyexecjs