prepare-pyodide.js 2.2 KB
Newer Older
Timothy J. Baek's avatar
Timothy J. Baek committed
1
const packages = [
Timothy J. Baek's avatar
Timothy J. Baek committed
2
3
	'micropip',
	'packaging',
Timothy J. Baek's avatar
Timothy J. Baek committed
4
5
6
7
8
9
10
	'requests',
	'beautifulsoup4',
	'numpy',
	'pandas',
	'matplotlib',
	'scikit-learn',
	'scipy',
11
12
	'regex',
	'seaborn'
Timothy J. Baek's avatar
Timothy J. Baek committed
13
];
14
15

import { loadPyodide } from 'pyodide';
Timothy J. Baek's avatar
Timothy J. Baek committed
16
import { writeFile, readFile, copyFile, readdir, rmdir } from 'fs/promises';
17
18
19

async function downloadPackages() {
	console.log('Setting up pyodide + micropip');
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
20
21
22
23
24
25
26
27
28
29

	let pyodide;
	try {
		pyodide = await loadPyodide({
			packageCacheDir: 'static/pyodide'
		});
	} catch (err) {
		console.error('Failed to load Pyodide:', err);
		return;
	}
Timothy J. Baek's avatar
Timothy J. Baek committed
30
31

	const packageJson = JSON.parse(await readFile('package.json'));
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
32
	const pyodideVersion = packageJson.dependencies.pyodide.replace('^', '');
Timothy J. Baek's avatar
Timothy J. Baek committed
33

Timothy J. Baek's avatar
fix  
Timothy J. Baek committed
34
35
	try {
		const pyodidePackageJson = JSON.parse(await readFile('static/pyodide/package.json'));
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
36
		const pyodidePackageVersion = pyodidePackageJson.version.replace('^', '');
Timothy J. Baek's avatar
fix  
Timothy J. Baek committed
37

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
38
		if (pyodideVersion !== pyodidePackageVersion) {
Timothy J. Baek's avatar
fix  
Timothy J. Baek committed
39
40
41
42
			console.log('Pyodide version mismatch, removing static/pyodide directory');
			await rmdir('static/pyodide', { recursive: true });
		}
	} catch (e) {
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
43
		console.log('Pyodide package not found, proceeding with download.');
Timothy J. Baek's avatar
Timothy J. Baek committed
44
45
	}

Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
	try {
		console.log('Loading micropip package');
		await pyodide.loadPackage('micropip');

		const micropip = pyodide.pyimport('micropip');
		console.log('Downloading Pyodide packages:', packages);

		try {
			for (const pkg of packages) {
				console.log(`Installing package: ${pkg}`);
				await micropip.install(pkg);
			}
		} catch (err) {
			console.error('Package installation failed:', err);
			return;
		}

		console.log('Pyodide packages downloaded, freezing into lock file');

		try {
			const lockFile = await micropip.freeze();
			await writeFile('static/pyodide/pyodide-lock.json', lockFile);
		} catch (err) {
			console.error('Failed to write lock file:', err);
		}
	} catch (err) {
		console.error('Failed to load or install micropip:', err);
	}
74
75
76
77
78
79
80
81
82
83
84
85
}

async function copyPyodide() {
	console.log('Copying Pyodide files into static directory');
	// Copy all files from node_modules/pyodide to static/pyodide
	for await (const entry of await readdir('node_modules/pyodide')) {
		await copyFile(`node_modules/pyodide/${entry}`, `static/pyodide/${entry}`);
	}
}

await downloadPackages();
await copyPyodide();