0
# Runtime Management
1
2
Management of JavaScript runtime environments and automatic runtime selection.
3
4
## Overview
5
6
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.
7
8
## Runtime Selection Functions
9
10
### get()
11
12
Get a JavaScript runtime instance by name or automatically select the best available one.
13
14
```python { .api }
15
def get(name=None):
16
"""
17
Get a JavaScript runtime by name or automatically select one.
18
19
Args:
20
name (str, optional): Name of specific runtime to get. If None, automatically selects best available runtime.
21
22
Returns:
23
AbstractRuntime: JavaScript runtime instance
24
25
Raises:
26
RuntimeUnavailableError: When specified runtime is not available or no runtimes are available
27
"""
28
```
29
30
### runtimes()
31
32
Get a dictionary of all supported JavaScript runtimes.
33
34
```python { .api }
35
def runtimes():
36
"""
37
Return dictionary of all supported JavaScript runtimes.
38
39
Returns:
40
OrderedDict: Ordered dictionary mapping runtime names to runtime instances
41
"""
42
```
43
44
### get_from_environment()
45
46
Get the runtime specified by the EXECJS_RUNTIME environment variable.
47
48
```python { .api }
49
def get_from_environment():
50
"""
51
Get runtime specified by EXECJS_RUNTIME environment variable.
52
53
Returns:
54
AbstractRuntime or None: Runtime instance specified by environment variable, or None if unavailable
55
"""
56
```
57
58
### register()
59
60
Register a new JavaScript runtime implementation.
61
62
```python { .api }
63
def register(name, runtime):
64
"""
65
Register a new JavaScript runtime.
66
67
Args:
68
name (str): Name to register the runtime under
69
runtime (AbstractRuntime): Runtime implementation instance
70
"""
71
```
72
73
## Runtime Names
74
75
Use these constants to specify specific runtime engines:
76
77
```python { .api }
78
import execjs.runtime_names as runtime_names
79
80
# First-class supported runtimes (tested)
81
runtime_names.PyV8 # "PyV8" - Google V8 engine wrapper
82
runtime_names.Node # "Node" - Node.js runtime
83
runtime_names.PhantomJS # "PhantomJS" - Headless WebKit browser
84
runtime_names.Nashorn # "Nashorn" - Java 8 JavaScript engine
85
86
# Second-class supported runtimes (provided but not tested)
87
runtime_names.JavaScriptCore # "JavaScriptCore" - Apple's JavaScript engine (Mac OS X)
88
runtime_names.JScript # "JScript" - Microsoft Windows Script Host
89
runtime_names.SlimerJS # "SlimerJS" - Gecko-based browser engine
90
runtime_names.SpiderMonkey # "SpiderMonkey" - Mozilla JavaScript engine
91
```
92
93
## Usage Examples
94
95
### Automatic Runtime Selection
96
97
```python
98
import execjs
99
100
# Get best available runtime automatically
101
runtime = execjs.get()
102
print(runtime.name) # e.g., "Node" or "PyV8"
103
104
# Use the runtime directly
105
result = runtime.eval("2 + 2") # 4
106
```
107
108
### Manual Runtime Selection
109
110
```python
111
import execjs
112
from execjs import runtime_names
113
114
# Get specific runtime
115
try:
116
node_runtime = execjs.get(runtime_names.Node)
117
result = node_runtime.eval("process.version")
118
print(f"Node.js version: {result}")
119
except execjs.RuntimeUnavailableError:
120
print("Node.js not available")
121
122
# Try multiple runtimes in preference order
123
preferred_runtimes = [runtime_names.Node, runtime_names.PyV8, runtime_names.PhantomJS]
124
125
runtime = None
126
for runtime_name in preferred_runtimes:
127
try:
128
runtime = execjs.get(runtime_name)
129
print(f"Using runtime: {runtime.name}")
130
break
131
except execjs.RuntimeUnavailableError:
132
continue
133
134
if runtime is None:
135
print("No preferred runtime available")
136
```
137
138
### Environment Variable Configuration
139
140
```python
141
import os
142
import execjs
143
144
# Set environment variable to specify default runtime
145
os.environ['EXECJS_RUNTIME'] = 'Node'
146
147
# Get runtime from environment
148
runtime = execjs.get_from_environment()
149
print(runtime.name) # "Node"
150
151
# This also affects the default behavior of execjs.eval(), execjs.exec_(), etc.
152
result = execjs.eval("2 + 2") # Will use Node.js runtime
153
```
154
155
### Listing Available Runtimes
156
157
```python
158
import execjs
159
160
# Get all runtime instances
161
all_runtimes = execjs.runtimes()
162
print("All runtimes:", list(all_runtimes.keys()))
163
164
# Check which runtimes are actually available
165
available_runtimes = []
166
for name, runtime in all_runtimes.items():
167
if runtime.is_available():
168
available_runtimes.append(name)
169
170
print("Available runtimes:", available_runtimes)
171
```
172
173
## Runtime Classes
174
175
### AbstractRuntime
176
177
Base class for all JavaScript runtime implementations.
178
179
```python { .api }
180
class AbstractRuntime:
181
"""Abstract base class for runtime implementations."""
182
183
def eval(self, source, cwd=None):
184
"""
185
Evaluate source in JavaScript runtime.
186
187
Args:
188
source (str): JavaScript source code to evaluate
189
cwd (str, optional): Working directory for execution
190
191
Returns:
192
any: Result of JavaScript evaluation
193
"""
194
195
def exec_(self, source, cwd=None):
196
"""
197
Execute source and return stdout output.
198
199
Args:
200
source (str): JavaScript source code to execute
201
cwd (str, optional): Working directory for execution
202
203
Returns:
204
str: Standard output from JavaScript execution
205
"""
206
207
def compile(self, source, cwd=None):
208
"""
209
Compile source as a context object.
210
211
Args:
212
source (str): JavaScript source code to compile
213
cwd (str, optional): Working directory for compilation
214
215
Returns:
216
Context object: Compiled JavaScript execution context
217
"""
218
219
def is_available(self):
220
"""
221
Check if runtime is available on the system.
222
223
Returns:
224
bool: True if runtime is available, False otherwise
225
"""
226
```
227
228
### ExternalRuntime
229
230
Runtime implementation for executing JavaScript via external commands.
231
232
```python { .api }
233
class ExternalRuntime(AbstractRuntime):
234
"""Runtime class for executing JavaScript via external commands."""
235
236
@property
237
def name(self):
238
"""
239
Name of the runtime.
240
241
Returns:
242
str: Runtime name
243
"""
244
245
def is_available(self):
246
"""
247
Check if external runtime is available.
248
249
Returns:
250
bool: True if external runtime command is available, False otherwise
251
"""
252
```
253
254
## Custom Runtime Registration
255
256
```python
257
import execjs
258
259
# Create custom runtime (hypothetical example)
260
# AbstractRuntime must be imported from the internal module
261
from execjs._abstract_runtime import AbstractRuntime
262
263
class CustomRuntime(AbstractRuntime):
264
def __init__(self):
265
self.name = "CustomJS"
266
267
def is_available(self):
268
# Check if custom runtime is available
269
return True
270
271
def eval(self, source, cwd=None):
272
# Custom evaluation logic
273
pass
274
275
# Register the custom runtime
276
custom_runtime = CustomRuntime()
277
execjs.register("CustomJS", custom_runtime)
278
279
# Now it's available
280
runtime = execjs.get("CustomJS")
281
```
282
283
## Runtime Priority and Selection
284
285
PyExecJS automatically selects runtimes in this priority order:
286
287
1. **PyV8** - Fastest, requires PyV8 package
288
2. **Node** - Fast, requires Node.js installation
289
3. **PhantomJS** - Good compatibility, requires PhantomJS
290
4. **Nashorn** - Java-based, requires Java 8+
291
5. **JavaScriptCore** - Mac OS X only
292
6. **JScript** - Windows only
293
7. **SlimerJS** - Requires SlimerJS installation
294
8. **SpiderMonkey** - Requires SpiderMonkey installation
295
296
The first available runtime in this order is selected automatically.