

















addEventListener is what creates a reference in JS to that object



p.canvas.oncontextmenu = lambda e: False
Perhaps on...() type events are an exception? (edited)


create_proxy() isn't always necessary. Pyodide is always either proxying or converting objects between Python and JS whenever objects get passed. create_proxy is just a useful sledgehammer when for some reason Pyodide either unwraps something incorrectly (so it can't be accessed/called) or it's referenced in such a way that it would normally be garbage collected/freed before the other language has a chance to access it
element.write to work with Rich. Might be of interest to those trying similar adaptations: https://jeff.glass/post/pyscript-rich/


paths to access arbirary files. I wonder whether we should call it files = [...] then
fetch-to-localโฆ isnโt great but maybe more descriptive than paths
files = ['./a.py', 'foo/b.py'], it's obvious that b.py should be written in the foo directory of the virtual FS
paths takes is already URLs, itโs just that most folks are using them for only relative URLswith open(โa.pyโ, โrโ) as fp:
print(fp.read())
with open(โb.pyโ, โrโ) as fp:
print(fp.read())
Because all objects in paths are copied to the same location as the executing script (edited)






runtimeLoaded store












async are really two different beasts, and the fact that they are semantically so similar makes things even more confusingasync function, it is automatically scheduled and added to the event loopasync function is basically a generator, and it will be executed only if you create a task for it


















duckdb can already be compiled to WASM, I am just trying to build it for pyodide. There's an open PR on the pyodide repository for this. I have tried it and was able to build 0.4.0 locally but wasn't able to build 0.6.0. The next step for me is basically contacting pyodide folks about this and hopefully collaborating on this and pushing it forward.

duckdb can already be compiled to WASM, I am just trying to build it for pyodide. There's an open PR on the pyodide repository for this. I have tried it and was able to build 0.4.0 locally but wasn't able to build 0.6.0. The next step for me is basically contacting pyodide folks about this and hopefully collaborating on this and pushing it forward. .csv, .json, or .parquet data files to preview. See DuckDB Client notebook for more info. Database Tables Table Columns Select table: Table Summary Summary of table data using Summary Table Observable cell: Table Data Data Wrangler Query...

















2






pyscript branch of my fork of Textual on GitHub, that has my progress so far: https://github.com/JeffersGlass/textual/tree/pyscript












































webserialdemo.py. Do you have the contents of that script in a file on your server? (and/or are you opening the example locally?)

webserialdemo.py. Do you have the contents of that script in a file on your server? (and/or are you opening the example locally?)

webserialdemo.py. Do you have the contents of that script in a file on your server? (and/or are you opening the example locally?) 

<py-script> tag and remove the src attribute 

<py-script> tag and remove the src attribute 

src attribute fetches a remote (python) file and executes the contents as Python code, similar to a <script> tag's src attribute. If your browser can't find that resource on the network (could be a webserver, or a simple local testing server [1]), it will error with a 404 like you saw.
One workaround is to just make all the code inline/on the page.
[1] https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server




1






<py-script async src="..."> which will automatically run with top-level await using runPythonAsync https://pyodide.org/en/stable/usage/api/js-api.html#pyodide.runPythonAsync (edited)

thenables or python coroutines from either language, if that helps your current awkward dance any.












<script> tag in the head of the document






































rich._console = RichConsole(color_system="truecolor"). You've done a great job rolling your own coloring, that's just another option

























widgets.py:Widget has some similarities to what I did.
One thing I wasn't sure of with tlk is how you can mix and match widgets and regular DOM elements. Eg, can you create a DOM element inside a widget, then another widget inside that normal DOM element, or do all descendants of an ltk widget have to be widgets themselves?

ltk.VBox(ltk.Div(...))




@app.page()
class LtkPage(Page):
def initial(self):
return {"name": ""}
def populate(self):
with t.div():
self.input_element = ltk.Input(self.state["name"])
self.input_element.on("click", ltk.callback(self.on_data_input))
t(self.input_element.element.get(0))
t(ltk.Heading1(f"Hello, {self.state['name']}").element.get(0))
def on_data_input(self, event):
self.state["name"] = event.target.value
print("INPUT", event, event.target, event.target.value)
Here's the problem though. You can't mix and match exactly, because ltk won't know how to render PuePy components if you try to add them as nested components inside ltk.
Maybe I should have approached everything more as a web component, but web components lack reactivity (unless you add that yourself) and I don't find the way slots work as succinct in web componenets.
But I could also point out, if you took all the ltk widgets and just made thin wrappers so they were themselves web components, you could use them to your heart's content in PuePy. That might be the best way to go, though I'm not sure how easy it is to mix jquery (which ltk uses) and web components. (edited)t(self.input_element.get(0)) part tells puepy to mount that html element onto its graph, though since it's just a regular DOM element, you can't do any further nesting inside PuePy...
I'll try to get that added in a more formal way this weekend. PuePy isn't my day job. 

















