Skip to content

Commit

Permalink
Generalise Pyodide base URL
Browse files Browse the repository at this point in the history
  • Loading branch information
yongrenjie committed Nov 22, 2023
1 parent 1007dde commit f5f82da
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 40 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
25 changes: 18 additions & 7 deletions web/src/lib/leftSidebar/create/ModifyOutputAreas.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@
green = oaChanges.get("greenspace");
greenModified = green !== null;
referenceSig = oaChanges.get("reference_sig");
// Update sliders as well
console.log(sig);
console.log(referenceSig);
jobMin = config.signatures[sig || referenceSig].job_d1;
jobMax = config.signatures[sig || referenceSig].job_d9;
useMin = config.signatures[sig || referenceSig].use_d1;
useMax = config.signatures[sig || referenceSig].use_d9;
} else {
// More than one OA selected
const allSigs: Array<number | null> = oas.map((oa) =>
Expand Down Expand Up @@ -224,8 +231,12 @@
let green: number | null = null;
let greenModified: boolean;
// Update values in dropdowns whenever clickedOAs is changed
let jobMin: number;
let jobMax: number;
let useMin: number;
let useMax: number;
$: {
// Update values in dropdowns whenever clickedOAs is changed
if (mounted) loadOAChangesToUI($clickedOAs);
}
</script>
Expand Down Expand Up @@ -304,9 +315,9 @@
on:modified={updateOAChanges}
leftEdge={0}
rightEdge={1}
min={0}
max={1}
defaultVal={0}
min={jobMin}
max={jobMax}
defaultVal={jobMin}
step={0.01}
/>

Expand All @@ -317,9 +328,9 @@
on:modified={updateOAChanges}
leftEdge={0}
rightEdge={1}
min={0}
max={1}
defaultVal={0}
min={useMin}
max={useMax}
defaultVal={useMin}
step={0.01}
/>

Expand Down
30 changes: 13 additions & 17 deletions web/src/lib/python/pyodide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ async function createOrGetWorker() {
return syncWorker;
}

export async function asyncRun(script, context) {
export async function asyncRunScenario(
script: string,
context: object,
) {
const worker = await createOrGetWorker();
id = (id + 1) % Number.MAX_SAFE_INTEGER;
return new Promise((onSuccess) => {
Expand All @@ -36,36 +39,26 @@ export async function asyncRun(script, context) {
});
}

export async function runScenario(scenario) {
// TODO convert scenario here?
export async function runScenario(scenario: string) {
const pythonProgram = `
import pyodide_http
pyodide_http.patch_all()
print(globals())
from js import scenario_json
import sys
import demoland_engine
import json
import pandas as pd
import numpy as np
import joblib
import sklearn
import time
start= time.time()
print(scenario_json)
start = time.time()
scenario = json.loads(scenario_json)
print(json.dumps(scenario, indent=2))
df = demoland_engine.get_empty()
print("Got empty")
for oa_code, vals in scenario["scenario_json"].items():
print(oa_code, list(vals.values()))
df.loc[oa_code] = list(vals.values())
print("setup codes")
pred = demoland_engine.get_indicators(df, random_seed=42)
print("made prediction")
sig = demoland_engine.sampling.oa_key.primary_type.copy()
mapping = {
Expand All @@ -91,10 +84,13 @@ export async function runScenario(scenario) {
sig.loc[changed.index] = changed
pred["signature_type"] = sig
prediction = pred.to_dict("index")
print(f"{time.time()- start} s to run")
print(f"{time.time() - start}s to run")
json.dumps(prediction)
`
const result = await asyncRun(pythonProgram, { scenario_json: scenario })
const result = await asyncRunScenario(pythonProgram, {
scenario_json: scenario,
BASE_URL: window.location.origin + window.location.pathname
});
if (result.error) {
console.error(result.error);
return result;
Expand Down
40 changes: 24 additions & 16 deletions web/src/lib/python/pyodide_worker.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
import { loadPyodide } from "pyodide";
import { loadPyodide, type PyodideInterface } from "pyodide";

// Specify the extra properties of `globalThis`
declare global {
interface Window {
pyodide: PyodideInterface;
scenario_json: string;
BASE_URL: string;
}
}

async function loadPyodideAndPackages() {
self.pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/" });
self.pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/"
});
await self.pyodide.loadPackage(["micropip"]);
console.log("loading micropip")
const micropip = self.pyodide.pyimport("micropip");
await micropip.install("lzma")
await micropip.install("pyodide-http")
console.log("installing demoland")
await micropip.install('/demoland_engine-1.1.1.dev22+g17677c0.d20231106-py3-none-any.whl');
console.log("installed demoland")
await micropip.install("/demoland_engine-0.1.dev1+gcccf10a-py3-none-any.whl");
}

const pyodideReadyPromise = loadPyodideAndPackages();

self.onmessage = async (event) => {
// make sure loading is done
// Load packages
try {
await pyodideReadyPromise;
await loadPyodideAndPackages();
} catch (error) {
console.error(error);
self.postMessage({ error: error.message });
}
// Don't bother yet with this line, suppose our API is built in such a way:
const { id, python, ...context } = event.data;
// The worker copies the context in its own "memory" (an object mapping name to values)
for (const key of Object.keys(context)) {
self[key] = context[key];
}
// Now is the easy part, the one that is similar to working in the main thread:

// The 'context' allows us to pass in variables from the main thread
// to the worker thread, and access them in Python code. On the TypeScript
// side we can do `from js import scenario_json`; and in the Python package
// itself we can do `import pyodide_js; pyodide_js.globals.get("BASE_URL")`.
self.scenario_json = context.scenario_json;
self.BASE_URL = context.BASE_URL;

try {
await self.pyodide.loadPackagesFromImports(python);
const results = await self.pyodide.runPythonAsync(python);
Expand Down

0 comments on commit f5f82da

Please sign in to comment.