Python distribution for the browser and Node.js based on WebAssembly that enables running Python code with full JavaScript interoperability
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The runtime loading system provides comprehensive control over how Pyodide initializes, including package loading, environment configuration, and file system setup.
Load and initialize the Pyodide WebAssembly runtime with configurable options.
function loadPyodide(options?: {
indexURL?: string;
packageCacheDir?: string;
lockFileURL?: string;
lockFileContents?: Lockfile | string | Promise<Lockfile | string>;
packageBaseUrl?: string;
fullStdLib?: boolean;
stdLibURL?: string;
stdin?: () => string;
stdout?: (msg: string) => void;
stderr?: (msg: string) => void;
jsglobals?: object;
_sysExecutable?: string;
args?: string[];
env?: { [key: string]: string };
packages?: string[];
pyproxyToStringRepr?: boolean;
enableRunUntilComplete?: boolean;
checkAPIVersion?: boolean;
fsInit?: (FS: FSType, info: { sitePackages: string }) => Promise<void>;
convertNullToNone?: boolean;
_makeSnapshot?: boolean;
_loadSnapshot?: Uint8Array | ArrayBuffer | PromiseLike<Uint8Array | ArrayBuffer>;
_snapshotDeserializer?: (obj: any) => any;
}): Promise<PyodideAPI>;Parameters:
indexURL - URL for Pyodide runtime files (default: auto-detected from script location)packageCacheDir - Directory for package caching in Node.js (default: same as indexURL)lockFileURL - URL for pyodide-lock.json (default: ${indexURL}/pyodide-lock.json)lockFileContents - Direct lock file contents instead of URLpackageBaseUrl - Base URL for relative package pathsfullStdLib - Load complete Python standard library (default: false)stdLibURL - URL for python_stdlib.zip (default: ${indexURL}/python_stdlib.zip)stdin - Standard input callback functionstdout - Standard output callback functionstderr - Standard error callback functionjsglobals - Object to use as JavaScript globals in Python (default: globalThis)args - Command line arguments for Python (default: [])env - Environment variables for Python (default: {})packages - Packages to load during initializationpyproxyToStringRepr - @deprecated Use old behavior where PyProxy.toString() calls repr() instead of str() (default: false)enableRunUntilComplete - Enable loop.run_until_complete() with stack switching (default: true)checkAPIVersion - Verify API version compatibility (default: true)convertNullToNone - @deprecated Use old behavior where JavaScript null converts to None instead of jsnull (default: false)fsInit - File system initialization hookReturns: Promise resolving to PyodideAPI instance
import { loadPyodide } from "pyodide";
const pyodide = await loadPyodide();
console.log("Pyodide loaded successfully");import { loadPyodide } from "pyodide";
const pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.28.2/full/",
fullStdLib: true,
packages: ["numpy", "pandas"],
stdout: (msg) => console.log(`Python: ${msg}`),
stderr: (msg) => console.error(`Python Error: ${msg}`),
env: {
"PYTHONPATH": "/custom/path",
"MY_VAR": "custom_value"
},
args: ["-u", "-W", "ignore"]
});import { loadPyodide } from "pyodide";
import path from "path";
const pyodide = await loadPyodide({
packageCacheDir: path.join(process.cwd(), "pyodide_cache"),
packages: ["scipy", "matplotlib"],
stdout: (msg) => process.stdout.write(msg + "\n"),
stderr: (msg) => process.stderr.write(msg + "\n")
});import { loadPyodide } from "pyodide";
const customLockFile = {
info: {
arch: "wasm32",
platform: "emscripten_3_1_27",
version: "0.28.2",
python: "3.12.1"
},
packages: {
// custom package definitions
}
};
const pyodide = await loadPyodide({
lockFileContents: customLockFile,
packageBaseUrl: "https://custom-cdn.example.com/packages/"
});import { loadPyodide } from "pyodide";
const pyodide = await loadPyodide({
fsInit: async (FS, { sitePackages }) => {
// Create custom directories
FS.mkdir("/workspace");
FS.mkdir("/data");
// Write initial files
FS.writeFile("/workspace/config.py", "DEBUG = True");
console.log(`Site packages located at: ${sitePackages}`);
}
});import { loadPyodide } from "pyodide";
// Load from a pre-created snapshot for faster startup
const snapshotData = await fetch("./pyodide-snapshot.dat")
.then(r => r.arrayBuffer());
const pyodide = await loadPyodide({
_loadSnapshot: snapshotData,
_snapshotDeserializer: (obj) => {
// Custom deserialization logic
return obj;
}
});interface FSType {
readFile(path: string, options?: { encoding?: string }): string | Uint8Array;
writeFile(path: string, data: string | ArrayBufferView): void;
mkdir(path: string): void;
// ... additional Emscripten FS methods
}
interface Lockfile {
info: LockfileInfo;
packages: { [name: string]: LockfilePackage };
}
interface LockfileInfo {
arch: string;
platform: string;
version: string;
python: string;
}
interface LockfilePackage {
name: string;
version: string;
file_name: string;
install_dir: string;
sha256: string;
imports: string[];
depends: string[];
package_type: string;
}try {
const pyodide = await loadPyodide({
indexURL: "https://invalid-url.com/pyodide/"
});
} catch (error) {
if (error.message.includes("Failed to fetch")) {
console.error("Network error loading Pyodide");
} else if (error.message.includes("version does not match")) {
console.error("API version mismatch");
} else {
console.error("Unknown error:", error);
}
}Access the Pyodide version after loading:
import { loadPyodide, version } from "pyodide";
console.log(`Loading Pyodide version: ${version}`);
const pyodide = await loadPyodide();
console.log(`Loaded Pyodide version: ${pyodide.version}`);Install with Tessl CLI
npx tessl i tessl/npm-pyodide