From 67be46f224c388dbc84cc29a32830535cf9849b5 Mon Sep 17 00:00:00 2001 From: Fabio Pliger Date: Tue, 12 Apr 2022 19:04:26 -0500 Subject: [PATCH 01/10] add support for paths on py-env so that we can load local (sort of) scripts into the environment --- pyscriptjs/src/components/pyenv.ts | 27 +++++++++++++++++++++++++-- pyscriptjs/src/interpreter.ts | 19 ++++++++++++++++++- pyscriptjs/src/utils.ts | 8 +++++++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/pyscriptjs/src/components/pyenv.ts b/pyscriptjs/src/components/pyenv.ts index e12d6f5..f67b808 100644 --- a/pyscriptjs/src/components/pyenv.ts +++ b/pyscriptjs/src/components/pyenv.ts @@ -1,7 +1,7 @@ import * as jsyaml from 'js-yaml'; import { pyodideLoaded, loadedEnvironments, mode, addInitializer } from '../stores'; -import { loadPackage } from '../interpreter'; +import { loadPackage, loadFromFile } from '../interpreter'; // Premise used to connect to the first available pyodide interpreter let pyodideReadyPromise; @@ -37,13 +37,36 @@ export class PyEnv extends HTMLElement { this.code = this.innerHTML; this.innerHTML = ''; - let env = this.environment = jsyaml.load(this.code); + let env = []; + let paths = []; + this.environment = jsyaml.load(this.code); + for (let entry of this.environment) { + if (typeof entry == "string" ){ + env.push(entry); + } + else if (entry.hasOwnProperty('paths')){ + for (let path of entry.paths) { + paths.push(path); + } + } + } + async function loadEnv() { let pyodide = await pyodideReadyPromise; await loadPackage(env, pyodide); console.log("enviroment loaded") } + + async function loadPaths() { + let pyodide = await pyodideReadyPromise; + for (let singleFile of paths) { + await loadFromFile(singleFile, pyodide); + } + console.log("paths loaded") + } addInitializer(loadEnv); + addInitializer(loadPaths); console.log("enviroment loading...", env) + } } diff --git a/pyscriptjs/src/interpreter.ts b/pyscriptjs/src/interpreter.ts index 8578f85..44d77d5 100644 --- a/pyscriptjs/src/interpreter.ts +++ b/pyscriptjs/src/interpreter.ts @@ -1,3 +1,5 @@ +import { getLastPath } from "./utils"; + // @ts-nocheck // @ts-ignore let pyodideReadyPromise; @@ -129,4 +131,19 @@ let loadPackage = async function(package_name: string[] | string, runtime: any): await runtime.loadPackage(package_name); } -export {loadInterpreter, pyodideReadyPromise, loadPackage} +let loadFromFile = async function(s: string, runtime: any): Promise { + let filename = getLastPath(s); + await runtime.runPythonAsync(` + from pyodide.http import pyfetch + from pyodide import eval_code + response = await pyfetch("`+s+`") + content = await response.bytes() + + with open("`+filename+`", "wb") as f: + f.write(content) + `) + + runtime.pyimport(filename.replace(".py", "")); +} + +export {loadInterpreter, pyodideReadyPromise, loadPackage, loadFromFile} diff --git a/pyscriptjs/src/utils.ts b/pyscriptjs/src/utils.ts index 624b8c9..1f66ac3 100644 --- a/pyscriptjs/src/utils.ts +++ b/pyscriptjs/src/utils.ts @@ -1,6 +1,12 @@ -export function addClasses(element: HTMLElement, classes: Array){ +function addClasses(element: HTMLElement, classes: Array){ for (let entry of classes) { element.classList.add(entry); } } + +const getLastPath = function (str) { + return str.split('\\').pop().split('/').pop(); +} + +export {addClasses, getLastPath} \ No newline at end of file From 92613c06f5c56e75cb47b6c9c7f5be63663f74c5 Mon Sep 17 00:00:00 2001 From: Fabio Pliger Date: Tue, 12 Apr 2022 19:04:53 -0500 Subject: [PATCH 02/10] update examples to show loading modules into the environment --- pyscriptjs/examples/repl2.html | 7 +++++++ pyscriptjs/examples/simple_script2.html | 14 ++++++++------ pyscriptjs/examples/todo.html | 8 +++++++- pyscriptjs/examples/todo.py | 8 +++++--- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/pyscriptjs/examples/repl2.html b/pyscriptjs/examples/repl2.html index 145ee91..38ca506 100644 --- a/pyscriptjs/examples/repl2.html +++ b/pyscriptjs/examples/repl2.html @@ -12,6 +12,13 @@ + +- bokeh +- numpy +- paths: + - /utils.py + +
diff --git a/pyscriptjs/examples/simple_script2.html b/pyscriptjs/examples/simple_script2.html index 431a5c7..60a06fe 100644 --- a/pyscriptjs/examples/simple_script2.html +++ b/pyscriptjs/examples/simple_script2.html @@ -10,6 +10,10 @@ + + - paths: + - /utils.py + @@ -17,20 +21,18 @@
-from datetime import datetime -now = datetime.now() -now.strftime("%m/%d/%Y, %H:%M:%S") +import utils +utils.now() -from datetime import datetime +from utils import now import asyncio async def foo(): while True: await asyncio.sleep(1) - now = datetime.now() - output = now.strftime("%m/%d/%Y, %H:%M:%S") + output = now() pyscript.write("outputDiv2", output) out3 = Element("outputDiv3") diff --git a/pyscriptjs/examples/todo.html b/pyscriptjs/examples/todo.html index 61a75dc..e2323f9 100644 --- a/pyscriptjs/examples/todo.html +++ b/pyscriptjs/examples/todo.html @@ -10,6 +10,10 @@ + + - paths: + - /utils.py + @@ -22,7 +26,8 @@

To Do List

- + +
+
diff --git a/pyscriptjs/examples/todo.py b/pyscriptjs/examples/todo.py index 35afc7c..d82e969 100644 --- a/pyscriptjs/examples/todo.py +++ b/pyscriptjs/examples/todo.py @@ -1,4 +1,5 @@ from datetime import datetime as dt +from utils import add_class, remove_class from js import console tasks = [] @@ -11,7 +12,9 @@ new_task_content = Element("new-task-content") def add_task(*ags, **kws): # create task task_id = f"task-{len(tasks)}" + now = dt.now() task = {"id": task_id, "content": new_task_content.element.value, "done": False, "created_at": dt.now()} + tasks.append(task) # add the task element to the page as new node in the list by cloning from a template @@ -24,14 +27,13 @@ def add_task(*ags, **kws): def check_task(evt=None): task['done'] = not task['done'] if task['done']: - taskHtmlContent.element.classList.add("line-through") + add_class(taskHtmlContent, "line-through") else: - taskHtmlContent.element.classList.remove("line-through") + remove_class(taskHtmlContent, "line-through") new_task_content.clear() taskHtmlCheck.element.onclick = check_task def add_task_event(e): - console.log("im in") if (e.key == "Enter"): add_task() From f79d76c542c7d5f4049a721bf9b239a86cd493a6 Mon Sep 17 00:00:00 2001 From: Fabio Pliger Date: Wed, 13 Apr 2022 09:25:34 -0500 Subject: [PATCH 03/10] remove py-button from todo example --- pyscriptjs/examples/todo.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyscriptjs/examples/todo.html b/pyscriptjs/examples/todo.html index e2323f9..b638062 100644 --- a/pyscriptjs/examples/todo.html +++ b/pyscriptjs/examples/todo.html @@ -26,8 +26,6 @@

To Do List

- -