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
Install and manage Python packages in the Pyodide environment with automatic dependency resolution and progress tracking.
Install Python packages from the Pyodide package repository.
function loadPackage(
packages: string | string[],
options?: {
messageCallback?: (message: string) => void;
errorCallback?: (message: string) => void;
checkIntegrity?: boolean;
}
): Promise<PackageData[]>;Parameters:
packages - Package name(s) to installoptions.messageCallback - Callback for progress messagesoptions.errorCallback - Callback for error/warning messagesoptions.checkIntegrity - Verify package integrity (default: true)Returns: Promise resolving to array of installed package metadata
Automatically detect and install packages based on import statements in Python code.
function loadPackagesFromImports(
code: string,
options?: {
messageCallback?: (message: string) => void;
errorCallback?: (message: string) => void;
checkIntegrity?: boolean;
}
): Promise<PackageData[]>;Parameters:
code - Python code to analyze for importsoptions - Same as loadPackageReturns: Promise resolving to array of installed package metadata
Access information about currently loaded packages.
const loadedPackages: Map<string, PackageData>;// Install single package
await pyodide.loadPackage("numpy");
// Install multiple packages
await pyodide.loadPackage(["pandas", "matplotlib", "scipy"]);
// Use installed packages
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.describe())
`);await pyodide.loadPackage(["scipy", "scikit-learn"], {
messageCallback: (msg) => {
console.log(`Download: ${msg}`);
},
errorCallback: (msg) => {
console.warn(`Warning: ${msg}`);
}
});const pythonCode = `
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
`;
// Automatically detect and install required packages
const installedPackages = await pyodide.loadPackagesFromImports(pythonCode);
console.log("Installed packages:", installedPackages.map(pkg => pkg.name));
// Now run the code
pyodide.runPython(pythonCode);
pyodide.runPython(`
# Packages are now available
X = np.array([[1], [2], [3], [4]])
y = np.array([2, 4, 6, 8])
model = LinearRegression().fit(X, y)
print(f"Slope: {model.coef_[0]}")
`);let progressDiv = document.getElementById('progress');
await pyodide.loadPackage(["tensorflow", "keras"], {
messageCallback: (msg) => {
// Parse download progress
if (msg.includes("Downloading")) {
const match = msg.match(/(\d+)\/(\d+)/);
if (match) {
const [, current, total] = match;
const percent = (current / total) * 100;
progressDiv.innerHTML = `Installing packages: ${percent.toFixed(1)}%`;
}
}
},
errorCallback: (msg) => {
console.error("Package installation warning:", msg);
}
});
progressDiv.innerHTML = "Installation complete!";// Load package and examine metadata
const packageData = await pyodide.loadPackage("networkx");
console.log("Package info:", packageData[0]);
// Check all loaded packages
console.log("Currently loaded packages:");
for (const [name, data] of pyodide.loadedPackages) {
console.log(`${name} v${data.version} (${data.package_type})`);
}
// Check if specific package is loaded
if (pyodide.loadedPackages.has("numpy")) {
const numpyInfo = pyodide.loadedPackages.get("numpy");
console.log(`NumPy version: ${numpyInfo.version}`);
}try {
await pyodide.loadPackage("nonexistent-package");
} catch (error) {
if (error.message.includes("not found")) {
console.error("Package not available in Pyodide repository");
} else {
console.error("Installation failed:", error.message);
}
}
// Handle import analysis errors
try {
const packages = await pyodide.loadPackagesFromImports(`
import some_package_that_doesnt_exist
`);
} catch (error) {
console.log("Some imports couldn't be resolved, continuing...");
}// Load packages during Pyodide initialization for better performance
const pyodide = await loadPyodide({
packages: ["numpy", "pandas", "matplotlib"]
});
// Packages are immediately available
pyodide.runPython(`
import numpy as np
print("NumPy version:", np.__version__)
`);// Install packages with complex dependency trees
const scientificStack = [
"numpy",
"scipy",
"pandas",
"matplotlib",
"scikit-learn",
"networkx",
"sympy"
];
console.log("Installing scientific Python stack...");
const results = await pyodide.loadPackage(scientificStack, {
messageCallback: (msg) => {
if (msg.includes("Installing")) {
console.log(msg);
}
}
});
console.log(`Successfully installed ${results.length} packages`);
// Verify installation
pyodide.runPython(`
import sys
installed = [pkg.split('.')[0] for pkg in sys.modules.keys()
if not pkg.startswith('_')]
print(f"Available modules: {len(set(installed))}")
`);// Use Python's micropip for additional packages
await pyodide.loadPackage("micropip");
pyodide.runPython(`
import micropip
# Install pure Python packages from PyPI
await micropip.install("requests")
await micropip.install("beautifulsoup4")
# Use installed packages
import requests
from bs4 import BeautifulSoup
print("Additional packages installed via micropip")
`);interface PackageData {
name: string; // Package name
version: string; // Package version
channel: string; // Distribution channel
file_name: string; // Archive filename
install_dir: string; // Installation directory
sha256: string; // File integrity hash
package_type: string; // Package type (e.g., "package")
imports: string[]; // Importable module names
depends: string[]; // Package dependencies
}// Load from custom lock file with different package sources
const customLockFile = await fetch("/custom-pyodide-lock.json")
.then(r => r.json());
const pyodide = await loadPyodide({
lockFileContents: customLockFile,
packageBaseUrl: "https://custom-packages.example.com/"
});
await pyodide.loadPackage("custom-package");const originalLoadPackage = pyodide.loadPackage;
// Wrap loadPackage with custom logic
pyodide.loadPackage = async function(packages, options = {}) {
console.log(`Installing packages: ${Array.isArray(packages) ? packages.join(", ") : packages}`);
const startTime = Date.now();
const result = await originalLoadPackage.call(this, packages, {
...options,
messageCallback: (msg) => {
console.log(`[${Date.now() - startTime}ms] ${msg}`);
options.messageCallback?.(msg);
}
});
console.log(`Installation completed in ${Date.now() - startTime}ms`);
return result;
};Install with Tessl CLI
npx tessl i tessl/npm-pyodide