CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pyodide

Python distribution for the browser and Node.js based on WebAssembly that enables running Python code with full JavaScript interoperability

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

code-execution.mddocs/

Code Execution

Execute Python code from JavaScript with full control over execution context, globals, and async/await support.

Synchronous Execution

runPython

Execute Python code synchronously and return the result of the last expression.

function runPython(
  code: string,
  options?: {
    globals?: PyProxy;
    locals?: PyProxy;
    filename?: string;
  }
): any;

Parameters:

  • code - Python code string to execute
  • options.globals - Python dictionary to use as global namespace (default: pyodide.globals)
  • options.locals - Python dictionary to use as local namespace (default: same as globals)
  • options.filename - Filename for traceback display (default: "<exec>")

Returns: Result of the last expression, converted to JavaScript

Asynchronous Execution

runPythonAsync

Execute Python code with top-level async/await support.

function runPythonAsync(
  code: string,
  options?: {
    globals?: PyProxy;
    locals?: PyProxy;
    filename?: string;
  }
): Promise<any>;

Parameters: Same as runPython

Returns: Promise resolving to the result of the last expression

Usage Examples

Basic Code Execution

// Simple expression
const result = pyodide.runPython("2 + 3");
console.log(result); // 5

// Multiple statements
pyodide.runPython(`
    import math
    x = 10
    y = math.sqrt(x)
    print(f"Square root of {x} is {y}")
`);

Working with Variables

// Set variables from JavaScript
pyodide.globals.set("js_value", 42);

const result = pyodide.runPython(`
    python_value = js_value * 2
    python_value  # This becomes the return value
`);

console.log(result); // 84

// Get variables back to JavaScript
const pythonVar = pyodide.globals.get("python_value");
console.log(pythonVar); // 84

Custom Globals and Locals

// Create custom execution context
const customGlobals = pyodide.toPy({
    myFunction: (x) => x * 2,
    myData: [1, 2, 3, 4, 5]
});

const result = pyodide.runPython(`
    # Use custom globals
    processed = [myFunction(x) for x in myData]
    sum(processed)
`, { globals: customGlobals });

console.log(result); // 30

File Context for Debugging

const result = pyodide.runPython(`
    def divide(a, b):
        return a / b
    
    divide(10, 0)  # This will cause an error
`, { filename: "my_script.py" });

// Error traceback will show "my_script.py" as the filename

Async/Await Support

// Top-level await in Python
const result = await pyodide.runPythonAsync(`
    import asyncio
    
    async def fetch_data():
        await asyncio.sleep(0.1)
        return {"message": "Hello from async Python!"}
    
    data = await fetch_data()
    data
`);

console.log(result); // { message: "Hello from async Python!" }

JavaScript Integration with Async

// Register async JavaScript function
pyodide.globals.set("fetchData", async (url) => {
    const response = await fetch(url);
    return await response.json();
});

const result = await pyodide.runPythonAsync(`
    # Call async JavaScript function from Python
    from js import fetchData
    data = await fetchData("https://api.example.com/data")
    data
`);

Error Handling

try {
    pyodide.runPython(`
        undefined_variable  # This will raise NameError
    `);
} catch (error) {
    console.error("Python error:", error.message);
    // Error includes Python traceback
}

// Async error handling
try {
    await pyodide.runPythonAsync(`
        async def failing_function():
            raise ValueError("Something went wrong")
        
        await failing_function()
    `);
} catch (error) {
    console.error("Async Python error:", error.message);
}

Working with Different Data Types

// Return various Python types
const results = {
    number: pyodide.runPython("42"),
    string: pyodide.runPython("'Hello World'"),
    list: pyodide.runPython("[1, 2, 3, 4, 5]"),
    dict: pyodide.runPython("{'key': 'value', 'number': 123}"),
    none: pyodide.runPython("None"),
    boolean: pyodide.runPython("True")
};

console.log(results);
// {
//   number: 42,
//   string: "Hello World", 
//   list: [1, 2, 3, 4, 5],
//   dict: {key: "value", number: 123},
//   none: null,
//   boolean: true
// }

Complex Objects and PyProxy

// Return complex Python objects
const pandas_df = pyodide.runPython(`
    import pandas as pd
    pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
`);

// pandas_df is a PyProxy object
console.log(pandas_df.toString()); // String representation
console.log(pandas_df.shape); // [3, 2]

// Call methods on PyProxy
const sum_result = pandas_df.sum();
console.log(sum_result.toJs()); // Convert to JavaScript object

Execution Context Isolation

// Create isolated execution context
const isolatedGlobals = pyodide.toPy({});
const isolatedLocals = pyodide.toPy({});

pyodide.runPython(`
    secret_value = "this won't leak"
    def private_function():
        return "private"
`, { 
    globals: isolatedGlobals, 
    locals: isolatedLocals 
});

// secret_value is not in main globals
console.log(pyodide.globals.has("secret_value")); // false

// But available in isolated context
console.log(isolatedGlobals.get("secret_value")); // "this won't leak"

Multi-line Code with Proper Indentation

const result = pyodide.runPython(`
    class Calculator:
        def __init__(self):
            self.history = []
        
        def add(self, a, b):
            result = a + b
            self.history.append(f"{a} + {b} = {result}")
            return result
        
        def get_history(self):
            return self.history
    
    calc = Calculator()
    calc.add(5, 3)
    calc.add(10, 7)
    calc.get_history()
`);

console.log(result); // ["5 + 3 = 8", "10 + 7 = 17"]

Expression vs Statement Handling

// Expression (returns value)
const expr_result = pyodide.runPython("2 + 3");
console.log(expr_result); // 5

// Statement (returns undefined) 
const stmt_result = pyodide.runPython("x = 2 + 3");
console.log(stmt_result); // undefined

// Mixed (returns last expression)
const mixed_result = pyodide.runPython(`
    x = 10
    y = 20
    x + y  # This expression is returned
`);
console.log(mixed_result); // 30

// Suppress return with semicolon
const suppressed = pyodide.runPython("2 + 3;");
console.log(suppressed); // undefined

Install with Tessl CLI

npx tessl i tessl/npm-pyodide

docs

advanced-features.md

code-execution.md

ffi.md

file-system.md

index.md

interoperability.md

io-streams.md

package-management.md

runtime-loading.md

tile.json