|
3 | 3 | let pyodideReadyPromise;
|
4 | 4 |
|
5 | 5 |
|
| 6 | +let additional_definitions = ` |
| 7 | +from js import document, setInterval, console |
| 8 | +import asyncio |
| 9 | +import io, base64 |
| 10 | +
|
| 11 | +loop = asyncio.get_event_loop() |
| 12 | +
|
| 13 | +class PyScript: |
| 14 | + loop = loop |
| 15 | +
|
| 16 | + @staticmethod |
| 17 | + def write(element_id, value, append=False, exec_id=0): |
| 18 | + """Writes value to the element with id "element_id""" |
| 19 | + console.log(f"APPENDING: {append} ==> {element_id} --> {value}") |
| 20 | + if append: |
| 21 | + child = document.createElement('div'); |
| 22 | + element = document.querySelector(f'#{element_id}'); |
| 23 | + exec_id = exec_id or element.childElementCount + 1 |
| 24 | + element_id = child.id = f"{element_id}-{exec_id}"; |
| 25 | + element.appendChild(child); |
| 26 | +
|
| 27 | + if hasattr(value, "savefig"): |
| 28 | + console.log(f"FIGURE: {value}") |
| 29 | + buf = io.BytesIO() |
| 30 | + value.savefig(buf, format='png') |
| 31 | + buf.seek(0) |
| 32 | + img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8') |
| 33 | + document.getElementById(element_id).innerHTML = f'<div><img id="plt" src="{img_str}"/></div>' |
| 34 | + elif hasattr(value, "startswith") and value.startswith("data:image"): |
| 35 | + console.log(f"DATA/IMAGE: {value}") |
| 36 | + document.getElementById(element_id).innerHTML = f'<div><img id="plt" src="{value}"/></div>' |
| 37 | + else: |
| 38 | + document.getElementById(element_id).innerHTML = repr(value); |
| 39 | + console.log(f"ELSE: {append} ==> {element_id} --> {value}") |
| 40 | +
|
| 41 | + @staticmethod |
| 42 | + def run_until_complete(f): |
| 43 | + p = loop.run_until_complete(f) |
| 44 | +
|
| 45 | +pyscript = PyScript() |
| 46 | +
|
| 47 | +
|
| 48 | +
|
| 49 | +class Element: |
| 50 | + def __init__(self, element_id): |
| 51 | + self._id = element_id |
| 52 | +
|
| 53 | + @property |
| 54 | + def element(self): |
| 55 | + """Return the dom element""" |
| 56 | + return document.querySelector(f'#{self._id}'); |
| 57 | +
|
| 58 | + def write(self, value, append=False): |
| 59 | + console.log(f"Element.write: {value} --> {append}") |
| 60 | + pyscript.write(self._id, value, append=append) |
| 61 | +
|
| 62 | + def clear(self): |
| 63 | + self.write("", append=False) |
| 64 | +
|
| 65 | + def clone(self, new_id=None): |
| 66 | + if new_id is None: |
| 67 | + new_id = self.element.id |
| 68 | +
|
| 69 | + clone = self.element.cloneNode(true); |
| 70 | + clone.id = new_id; |
| 71 | +
|
| 72 | + # Inject it into the DOM |
| 73 | + self.element.after(clone); |
| 74 | +
|
| 75 | +` |
| 76 | + |
6 | 77 | let loadInterpreter = async function(): any {
|
7 | 78 | /* @ts-ignore */
|
8 | 79 | let pyodide = await loadPyodide({
|
9 | 80 | indexURL: "https://cdn.jsdelivr.net/pyodide/v0.19.0/full/",
|
10 | 81 | });
|
| 82 | + |
| 83 | + // now that we loaded, add additional convenience fuctions |
| 84 | + pyodide.loadPackage(['matplotlib', 'numpy']) |
| 85 | + |
| 86 | + await pyodide.loadPackage("micropip"); |
| 87 | + await pyodide.runPythonAsync(` |
| 88 | + import micropip |
| 89 | + await micropip.install("ipython") |
| 90 | + `); |
| 91 | + |
| 92 | + let output = pyodide.runPython(additional_definitions); |
| 93 | + |
11 | 94 | /* @ts-ignore */
|
12 | 95 | return pyodide;
|
13 | 96 | }
|
|
0 commit comments