Python distribution for the browser and Node.js based on WebAssembly that enables running Python code with full JavaScript interoperability
npx @tessl/cli install tessl/npm-pyodide@0.28.0Pyodide is a Python distribution for the browser and Node.js based on WebAssembly that enables running Python code in web browsers and JavaScript environments with full bidirectional JavaScript-Python interoperability. It includes a complete CPython interpreter, the Python standard library, and many popular scientific Python packages pre-compiled for WebAssembly.
npm install pyodideimport { loadPyodide } from "pyodide";For CommonJS:
const { loadPyodide } = require("pyodide");import { loadPyodide } from "pyodide";
// Load Pyodide runtime
const pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/",
});
// Run Python code
const result = pyodide.runPython(`
import sys
sys.version
`);
console.log(result); // Python version string
// Install and use Python packages
await pyodide.loadPackage(["numpy", "pandas"]);
pyodide.runPython(`
import numpy as np
import pandas as pd
data = np.array([1, 2, 3, 4, 5])
df = pd.DataFrame({"values": data})
print(df.head())
`);
// JavaScript-Python interoperability
pyodide.globals.set("js_data", [1, 2, 3, 4, 5]);
const python_result = pyodide.runPython(`
js_data_from_python = js_data
sum(js_data_from_python)
`);
console.log(python_result); // 15Pyodide is built around several key components:
Core functionality for loading and configuring the Pyodide WebAssembly runtime with various options for different environments.
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>;Execute Python code from JavaScript with support for synchronous and asynchronous execution patterns.
function runPython(
code: string,
options?: {
globals?: PyProxy;
locals?: PyProxy;
filename?: string;
}
): any;
function runPythonAsync(
code: string,
options?: {
globals?: PyProxy;
locals?: PyProxy;
filename?: string;
}
): Promise<any>;Install and manage Python packages in the WebAssembly environment with automatic dependency resolution.
function loadPackage(
packages: string | string[],
options?: {
messageCallback?: (message: string) => void;
errorCallback?: (message: string) => void;
checkIntegrity?: boolean;
}
): Promise<PackageData[]>;
function loadPackagesFromImports(
code: string,
options?: {
messageCallback?: (message: string) => void;
errorCallback?: (message: string) => void;
checkIntegrity?: boolean;
}
): Promise<PackageData[]>;
const loadedPackages: Map<string, PackageData>;Convert objects between JavaScript and Python, register JavaScript modules for Python import, and access Python objects from JavaScript.
function toPy(
obj: any,
options?: {
depth?: number;
defaultConverter?: (
value: any,
converter: (value: any) => any,
cacheConversion: (input: any, output: any) => void
) => any;
}
): any;
function pyimport(moduleName: string): any;
function registerJsModule(name: string, module: object): void;
function unregisterJsModule(name: string): void;
const globals: PyProxy;
const pyodide_py: PyProxy;Access and manipulate the virtual file system with support for mounting host directories and browser file systems.
const FS: {
readFile(path: string, options?: { encoding?: string }): string | Uint8Array;
writeFile(path: string, data: string | ArrayBufferView, options?: { encoding?: string }): void;
mkdir(path: string): void;
rmdir(path: string): void;
readdir(path: string): string[];
stat(path: string): FSStats;
mount(type: any, options: any, mountpoint: string): void;
// ... additional Emscripten FS methods
};
const PATH: {
dirname(path: string): string;
basename(path: string): string;
extname(path: string): string;
join(...paths: string[]): string;
normalize(path: string): string;
// ... additional path methods
};
function mountNodeFS(emscriptenPath: string, hostPath: string): void;
function mountNativeFS(
path: string,
fileSystemHandle: FileSystemDirectoryHandle
): Promise<NativeFS>;Customize input/output handling for different environments and use cases.
function setStdin(options?: {
stdin?: () => string;
read?: (buffer: Uint8Array) => number;
isatty?: boolean;
}): void;
function setStdout(options?: {
batched?: (output: string) => void;
raw?: (charCode: number) => void;
write?: (buffer: Uint8Array) => number;
isatty?: boolean;
}): void;
function setStderr(options?: {
batched?: (output: string) => void;
raw?: (charCode: number) => void;
write?: (buffer: Uint8Array) => number;
isatty?: boolean;
}): void;Advanced functionality including canvas integration, worker support, interrupt handling, debug control, and package information access.
const canvas: {
setCanvas2D(canvas: HTMLCanvasElement): void;
getCanvas2D(): HTMLCanvasElement | undefined;
setCanvas3D(canvas: HTMLCanvasElement): void;
getCanvas3D(): HTMLCanvasElement | undefined;
};
function setInterruptBuffer(buffer: TypedArray): void;
function checkInterrupt(): void;
function registerComlink(Comlink: any): void;
function unpackArchive(
buffer: TypedArray | ArrayBuffer,
format: string,
options?: { extractDir?: string }
): void;
function setDebug(debug: boolean): boolean;
const lockfile: Lockfile;
const lockfileBaseUrl: string | undefined;Comprehensive type system for seamless JavaScript-Python interoperability with proxy objects, type conversion, and error handling.
import { ffi } from "pyodide/ffi";
const ffi: {
PyProxy: typeof PyProxy;
PyDict: typeof PyDict;
PySequence: typeof PySequence;
PyMutableSequence: typeof PyMutableSequence;
PyCallable: typeof PyCallable;
PyIterable: typeof PyIterable;
PyAsyncIterable: typeof PyAsyncIterable;
PyBuffer: typeof PyBuffer;
PythonError: typeof PythonError;
// ... additional FFI types
};interface PyodideAPI {
loadPackage: typeof loadPackage;
loadPackagesFromImports: typeof loadPackagesFromImports;
loadedPackages: Map<string, PackageData>;
runPython: typeof runPython;
runPythonAsync: typeof runPythonAsync;
pyimport: typeof pyimport;
registerJsModule: typeof registerJsModule;
unregisterJsModule: typeof unregisterJsModule;
toPy: typeof toPy;
globals: PyProxy;
pyodide_py: PyProxy;
FS: FSType;
PATH: any;
canvas: CanvasInterface;
setStdin: typeof setStdin;
setStdout: typeof setStdout;
setStderr: typeof setStderr;
setInterruptBuffer: typeof setInterruptBuffer;
checkInterrupt: typeof checkInterrupt;
registerComlink: typeof registerComlink;
mountNodeFS: typeof mountNodeFS;
mountNativeFS: typeof mountNativeFS;
unpackArchive: typeof unpackArchive;
setDebug: (debug: boolean) => boolean;
lockfile: Lockfile;
lockfileBaseUrl: string | undefined;
ERRNO_CODES: { [code: string]: number };
version: string;
}
interface PackageData {
name: string;
version: string;
channel: string;
file_name: string;
install_dir: string;
sha256: string;
package_type: string;
imports: string[];
depends: string[];
}
type TypedArray =
| Int8Array
| Uint8Array
| Int16Array
| Uint16Array
| Int32Array
| Uint32Array
| Uint8ClampedArray
| Float32Array
| Float64Array;
interface Lockfile {
info: LockfileInfo;
packages: { [name: string]: LockfilePackage };
}
interface LockfileInfo {
arch: "wasm32";
abi_version: string;
platform: string;
version: string;
python: string;
}
interface LockfilePackage {
name: string;
version: string;
file_name: string;
package_type: PackageType;
install_dir: "site" | "dynlib";
sha256: string;
imports: string[];
depends: string[];
}
type PackageType =
| "package"
| "cpython_module"
| "shared_library"
| "static_library";