mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-20 10:47:35 -05:00
Compare commits
7 Commits
2023.11.1
...
fpliger/ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9e1abf6d1 | ||
|
|
24da768959 | ||
|
|
e750fa7393 | ||
|
|
5a15199a3a | ||
|
|
1801472fc4 | ||
|
|
72955bced9 | ||
|
|
c63c4043d3 |
27
pyscript.core/src/plugins/deprecations-manager.js
Normal file
27
pyscript.core/src/plugins/deprecations-manager.js
Normal file
@@ -0,0 +1,27 @@
|
||||
// PyScript Derepcations Plugin
|
||||
import { hooks } from "../core.js";
|
||||
import { notify } from "./error.js";
|
||||
|
||||
// react lazily on PyScript bootstrap
|
||||
hooks.main.onReady.add(checkDeprecations);
|
||||
hooks.main.onWorker.add(checkDeprecations);
|
||||
|
||||
/**
|
||||
* Check that there are no scripts loading from pyscript.net/latest
|
||||
*/
|
||||
function checkDeprecations() {
|
||||
const scripts = document.querySelectorAll("script");
|
||||
for (const script of scripts) checkLoadingScriptsFromLatest(script.src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if src being loaded from pyscript.net/latest and display a notification if true
|
||||
* * @param {string} src
|
||||
*/
|
||||
function checkLoadingScriptsFromLatest(src) {
|
||||
if (/\/pyscript\.net\/latest/.test(src)) {
|
||||
notify(
|
||||
"Loading scripts from latest is deprecated and will be removed soon. Please use a specific version instead.",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ from typing import Any
|
||||
from pyodide.ffi import JsProxy
|
||||
from pyscript import display, document, window
|
||||
|
||||
# from pyscript import when as _when
|
||||
|
||||
alert = window.alert
|
||||
|
||||
|
||||
@@ -177,9 +175,6 @@ class Element(BaseElement):
|
||||
def show_me(self):
|
||||
self._js.scrollIntoView()
|
||||
|
||||
def when(self, event, handler):
|
||||
document.when(event, selector=self)(handler)
|
||||
|
||||
|
||||
class StyleProxy(dict):
|
||||
def __init__(self, element: Element) -> None:
|
||||
@@ -319,8 +314,8 @@ class PyDom(BaseElement):
|
||||
self.body = Element(document.body)
|
||||
self.head = Element(document.head)
|
||||
|
||||
def create(self, type_, parent=None, classes=None, html=None):
|
||||
return super().create(type_, is_child=False)
|
||||
def create(self, type_, classes=None, html=None):
|
||||
return super().create(type_, is_child=False, classes=classes, html=html)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, int):
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
def on_click(event):
|
||||
print(f"Hello from Python! {dt.now()}")
|
||||
display(f"Hello from Python! {dt.now()}", append=False, target='eresult')
|
||||
display(f"Hello from Python! {dt.now()}", append=False, target='result')
|
||||
|
||||
add_event_listener(element, "click", on_click)
|
||||
</script>
|
||||
|
||||
78
pyscript.core/test/panel/panel.py
Normal file
78
pyscript.core/test/panel/panel.py
Normal file
@@ -0,0 +1,78 @@
|
||||
import json
|
||||
|
||||
import js
|
||||
import panel as pn
|
||||
from js import JSON
|
||||
from panel.io.pyodide import init_doc, write_doc
|
||||
from polyscript import xworker
|
||||
from pyodide.ffi import create_once_callable, create_proxy, to_js
|
||||
from pyscript import document, window
|
||||
|
||||
js.document = document
|
||||
init_doc()
|
||||
|
||||
print("Hello from panel.py")
|
||||
|
||||
slider = pn.widgets.FloatSlider(start=0, end=10, name="Amplitude")
|
||||
|
||||
|
||||
def callback(new):
|
||||
print(f"Amplitude is: {new}")
|
||||
return f"Amplitude is: {new}"
|
||||
|
||||
|
||||
print("made this far...")
|
||||
pn.Row(slider, pn.bind(callback, slider)).servable(target="simple_app")
|
||||
|
||||
# ------ END OF PANEL CODE ------
|
||||
|
||||
docs_json_str, render_items_str, root_ids_str = await write_doc()
|
||||
docs_json = JSON.parse(docs_json_str) # .as_object_map()
|
||||
# render_items = to_js(JSON.parse(render_items_str), depth=-1, pyproxies=None, create_pyproxies=False, dict_converter=js.Object.fromEntries)#.as_object_map()
|
||||
root_ids = JSON.parse(root_ids_str) # .as_object_map()
|
||||
|
||||
# docs_json = json.loads(docs_json_str)
|
||||
render_items = json.loads(render_items_str)
|
||||
# root_ids = json.loads(root_ids_str)
|
||||
|
||||
print(type(render_items))
|
||||
root_elements = document.querySelectorAll("[data-root-id]")
|
||||
data_roots = []
|
||||
for el in root_elements:
|
||||
el.innerHTML = ""
|
||||
data_roots.append([el.getAttribute("data-root-id"), el.id])
|
||||
|
||||
roots = {root_ids[i]: root for i, root in enumerate(data_roots)}
|
||||
|
||||
print("Quick check")
|
||||
print(roots)
|
||||
print(root_ids)
|
||||
print(render_items)
|
||||
# render_items[0]['roots'] = roots
|
||||
# render_items[0]['root_ids'] = root_ids
|
||||
# render_items[0].roots = to_js(roots)
|
||||
# render_items[0].root_ids = to_js(root_ids)
|
||||
|
||||
|
||||
# print(roots)
|
||||
# print(data_roots)
|
||||
print(docs_json)
|
||||
print(render_items)
|
||||
print("here....")
|
||||
|
||||
# views = await window.Bokeh.embed.embed_items(to_js(docs_json), to_js(render_items))
|
||||
views = await window.Bokeh.embed.embed_items(
|
||||
docs_json, # to_js(docs_json, depth=-1, pyproxies=None, create_pyproxies=False, dict_converter=js.Object.fromEntries),
|
||||
to_js(
|
||||
render_items,
|
||||
depth=-1,
|
||||
pyproxies=None,
|
||||
create_pyproxies=False,
|
||||
dict_converter=js.Object.fromEntries,
|
||||
),
|
||||
)
|
||||
|
||||
# Experiments back to main thread
|
||||
# await xworker.sync.render_full(docs_json_str, render_items_str, root_ids_str)
|
||||
print("made it to the end")
|
||||
print(docs_json)
|
||||
5
pyscript.core/test/panel/panel.toml
Normal file
5
pyscript.core/test/panel/panel.toml
Normal file
@@ -0,0 +1,5 @@
|
||||
packages = [
|
||||
"https://cdn.holoviz.org/panel/0.14.3/dist/wheels/bokeh-2.4.3-py3-none-any.whl",
|
||||
"numpy",
|
||||
"panel==0.14.1"
|
||||
]
|
||||
71
pyscript.core/test/panel/panel_worker.html
Normal file
71
pyscript.core/test/panel/panel_worker.html
Normal file
@@ -0,0 +1,71 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Panel Example</title>
|
||||
<meta charset="iso-8859-1" />
|
||||
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||
</head>
|
||||
<body>
|
||||
<section class="pyscript">
|
||||
<div id="simple_app"></div>
|
||||
|
||||
<py-tutor>
|
||||
<script defer src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
||||
<script defer src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
||||
<script defer src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/@holoviz/panel@0.14.1/dist/panel.min.js"></script>
|
||||
|
||||
<script type="module" src="../../core.js"></script>
|
||||
<!-- <script
|
||||
type="module"
|
||||
src="https://esm.sh/@pyscript/core@latest/core.js"
|
||||
></script> -->
|
||||
|
||||
<script type="py" worker="./panel.py" config="./panel.toml" async></script>
|
||||
|
||||
<!-- Code below borrowed for reference from example working on polyscript directly -->
|
||||
<!-- <script type="micropython">
|
||||
from pyscript import PyWorker
|
||||
import json
|
||||
import js
|
||||
|
||||
w = PyWorker('./panel.py', **{'type': 'pyodide', 'async': True, 'config': './panel.toml'})
|
||||
|
||||
# xworker.window made the following completely unnecessary
|
||||
document = js.document
|
||||
|
||||
async def render_full(docs_json_str, render_items_str, root_ids_str):
|
||||
docs_json = json.loads(docs_json_str)
|
||||
render_items = json.loads(render_items_str)
|
||||
root_ids = json.loads(root_ids_str)
|
||||
|
||||
print(type(render_items))
|
||||
root_elements = document.querySelectorAll('[data-root-id]')
|
||||
data_roots = []
|
||||
for el in root_elements:
|
||||
el.innerHTML = ''
|
||||
data_roots.append([el.getAttribute('data-root-id'), el.id])
|
||||
|
||||
roots = {root_ids[i]: root for i, root in enumerate(data_roots)}
|
||||
|
||||
print("Quick check")
|
||||
render_items[0]['roots'] = roots
|
||||
render_items[0]['root_ids'] = root_ids
|
||||
print("here....")
|
||||
views = await js.Bokeh.embed.embed_items(docs_json, render_items)
|
||||
|
||||
|
||||
def render(docs_json, render_items):
|
||||
print(f"GOT DATA: {docs_json}")
|
||||
print(f"GOT ITEMS: {render_items}")
|
||||
|
||||
await js.Bokeh.embed.embed_items(json.loads(docs_json), json.loads(render_items))
|
||||
# views = await xworker.window.Bokeh.embed.embed_items(create_proxy(docs_json), create_proxy(render_items))
|
||||
|
||||
w.sync.render = render
|
||||
w.sync.render_full = render_full
|
||||
|
||||
</script> -->
|
||||
</py-tutor>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -545,7 +545,9 @@ class PyScriptTest:
|
||||
- wait until pyscript has been fully loaded
|
||||
"""
|
||||
doc = self._pyscript_format(
|
||||
snippet, execution_thread=self.execution_thread, extra_head=extra_head
|
||||
snippet,
|
||||
execution_thread=self.execution_thread,
|
||||
extra_head=extra_head,
|
||||
)
|
||||
if not wait_for_pyscript and timeout is not None:
|
||||
raise ValueError("Cannot set a timeout if wait_for_pyscript=False")
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
import pytest
|
||||
|
||||
from .support import PyScriptTest
|
||||
|
||||
pytest.skip(reason="NEXT: Restore the banner", allow_module_level=True)
|
||||
from .support import PyScriptTest, skip_worker
|
||||
|
||||
|
||||
class TestWarningsAndBanners(PyScriptTest):
|
||||
# Test the behavior of generated warning banners
|
||||
|
||||
def test_deprecate_loading_scripts_from_latest(self):
|
||||
# Use a script tag with an invalid output attribute to generate a warning, but only one
|
||||
self.pyscript_run(
|
||||
"""
|
||||
<script type="py">
|
||||
print("whatever..")
|
||||
</script>
|
||||
""",
|
||||
extra_head='<script type="ignore-me" src="https://pyscript.net/latest/any-path-triggers-the-warning-anyway.js"></script>',
|
||||
)
|
||||
|
||||
# wait for the banner to appear (we could have a page.locater call but for some reason
|
||||
# the worker takes to long to render on CI, since it's a test we can afford 2 calls)
|
||||
loc = self.page.wait_for_selector(".py-error")
|
||||
assert (
|
||||
loc.inner_text()
|
||||
== "Loading scripts from latest is deprecated and will be removed soon. Please use a specific version instead."
|
||||
)
|
||||
|
||||
# Only one banner should appear
|
||||
loc = self.page.locator(".py-error")
|
||||
assert loc.count() == 1
|
||||
|
||||
@pytest.mark.skip("NEXT: To check if behaviour is consistent with classic")
|
||||
def test_create_singular_warning(self):
|
||||
# Use a script tag with an invalid output attribute to generate a warning, but only one
|
||||
self.pyscript_run(
|
||||
|
||||
1
pyscript.core/types/plugins.d.ts
vendored
1
pyscript.core/types/plugins.d.ts
vendored
@@ -1,4 +1,5 @@
|
||||
declare const _default: {
|
||||
"deprecations-manager": () => Promise<typeof import("./plugins/deprecations-manager.js")>;
|
||||
error: () => Promise<typeof import("./plugins/error.js")>;
|
||||
"py-terminal": () => Promise<typeof import("./plugins/py-terminal.js")>;
|
||||
};
|
||||
|
||||
1
pyscript.core/types/plugins/deprecations-manager.d.ts
vendored
Normal file
1
pyscript.core/types/plugins/deprecations-manager.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
Reference in New Issue
Block a user