0
# Package Management
1
2
Install and manage Python packages in the Pyodide environment with automatic dependency resolution and progress tracking.
3
4
## Loading Packages
5
6
### loadPackage
7
8
Install Python packages from the Pyodide package repository.
9
10
```javascript { .api }
11
function loadPackage(
12
packages: string | string[],
13
options?: {
14
messageCallback?: (message: string) => void;
15
errorCallback?: (message: string) => void;
16
checkIntegrity?: boolean;
17
}
18
): Promise<PackageData[]>;
19
```
20
21
**Parameters:**
22
- `packages` - Package name(s) to install
23
- `options.messageCallback` - Callback for progress messages
24
- `options.errorCallback` - Callback for error/warning messages
25
- `options.checkIntegrity` - Verify package integrity (default: true)
26
27
**Returns:** Promise resolving to array of installed package metadata
28
29
### loadPackagesFromImports
30
31
Automatically detect and install packages based on import statements in Python code.
32
33
```javascript { .api }
34
function loadPackagesFromImports(
35
code: string,
36
options?: {
37
messageCallback?: (message: string) => void;
38
errorCallback?: (message: string) => void;
39
checkIntegrity?: boolean;
40
}
41
): Promise<PackageData[]>;
42
```
43
44
**Parameters:**
45
- `code` - Python code to analyze for imports
46
- `options` - Same as `loadPackage`
47
48
**Returns:** Promise resolving to array of installed package metadata
49
50
## Package Registry
51
52
### loadedPackages
53
54
Access information about currently loaded packages.
55
56
```javascript { .api }
57
const loadedPackages: Map<string, PackageData>;
58
```
59
60
## Usage Examples
61
62
### Basic Package Installation
63
64
```javascript
65
// Install single package
66
await pyodide.loadPackage("numpy");
67
68
// Install multiple packages
69
await pyodide.loadPackage(["pandas", "matplotlib", "scipy"]);
70
71
// Use installed packages
72
pyodide.runPython(`
73
import numpy as np
74
import pandas as pd
75
76
data = np.array([1, 2, 3, 4, 5])
77
df = pd.DataFrame({"values": data})
78
print(df.describe())
79
`);
80
```
81
82
### Progress Tracking
83
84
```javascript
85
await pyodide.loadPackage(["scipy", "scikit-learn"], {
86
messageCallback: (msg) => {
87
console.log(`Download: ${msg}`);
88
},
89
errorCallback: (msg) => {
90
console.warn(`Warning: ${msg}`);
91
}
92
});
93
```
94
95
### Auto-loading from Import Analysis
96
97
```javascript
98
const pythonCode = `
99
import numpy as np
100
import pandas as pd
101
from sklearn.linear_model import LinearRegression
102
import matplotlib.pyplot as plt
103
`;
104
105
// Automatically detect and install required packages
106
const installedPackages = await pyodide.loadPackagesFromImports(pythonCode);
107
console.log("Installed packages:", installedPackages.map(pkg => pkg.name));
108
109
// Now run the code
110
pyodide.runPython(pythonCode);
111
pyodide.runPython(`
112
# Packages are now available
113
X = np.array([[1], [2], [3], [4]])
114
y = np.array([2, 4, 6, 8])
115
model = LinearRegression().fit(X, y)
116
print(f"Slope: {model.coef_[0]}")
117
`);
118
```
119
120
### Custom Progress UI
121
122
```javascript
123
let progressDiv = document.getElementById('progress');
124
125
await pyodide.loadPackage(["tensorflow", "keras"], {
126
messageCallback: (msg) => {
127
// Parse download progress
128
if (msg.includes("Downloading")) {
129
const match = msg.match(/(\d+)\/(\d+)/);
130
if (match) {
131
const [, current, total] = match;
132
const percent = (current / total) * 100;
133
progressDiv.innerHTML = `Installing packages: ${percent.toFixed(1)}%`;
134
}
135
}
136
},
137
errorCallback: (msg) => {
138
console.error("Package installation warning:", msg);
139
}
140
});
141
142
progressDiv.innerHTML = "Installation complete!";
143
```
144
145
### Package Information
146
147
```javascript
148
// Load package and examine metadata
149
const packageData = await pyodide.loadPackage("networkx");
150
console.log("Package info:", packageData[0]);
151
152
// Check all loaded packages
153
console.log("Currently loaded packages:");
154
for (const [name, data] of pyodide.loadedPackages) {
155
console.log(`${name} v${data.version} (${data.package_type})`);
156
}
157
158
// Check if specific package is loaded
159
if (pyodide.loadedPackages.has("numpy")) {
160
const numpyInfo = pyodide.loadedPackages.get("numpy");
161
console.log(`NumPy version: ${numpyInfo.version}`);
162
}
163
```
164
165
### Error Handling
166
167
```javascript
168
try {
169
await pyodide.loadPackage("nonexistent-package");
170
} catch (error) {
171
if (error.message.includes("not found")) {
172
console.error("Package not available in Pyodide repository");
173
} else {
174
console.error("Installation failed:", error.message);
175
}
176
}
177
178
// Handle import analysis errors
179
try {
180
const packages = await pyodide.loadPackagesFromImports(`
181
import some_package_that_doesnt_exist
182
`);
183
} catch (error) {
184
console.log("Some imports couldn't be resolved, continuing...");
185
}
186
```
187
188
### Installing from Initialization
189
190
```javascript
191
// Load packages during Pyodide initialization for better performance
192
const pyodide = await loadPyodide({
193
packages: ["numpy", "pandas", "matplotlib"]
194
});
195
196
// Packages are immediately available
197
pyodide.runPython(`
198
import numpy as np
199
print("NumPy version:", np.__version__)
200
`);
201
```
202
203
### Batch Installation with Dependencies
204
205
```javascript
206
// Install packages with complex dependency trees
207
const scientificStack = [
208
"numpy",
209
"scipy",
210
"pandas",
211
"matplotlib",
212
"scikit-learn",
213
"networkx",
214
"sympy"
215
];
216
217
console.log("Installing scientific Python stack...");
218
const results = await pyodide.loadPackage(scientificStack, {
219
messageCallback: (msg) => {
220
if (msg.includes("Installing")) {
221
console.log(msg);
222
}
223
}
224
});
225
226
console.log(`Successfully installed ${results.length} packages`);
227
228
// Verify installation
229
pyodide.runPython(`
230
import sys
231
installed = [pkg.split('.')[0] for pkg in sys.modules.keys()
232
if not pkg.startswith('_')]
233
print(f"Available modules: {len(set(installed))}")
234
`);
235
```
236
237
### Working with MicroPip
238
239
```javascript
240
// Use Python's micropip for additional packages
241
await pyodide.loadPackage("micropip");
242
243
pyodide.runPython(`
244
import micropip
245
246
# Install pure Python packages from PyPI
247
await micropip.install("requests")
248
await micropip.install("beautifulsoup4")
249
250
# Use installed packages
251
import requests
252
from bs4 import BeautifulSoup
253
print("Additional packages installed via micropip")
254
`);
255
```
256
257
## Package Data Structure
258
259
```javascript { .api }
260
interface PackageData {
261
name: string; // Package name
262
version: string; // Package version
263
channel: string; // Distribution channel
264
file_name: string; // Archive filename
265
install_dir: string; // Installation directory
266
sha256: string; // File integrity hash
267
package_type: string; // Package type (e.g., "package")
268
imports: string[]; // Importable module names
269
depends: string[]; // Package dependencies
270
}
271
```
272
273
## Advanced Package Management
274
275
### Custom Package Sources
276
277
```javascript
278
// Load from custom lock file with different package sources
279
const customLockFile = await fetch("/custom-pyodide-lock.json")
280
.then(r => r.json());
281
282
const pyodide = await loadPyodide({
283
lockFileContents: customLockFile,
284
packageBaseUrl: "https://custom-packages.example.com/"
285
});
286
287
await pyodide.loadPackage("custom-package");
288
```
289
290
### Package Installation Hooks
291
292
```javascript
293
const originalLoadPackage = pyodide.loadPackage;
294
295
// Wrap loadPackage with custom logic
296
pyodide.loadPackage = async function(packages, options = {}) {
297
console.log(`Installing packages: ${Array.isArray(packages) ? packages.join(", ") : packages}`);
298
299
const startTime = Date.now();
300
const result = await originalLoadPackage.call(this, packages, {
301
...options,
302
messageCallback: (msg) => {
303
console.log(`[${Date.now() - startTime}ms] ${msg}`);
304
options.messageCallback?.(msg);
305
}
306
});
307
308
console.log(`Installation completed in ${Date.now() - startTime}ms`);
309
return result;
310
};
311
```