while True: pass; in your code would make the whole thing unresponsive ... am I correct?

while True: pass; in your code would make the whole thing unresponsive ... am I correct? 


























main.py you will find the usage of the Hiccup syntax. Hiccup is about representing HTML in Python. Using list or tuple to represent HTML elements, and dict to represent the element attributes.
https://pyscript.com/@davidvujic/pyscript-jokes-with-a-hiccup/ (edited)


















py-game as <script type=".."> ?

py-game as <script type=".."> ? webwindow
The pygame_window code I have on there is written as a webwindow protocol and was just for running natively, for easier dev/testing to save having to reload things in the browser - the browser version that's running in pyscript runs fully with zengl/webwindow, and only uses pygame for a bit for rect/vector/image loading stuff.
Wasn't sure if py-game script type supports running with OpenGL context? I will try it out for my next project if so!

webwindow
The pygame_window code I have on there is written as a webwindow protocol and was just for running natively, for easier dev/testing to save having to reload things in the browser - the browser version that's running in pyscript runs fully with zengl/webwindow, and only uses pygame for a bit for rect/vector/image loading stuff.
Wasn't sure if py-game script type supports running with OpenGL context? I will try it out for my next project if so! 
script type="py-game" using zengl WebGL context.
It crashes with the attached errors. (it runs fine with script type="py" and using https://github.com/szabolcsdombi/webwindow)
Looks like the error originates from this file within ZenGL https://github.com/szabolcsdombi/zengl/blob/main/zengl.js
Let me know if you wanted any more info from the console error message drop down frames (edited)
script type="py" , zengl.Image buffers with format="r32float" (used for shadow map texture) don't seem to work, and have to use a less efficient "rgba8unorm" format instead. seems that pygbag does work fine with the "r32float" format though (edited)

script type="py" , zengl.Image buffers with format="r32float" (used for shadow map texture) don't seem to work, and have to use a less efficient "rgba8unorm" format instead. seems that pygbag does work fine with the "r32float" format though (edited)py-game ... at the end of the day py-game is literally just py with py-game-ce currently implicitly used as dependency ... there's not much else going on in there, but I start thinking that's also not a good reason enough to have a dedicated type, if it also doesn't work as expected

py-game ... at the end of the day py-game is literally just py with py-game-ce currently implicitly used as dependency ... there's not much else going on in there, but I start thinking that's also not a good reason enough to have a dedicated type, if it also doesn't work as expected pygame.display.set_mode(..., flags=pygame.OPENGL) version, so its a fairly niche issue. would be cool if it worked though.
I guess py-game would maybe need a similar implementation to what the JS string in the webwindow/webwindow.py library is doing, to hook onto the GL context. but that might be out of scope for it

pygame.display.set_mode(..., flags=pygame.OPENGL) version, so its a fairly niche issue. would be cool if it worked though.
I guess py-game would maybe need a similar implementation to what the JS string in the webwindow/webwindow.py library is doing, to hook onto the GL context. but that might be out of scope for it 




logging to logging_console ( name tbd) reults in a console log that has the same levels ( not just info ) and can be filtered on that same level by just about any browser.
And Tracebacks with actual useful info on where the problem is import logging_console as logging
logging.basicConfig(level=logging.INFO )
logging.getLogger().addHandler(logging.PyscriptHandler())
log = logging.getLogger()
# keep default handler only for critical logs
for handler in logging.getLogger().handlers:
if not isinstance(handler, logging.PyscriptHandler):
handler.setLevel(logging.CRITICAL)
log.debug("test - debug") # ignored by default
log.info("test - info")
log.warning("test - warning")
log.error("test - error")
log.critical("test - critical")
try:
1 / 0
except Exception as e:
log.exception("OOPS", exc_info=e) (edited)


settrace - the thing needed for us to implement a generic PyScript debugger and visibility into the performance of code. 

settrace - the thing needed for us to implement a generic PyScript debugger and visibility into the performance of code. 