mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-23 22:00:25 -05:00
* PyodideRuntime should be one of the runtimes * subsume interpreter into runtime API * fix eslint * add comments * move initializers, postInitializers, scriptsQueue, etc. to initialize() of Runtime Super Class * modify comment for initialize * small renaming * change id to default * fix pyscript.py import * try adding tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add inlineDynamicImports option * Make jest happy about ESM modules * Attempt to make jest happy about pyodide * point to version in accordance with node module being used * fix base.ts * fix tests * fix indexURL path determination * edit pyodide.asm.js as a part of setup process * load runtime beforeAll tests * add test for loading a package * use only runPythonAsync underneath for pyodide * import PyodideInterface type directly from pyodide * add some comments Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
import { Runtime } from './runtime';
|
|
import { getLastPath, inJest } from './utils';
|
|
import type { PyodideInterface } from 'pyodide';
|
|
import { loadPyodide } from 'pyodide';
|
|
// eslint-disable-next-line
|
|
// @ts-ignore
|
|
import pyscript from './python/pyscript.py';
|
|
|
|
export class PyodideRuntime extends Runtime {
|
|
src = 'https://cdn.jsdelivr.net/pyodide/v0.21.1/full/pyodide.js';
|
|
name = 'pyodide-default';
|
|
lang = 'python';
|
|
interpreter: PyodideInterface;
|
|
globals: any;
|
|
|
|
async loadInterpreter(): Promise<void> {
|
|
console.log('creating pyodide runtime');
|
|
// eslint-disable-next-line
|
|
// @ts-ignore
|
|
let extraOpts: any = {}
|
|
if (inJest()) {
|
|
extraOpts = {indexURL: [process.cwd(), 'node_modules', 'pyodide'].join('/') }
|
|
}
|
|
this.interpreter = await loadPyodide({
|
|
stdout: console.log,
|
|
stderr: console.log,
|
|
fullStdLib: false,
|
|
...extraOpts
|
|
});
|
|
|
|
this.globals = this.interpreter.globals;
|
|
|
|
// now that we loaded, add additional convenience functions
|
|
console.log('loading micropip');
|
|
await this.loadPackage('micropip');
|
|
|
|
console.log('loading pyscript...');
|
|
const output = await this.run(pyscript);
|
|
if (output !== undefined) {
|
|
console.log(output);
|
|
}
|
|
|
|
console.log('done setting up environment');
|
|
}
|
|
|
|
async run(code: string): Promise<any> {
|
|
return await this.interpreter.runPythonAsync(code);
|
|
}
|
|
|
|
registerJsModule(name: string, module: object): void {
|
|
this.interpreter.registerJsModule(name, module);
|
|
}
|
|
|
|
async loadPackage(names: string | string[]): Promise<void> {
|
|
await this.interpreter.loadPackage(names);
|
|
}
|
|
|
|
async installPackage(package_name: string | string[]): Promise<void> {
|
|
if (package_name.length > 0){
|
|
const micropip = this.globals.get('micropip');
|
|
await micropip.install(package_name);
|
|
micropip.destroy();
|
|
}
|
|
}
|
|
|
|
async loadFromFile(path: string): Promise<void> {
|
|
const filename = getLastPath(path);
|
|
await this.run(
|
|
`
|
|
from pyodide.http import pyfetch
|
|
from js import console
|
|
|
|
try:
|
|
response = await pyfetch("${path}")
|
|
except Exception as err:
|
|
console.warn("PyScript: Access to local files (using 'paths:' in py-env) is not available when directly opening a HTML file; you must use a webserver to serve the additional files. See https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062 on starting a simple webserver with Python.")
|
|
raise(err)
|
|
content = await response.bytes()
|
|
with open("${filename}", "wb") as f:
|
|
f.write(content)
|
|
`,
|
|
);
|
|
}
|
|
}
|