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

runtime-loading.mddocs/

Runtime Loading

The runtime loading system provides comprehensive control over how Pyodide initializes, including package loading, environment configuration, and file system setup.

Loading the Runtime

loadPyodide

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 URL
  • packageBaseUrl - Base URL for relative package paths
  • fullStdLib - Load complete Python standard library (default: false)
  • stdLibURL - URL for python_stdlib.zip (default: ${indexURL}/python_stdlib.zip)
  • stdin - Standard input callback function
  • stdout - Standard output callback function
  • stderr - Standard error callback function
  • jsglobals - 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 initialization
  • pyproxyToStringRepr - @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 hook

Returns: Promise resolving to PyodideAPI instance

Usage Examples

Basic Loading

import { loadPyodide } from "pyodide";

const pyodide = await loadPyodide();
console.log("Pyodide loaded successfully");

Custom Configuration

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"]
});

Node.js with Package Caching

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")
});

Custom Lock File

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/"
});

File System Initialization

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}`);
  }
});

Snapshot Loading (Advanced)

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;
  }
});

Configuration Types

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;
}

Error Handling

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);
  }
}

Version Information

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

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