import { syncKernel, asyncKernel, FileSystemSpec } from "@cowasm/kernel";
import { join } from "path";
import { existsSync } from "fs";
import debug from "debug";
const log = debug("python-wasm");
import { Options, PythonWasmSync, PythonWasmAsync } from "./common";
export type { Options, PythonWasmSync, PythonWasmAsync };
export const path = __dirname;
const python_wasm = join(__dirname, "python.wasm");
const pythonEverything = join(__dirname, "python-everything.zip");
const pythonStdlib = join(__dirname, "python-stdlib.zip");
const pythonReadline = join(__dirname, "python-readline.zip");
const pythonMinimal = join(__dirname, "python-minimal.zip");
const PYTHONEXECUTABLE = join(__dirname, "../../cpython/bin/python-wasm");
export async function syncPython(
opts: Options = { fs: "everything" }
): Promise<PythonWasmSync> {
return (await createPython(true, opts)) as PythonWasmSync;
}
export async function asyncPython(
opts: Options = { fs: "everything" }
): Promise<PythonWasmAsync> {
return (await createPython(false, opts)) as PythonWasmAsync;
}
export default asyncPython;
async function createPython(
sync: boolean,
opts: Options
): Promise<PythonWasmSync | PythonWasmAsync> {
opts = { fs: "everything", ...opts };
log("creating Python; sync = ", sync, ", opts = ", opts);
const fs = getFilesystem(opts);
let env: any = { PYTHONEXECUTABLE };
let wasm = python_wasm;
if (opts?.fs == "everything") {
wasm = "/usr/lib/python3.11/python.wasm";
}
if (opts?.fs == "everything") {
env.PYTHONHOME = "/usr";
}
if (opts?.env != null) {
env = { ...env, ...opts.env };
}
const kernel = sync
? await syncKernel({ env, fs })
: await asyncKernel({
env,
fs,
interactive: opts?.interactive,
noStdio: opts?.noStdio,
});
log("done");
log("initializing python");
const python = sync
? new PythonWasmSync(kernel as any, wasm)
: new PythonWasmAsync(kernel as any, wasm);
await python.init();
log("done");
return python;
}
function getFilesystem(opts?: Options): FileSystemSpec[] {
if (opts?.fs == "everything") {
return [
{
type: "zipfile",
zipfile: pythonEverything,
mountpoint: "/usr/lib/python3.11",
},
{ type: "native" },
];
}
if (opts?.fs == "stdlib") {
return [
{
type: "zipfile",
zipfile: pythonStdlib,
mountpoint: "/usr/lib/python3.11",
},
{ type: "native" },
];
}
if (opts?.fs == "bundle" || !existsSync(PYTHONEXECUTABLE)) {
return [
{
type: "zipfile",
zipfile: opts?.noReadline ? pythonMinimal : pythonReadline,
mountpoint: "/usr/lib/python3.11",
},
{
type: "zipfile",
async: true,
zipfile: pythonStdlib,
mountpoint: "/usr/lib/python3.11",
},
{ type: "native" },
];
} else {
return [{ type: "native" }];
}
}