0
# Code Execution
1
2
Execute Python code from JavaScript with full control over execution context, globals, and async/await support.
3
4
## Synchronous Execution
5
6
### runPython
7
8
Execute Python code synchronously and return the result of the last expression.
9
10
```javascript { .api }
11
function runPython(
12
code: string,
13
options?: {
14
globals?: PyProxy;
15
locals?: PyProxy;
16
filename?: string;
17
}
18
): any;
19
```
20
21
**Parameters:**
22
- `code` - Python code string to execute
23
- `options.globals` - Python dictionary to use as global namespace (default: pyodide.globals)
24
- `options.locals` - Python dictionary to use as local namespace (default: same as globals)
25
- `options.filename` - Filename for traceback display (default: "<exec>")
26
27
**Returns:** Result of the last expression, converted to JavaScript
28
29
## Asynchronous Execution
30
31
### runPythonAsync
32
33
Execute Python code with top-level async/await support.
34
35
```javascript { .api }
36
function runPythonAsync(
37
code: string,
38
options?: {
39
globals?: PyProxy;
40
locals?: PyProxy;
41
filename?: string;
42
}
43
): Promise<any>;
44
```
45
46
**Parameters:** Same as `runPython`
47
48
**Returns:** Promise resolving to the result of the last expression
49
50
## Usage Examples
51
52
### Basic Code Execution
53
54
```javascript
55
// Simple expression
56
const result = pyodide.runPython("2 + 3");
57
console.log(result); // 5
58
59
// Multiple statements
60
pyodide.runPython(`
61
import math
62
x = 10
63
y = math.sqrt(x)
64
print(f"Square root of {x} is {y}")
65
`);
66
```
67
68
### Working with Variables
69
70
```javascript
71
// Set variables from JavaScript
72
pyodide.globals.set("js_value", 42);
73
74
const result = pyodide.runPython(`
75
python_value = js_value * 2
76
python_value # This becomes the return value
77
`);
78
79
console.log(result); // 84
80
81
// Get variables back to JavaScript
82
const pythonVar = pyodide.globals.get("python_value");
83
console.log(pythonVar); // 84
84
```
85
86
### Custom Globals and Locals
87
88
```javascript
89
// Create custom execution context
90
const customGlobals = pyodide.toPy({
91
myFunction: (x) => x * 2,
92
myData: [1, 2, 3, 4, 5]
93
});
94
95
const result = pyodide.runPython(`
96
# Use custom globals
97
processed = [myFunction(x) for x in myData]
98
sum(processed)
99
`, { globals: customGlobals });
100
101
console.log(result); // 30
102
```
103
104
### File Context for Debugging
105
106
```javascript
107
const result = pyodide.runPython(`
108
def divide(a, b):
109
return a / b
110
111
divide(10, 0) # This will cause an error
112
`, { filename: "my_script.py" });
113
114
// Error traceback will show "my_script.py" as the filename
115
```
116
117
### Async/Await Support
118
119
```javascript
120
// Top-level await in Python
121
const result = await pyodide.runPythonAsync(`
122
import asyncio
123
124
async def fetch_data():
125
await asyncio.sleep(0.1)
126
return {"message": "Hello from async Python!"}
127
128
data = await fetch_data()
129
data
130
`);
131
132
console.log(result); // { message: "Hello from async Python!" }
133
```
134
135
### JavaScript Integration with Async
136
137
```javascript
138
// Register async JavaScript function
139
pyodide.globals.set("fetchData", async (url) => {
140
const response = await fetch(url);
141
return await response.json();
142
});
143
144
const result = await pyodide.runPythonAsync(`
145
# Call async JavaScript function from Python
146
from js import fetchData
147
data = await fetchData("https://api.example.com/data")
148
data
149
`);
150
```
151
152
### Error Handling
153
154
```javascript
155
try {
156
pyodide.runPython(`
157
undefined_variable # This will raise NameError
158
`);
159
} catch (error) {
160
console.error("Python error:", error.message);
161
// Error includes Python traceback
162
}
163
164
// Async error handling
165
try {
166
await pyodide.runPythonAsync(`
167
async def failing_function():
168
raise ValueError("Something went wrong")
169
170
await failing_function()
171
`);
172
} catch (error) {
173
console.error("Async Python error:", error.message);
174
}
175
```
176
177
### Working with Different Data Types
178
179
```javascript
180
// Return various Python types
181
const results = {
182
number: pyodide.runPython("42"),
183
string: pyodide.runPython("'Hello World'"),
184
list: pyodide.runPython("[1, 2, 3, 4, 5]"),
185
dict: pyodide.runPython("{'key': 'value', 'number': 123}"),
186
none: pyodide.runPython("None"),
187
boolean: pyodide.runPython("True")
188
};
189
190
console.log(results);
191
// {
192
// number: 42,
193
// string: "Hello World",
194
// list: [1, 2, 3, 4, 5],
195
// dict: {key: "value", number: 123},
196
// none: null,
197
// boolean: true
198
// }
199
```
200
201
### Complex Objects and PyProxy
202
203
```javascript
204
// Return complex Python objects
205
const pandas_df = pyodide.runPython(`
206
import pandas as pd
207
pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
208
`);
209
210
// pandas_df is a PyProxy object
211
console.log(pandas_df.toString()); // String representation
212
console.log(pandas_df.shape); // [3, 2]
213
214
// Call methods on PyProxy
215
const sum_result = pandas_df.sum();
216
console.log(sum_result.toJs()); // Convert to JavaScript object
217
```
218
219
### Execution Context Isolation
220
221
```javascript
222
// Create isolated execution context
223
const isolatedGlobals = pyodide.toPy({});
224
const isolatedLocals = pyodide.toPy({});
225
226
pyodide.runPython(`
227
secret_value = "this won't leak"
228
def private_function():
229
return "private"
230
`, {
231
globals: isolatedGlobals,
232
locals: isolatedLocals
233
});
234
235
// secret_value is not in main globals
236
console.log(pyodide.globals.has("secret_value")); // false
237
238
// But available in isolated context
239
console.log(isolatedGlobals.get("secret_value")); // "this won't leak"
240
```
241
242
### Multi-line Code with Proper Indentation
243
244
```javascript
245
const result = pyodide.runPython(`
246
class Calculator:
247
def __init__(self):
248
self.history = []
249
250
def add(self, a, b):
251
result = a + b
252
self.history.append(f"{a} + {b} = {result}")
253
return result
254
255
def get_history(self):
256
return self.history
257
258
calc = Calculator()
259
calc.add(5, 3)
260
calc.add(10, 7)
261
calc.get_history()
262
`);
263
264
console.log(result); // ["5 + 3 = 8", "10 + 7 = 17"]
265
```
266
267
## Expression vs Statement Handling
268
269
```javascript
270
// Expression (returns value)
271
const expr_result = pyodide.runPython("2 + 3");
272
console.log(expr_result); // 5
273
274
// Statement (returns undefined)
275
const stmt_result = pyodide.runPython("x = 2 + 3");
276
console.log(stmt_result); // undefined
277
278
// Mixed (returns last expression)
279
const mixed_result = pyodide.runPython(`
280
x = 10
281
y = 20
282
x + y # This expression is returned
283
`);
284
console.log(mixed_result); // 30
285
286
// Suppress return with semicolon
287
const suppressed = pyodide.runPython("2 + 3;");
288
console.log(suppressed); // undefined
289
```