





















































<py-inputbox id="n">10</py-inputbox> like this?

<script>
window.addEventListener('load', function() {
let input_box = document.querySelector("#new-task-content")
input_box.value = "hello"
})
</script>
You can use this just change new-task-content to whatever id your py-inputbox has and hello to value you want it to be
#newtask vs newtask?


.newtask





<py-script> output?

<py-script> output? 
import warnings
warnings.filterwarnings("ignore") doesn't do it
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()








from js import document, console
from pyodide import create_proxy
def _log_to_console(e):
form = document.getElementById("my_form")
for elem in form.elements:
console.log(elem.name + ":" + elem.value)
#Stop page from submitting/refreshing
e.preventDefault()
e.stopPropagation()
return False
logToConsole = create_proxy(_log_to_console)
document.getElementById("my_form").addEventListener("submit", logToConsole)


import os, sys
sys.stderr = open(os.devnull, "w") 





Hello world request example!
Here is the output of your request:
JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/asyncio/futures.py", line 201, in result raise self._exception File "/lib/python3.10/asyncio/tasks.py", line 232, in __step result = coro.send(None) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 500, in eval_code_async await CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 353, in run_async await coroutine File "", line 3, in ModuleNotFoundError: No module named 'request' )
You can also use other methods. See fetch documentation:
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
See pyodide documentation for what to do with a FetchResponse object:
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
i use pythonanywhere

Hello world request example!
Here is the output of your request:
JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/asyncio/futures.py", line 201, in result raise self._exception File "/lib/python3.10/asyncio/tasks.py", line 232, in __step result = coro.send(None) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 500, in eval_code_async await CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 353, in run_async await coroutine File "", line 3, in ModuleNotFoundError: No module named 'request' )
You can also use other methods. See fetch documentation:
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
See pyodide documentation for what to do with a FetchResponse object:
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
i use pythonanywhere 
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- paths:
- request.py
</py-env>
</head>
<body><p>
Hello world request example! <br>
Here is the output of your request:
</p>
<py-script>
import asyncio # important!!
import json
from request import request
baseurl = "https://jsonplaceholder.typicode.com/"
# GET
headers = {"Content-type": "application/json"}
response = await request(baseurl+"posts/2", method="GET", headers=headers)
print(f"GET request=> status:{response.status}, json:{await response.json()}")
# POST
body = json.dumps({"title":"test_title", "body":"test body", "userId":1})
new_post = await request(baseurl+"posts", body=body, method="POST", headers=headers)
print(f"POST request=> status:{new_post.status}, json:{await new_post.json()}")
# PUT
body = json.dumps({"id":1, "title":"test_title", "body":"test body", "userId":2})
new_post = await request(baseurl+"posts/1", body=body, method="PUT", headers=headers)
print(f"PUT request=> status:{new_post.status}, json:{await new_post.json()}")
# DELETE
new_post = await request(baseurl+"posts/1", method="DELETE", headers=headers)
print(f"DELETE request=> status:{new_post.status}, json:{await new_post.json()}")
</py-script>
<div>
<p>
You can also use other methods. See fetch documentation: <br>
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
</p>
</div>
<div>
<p>
See pyodide documentation for what to do with a FetchResponse object: <br>
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
</p>
</div>
</body>
</html>
</html> (edited)
.py from request.py and change request to requests

.py from request.py and change request to requests 

<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- paths:
- requests
</py-env>
</head>
<body><p>
Hello world request example! <br>
Here is the output of your request:
</p>
<py-script>
import asyncio # important!!
import json
from request import request
baseurl = "https://jsonplaceholder.typicode.com/"
# GET
headers = {"Content-type": "application/json"}
response = await request(baseurl+"posts/2", method="GET", headers=headers)
print(f"GET request=> status:{response.status}, json:{await response.json()}")
# POST
body = json.dumps({"title":"test_title", "body":"test body", "userId":1})
new_post = await request(baseurl+"posts", body=body, method="POST", headers=headers)
print(f"POST request=> status:{new_post.status}, json:{await new_post.json()}")
# PUT
body = json.dumps({"id":1, "title":"test_title", "body":"test body", "userId":2})
new_post = await request(baseurl+"posts/1", body=body, method="PUT", headers=headers)
print(f"PUT request=> status:{new_post.status}, json:{await new_post.json()}")
# DELETE
new_post = await request(baseurl+"posts/1", method="DELETE", headers=headers)
print(f"DELETE request=> status:{new_post.status}, json:{await new_post.json()}")
</py-script>
<div>
<p>
You can also use other methods. See fetch documentation: <br>
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
</p>
</div>
<div>
<p>
See pyodide documentation for what to do with a FetchResponse object: <br>
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
</p>
</div>
</body>
</html>
</html>



<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- paths:
- requests
</py-env>
</head>
<body><p>
Hello world request example! <br>
Here is the output of your request:
</p>
<py-script>
import asyncio # important!!
import json
from request import request
baseurl = "https://jsonplaceholder.typicode.com/"
# GET
headers = {"Content-type": "application/json"}
response = await request(baseurl+"posts/2", method="GET", headers=headers)
print(f"GET request=> status:{response.status}, json:{await response.json()}")
# POST
body = json.dumps({"title":"test_title", "body":"test body", "userId":1})
new_post = await request(baseurl+"posts", body=body, method="POST", headers=headers)
print(f"POST request=> status:{new_post.status}, json:{await new_post.json()}")
# PUT
body = json.dumps({"id":1, "title":"test_title", "body":"test body", "userId":2})
new_post = await request(baseurl+"posts/1", body=body, method="PUT", headers=headers)
print(f"PUT request=> status:{new_post.status}, json:{await new_post.json()}")
# DELETE
new_post = await request(baseurl+"posts/1", method="DELETE", headers=headers)
print(f"DELETE request=> status:{new_post.status}, json:{await new_post.json()}")
</py-script>
<div>
<p>
You can also use other methods. See fetch documentation: <br>
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
</p>
</div>
<div>
<p>
See pyodide documentation for what to do with a FetchResponse object: <br>
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
</p>
</div>
</body>
</html>
</html>
PyScript: Loading from file requests failed with error 404 (File not Found). Are your filename and path are correct?
Hello world request example!
Here is the output of your request:
JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/asyncio/futures.py", line 201, in result raise self._exception File "/lib/python3.10/asyncio/tasks.py", line 232, in __step result = coro.send(None) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 500, in eval_code_async await CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 353, in run_async await coroutine File "", line 3, in ModuleNotFoundError: No module named 'request' )
You can also use other methods. See fetch documentation:
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
See pyodide documentation for what to do with a FetchResponse object:
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- requests
</py-env>
</head>
<body>
<py-script>
import requests
r = requests.get("https://google.com")
</py-script>
</body>
</html>blah blah blah..... (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) )
So yea as stated by @DennisChou it wont work as SSL is required + there was same issue with mysql connectivity too! So ig we have to wait for PyScript team to add something like async http.pyfetch as in pyodide

<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- paths:
- requests
</py-env>
</head>
<body><p>
Hello world request example! <br>
Here is the output of your request:
</p>
<py-script>
import asyncio # important!!
import json
from request import request
baseurl = "https://jsonplaceholder.typicode.com/"
# GET
headers = {"Content-type": "application/json"}
response = await request(baseurl+"posts/2", method="GET", headers=headers)
print(f"GET request=> status:{response.status}, json:{await response.json()}")
# POST
body = json.dumps({"title":"test_title", "body":"test body", "userId":1})
new_post = await request(baseurl+"posts", body=body, method="POST", headers=headers)
print(f"POST request=> status:{new_post.status}, json:{await new_post.json()}")
# PUT
body = json.dumps({"id":1, "title":"test_title", "body":"test body", "userId":2})
new_post = await request(baseurl+"posts/1", body=body, method="PUT", headers=headers)
print(f"PUT request=> status:{new_post.status}, json:{await new_post.json()}")
# DELETE
new_post = await request(baseurl+"posts/1", method="DELETE", headers=headers)
print(f"DELETE request=> status:{new_post.status}, json:{await new_post.json()}")
</py-script>
<div>
<p>
You can also use other methods. See fetch documentation: <br>
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
</p>
</div>
<div>
<p>
See pyodide documentation for what to do with a FetchResponse object: <br>
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
</p>
</div>
</body>
</html>
</html>
PyScript: Loading from file requests failed with error 404 (File not Found). Are your filename and path are correct?
Hello world request example!
Here is the output of your request:
JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/asyncio/futures.py", line 201, in result raise self._exception File "/lib/python3.10/asyncio/tasks.py", line 232, in __step result = coro.send(None) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 500, in eval_code_async await CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 353, in run_async await coroutine File "", line 3, in ModuleNotFoundError: No module named 'request' )
You can also use other methods. See fetch documentation:
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
See pyodide documentation for what to do with a FetchResponse object:
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse 










JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/site-packages/_pyodide/_base.py", line 421, in eval_code CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 237, in __init__ self.ast = next(self._gen) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 141, in _parse_and_compile_gen mod = compile(source, filename, mode, flags | ast.PyCF_ONLY_AST) File "", line 1 ^ SyntaxError: invalid syntax ){% extends "layout.html" %} {% block content %}
<div class="home">
<h1>Generator</h1>
<p>nantoka nantoka</p>
<py-env>
- pandas
</py-env>
<p id="csv"></p>
<py-script src="/myscript.py"></py-script>
</div>
{% endblock %}
And here's my python code
import pandas as pd
from pyodide.http import open_url
df = pd.read_csv(open_url("https://raw.githubusercontent.com/fromwindowstolinux/Python-Projects/main/Flask%20Project/manga.csv"))
csv = Element("csv")
csv.write(df.head())line 1 ^ SyntaxError: invalid syntax, I've checked, and seems nothing wrong? Or I should be looking at something else?

{% extends "layout.html" %} {% block content %}
<div class="home">
<h1>Generator</h1>
<p>nantoka nantoka</p>
<py-env>
- pandas
</py-env>
<p id="csv"></p>
<py-script src="/myscript.py"></py-script>
</div>
{% endblock %}
And here's my python code
import pandas as pd
from pyodide.http import open_url
df = pd.read_csv(open_url("https://raw.githubusercontent.com/fromwindowstolinux/Python-Projects/main/Flask%20Project/manga.csv"))
csv = Element("csv")
csv.write(df.head()) 


JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/site-packages/_pyodide/_base.py", line 421, in eval_code CodeRunner( File "/lib/python3.10/site-packages/_pyodide/_base.py", line 237, in __init__ self.ast = next(self._gen) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 141, in _parse_and_compile_gen mod = compile(source, filename, mode, flags | ast.PyCF_ONLY_AST) File "", line 1 ^ SyntaxError: invalid syntax ) src="/myscript.py" ? could be "./myscript.py" ?


/myscripy.py or ./myscript.py could be correct.


pyodide.asm.js:14 Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/lib/python3.10/asyncio/futures.py", line 201, in result
raise self._exception
File "/lib/python3.10/asyncio/tasks.py", line 234, in __step
result = coro.throw(exc)
File "/lib/python3.10/site-packages/micropip/_micropip.py", line 183, in install
transaction = await self.gather_requirements(requirements, ctx, keep_going)
File "/lib/python3.10/site-packages/micropip/_micropip.py", line 173, in gather_requirements
await gather(*requirement_promises)
File "/lib/python3.10/asyncio/futures.py", line 284, in __await__
yield self # This tells Task to wait for completion.
File "/lib/python3.10/asyncio/tasks.py", line 304, in __wakeup
future.result()
File "/lib/python3.10/asyncio/futures.py", line 201, in result
raise self._exception
File "/lib/python3.10/asyncio/tasks.py", line 232, in __step
result = coro.send(None)
File "/lib/python3.10/site-packages/micropip/_micropip.py", line 291, in add_requirement
await self.add_wheel(
File "/lib/python3.10/site-packages/micropip/_micropip.py", line 316, in add_wheel
await self.add_requirement(recurs_req, ctx, transaction)
File "/lib/python3.10/site-packages/micropip/_micropip.py", line 286, in add_requirement
raise ValueError(
ValueError: Couldn't find a pure Python 3 wheel for 'tokenizers!=0.11.3,<0.13,>=0.11.1'. You can use `micropip.install(..., keep_going=True)` to get a list of all packages with missing wheels. (edited)
tokenizers package is written mostly in rust, with Python bindings over the top. Pyodide (which PyScript uses to run Python) pretty much only runs pure-Python packages, or ones specifically compiled into Web Assembly for the browser.






hello world so this stuff was much advance than that!

























<style> input{ border-width: 4px; } </style>
<body>
<p>Type a string here to save it to file:</p>
<label for="Type a password here:"></label><input type="text" id="pwd">
<br><br>
<p>File name: </p>
<head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<label for="Type a password here:"></label><input type="text" id="filename">
<button id="download">Download</button>
<py-script>
from js import document, Blob, window
from pyodide import create_proxy
def _download_contents_of_field(field_name):
text_to_save = document.getElementById("pwd").value
blob_of_text = Blob.new(([text_to_save]))
url = window.URL.createObjectURL(blob_of_text)
file_name = document.getElementById("filename").value
link = document.createElement("a");
link.download = file_name;
link.href = url;
link.click()
download_contents_of_field = create_proxy(_download_contents_of_field)
document.getElementById("download").addEventListener("click", download_contents_of_field)
</py-script>
</body> (edited)_download_contents_of_field gets the value from the password field, turns it into a "blob" object, creates a download link to that blob of text (that link lives nowhere on the page yet, but that's fine), then clicks that link




<script defer src="https://pyscript.net/alpha/pyscript.js"></script>










































<body>
<button class='rslt' id="rslt" pys-onClick="run_this">Click here!</button>
<div id="output"></div>
<py-script>
def run_this(self):
pyscript.write('output', 'Hello World')
</py-script>
</body>














main.ts file, we can see that the current pyscript tags are: py-script py-repl py-env py-box py-button py-title py-inputbox py-register-widget py-loader and py-config. (edited)

main.ts file, we can see that the current pyscript tags are: py-script py-repl py-env py-box py-button py-title py-inputbox py-register-widget py-loader and py-config. (edited)
py-loader is what causes the semi-transparent "loading runtime" overlay on the screen while the runtime loads.





main.ts file, we can see that the current pyscript tags are: py-script py-repl py-env py-box py-button py-title py-inputbox py-register-widget py-loader and py-config. (edited)

py-loader is what causes the semi-transparent "loading runtime" overlay on the screen while the runtime loads. 




<html>
<head>
<title>Matplotlib</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- matplotlib
- scikit-image
- numpy
</py-env>
</head>
<body>
<div id="mpl"></div>
<py-script output="mpl">
from skimage import data
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
ax1.imshow(data.camera(), cmap="gray")
fig2, ax2 = plt.subplots()
ax2.imshow(data.cat())
fig1
fig2
</py-script>
</body>
</html>

<html>
<head>
<title>Matplotlib</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- matplotlib
- scikit-image
- numpy
</py-env>
</head>
<body>
<div id="mpl"></div>
<py-script output="mpl">
from skimage import data
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
ax1.imshow(data.camera(), cmap="gray")
fig2, ax2 = plt.subplots()
ax2.imshow(data.cat())
fig1
fig2
</py-script>
</body>
</html> print(fig1)
print(fig2)

Figure(640x480)
Figure(640x480)
<html>
<head>
<title>Matplotlib</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- matplotlib
- scikit-image
- numpy
</py-env>
</head>
<body>
<div id="mpl"></div>
<div id="mpl2"></div>
<py-script>
from skimage import data
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
ax1.imshow(data.camera(), cmap="gray")
fig2, ax2 = plt.subplots()
ax2.imshow(data.cat())
pyscript.write("mpl",fig1)
pyscript.write("mpl2",fig2)
</py-script>
</body>
</html> (edited)

<html>
<head>
<title>Matplotlib</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- matplotlib
- scikit-image
- numpy
</py-env>
</head>
<body>
<div id="mpl"></div>
<div id="mpl2"></div>
<py-script>
from skimage import data
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
ax1.imshow(data.camera(), cmap="gray")
fig2, ax2 = plt.subplots()
ax2.imshow(data.cat())
pyscript.write("mpl",fig1)
pyscript.write("mpl2",fig2)
</py-script>
</body>
</html> (edited)
<html lang="en">
<head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<p id="x"></p>
<py-button label="add one">
def on_click(event):
global x # need to declare global
x+=1
pyscript.write('x', x)
</py-button>
<py-script>
x=0
pyscript.write('x',x)
</py-script>
</html>



<html>
<head>
<title>Matplotlib</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- matplotlib
- scikit-image
- numpy
</py-env>
</head>
<body>
<div id="mpl"></div>
<py-script output="mpl">
from skimage import data
import matplotlib.pyplot as plt
fig1, ax1 = plt.subplots()
ax1.imshow(data.camera(), cmap="gray")
fig2, ax2 = plt.subplots()
ax2.imshow(data.cat())
fig1
fig2
</py-script>
</body>
</html> 







<input> item within your html, then using either a py-button or a regular <button> to read its contents and display your output to the screen
Edit: There's also py-inputbox, which seems like it will be very useful to you when it supports the keydown event https://realpython.com/pyscript-python-in-browser/#pyinputbox (edited)<input>, then when the button below it is clicked, reading its contents and acting on the https://jeff.glass/post/7-guis-pyscript/#flight-header\
input() in the future. This is supported upstream by Pyodide, but not yet by Pyscript. https://github.com/pyscript/pyscript/issues/502





import js
from js import document
def main():
msg = document.getElementById("msg")
msg.innerHTML = 'Hello world'
main()
running this example locally with normal python will as expected bring the error:
ModuleNotFoundError: No module named 'js'
To make this work both ways, one could e.g. add try-except blocks:
try:
import js
from js import document
except ModuleNotFoundError:
pass
def main():
my_string = "Hello World"
try:
msg = document.getElementById("msg")
msg.innerHTML = my_string
except NameError:
print(my_string)
main()
But is there maybe a better way to do this? (edited)

import sys
if "pyodide" in sys.modules:
# running in Pyodide
and
import platform
if platform.system() == 'Emscripten':
# running in Pyodide or other Emscripten based build
print("<em>Hello</em>") renders without the <em> tag being applied)

py-script tag or a py-repl?<em> tags working in the REPL2 example
print() inside a pyscript tag, though they do work within a REPL...

### my_string_file.py
formatted_string = "<em>Hello, world!</em>
### my_page.html
<py-env>
- paths:
- ./my_string_file.py
</py-env>
<py-script>
import my_string_file
print(my_string_file.formatted_string)
</py-script>
Output: Hello, world! (edited)

requests working, however, I'm unable to get a working demo in-side of py-script despite the other getting it to work inside a pyodide demo.
I essentially git clone'd this and manually built a wheel so I could reference the specific branch of this repo as apart of my <py-env>. It gets really close until I get to a JsException: NetworkError: Failed to execute 'send' on 'XMLHttpRequest'
I'm reaching my limits here but I'm wondering if atleast this may be useful to y'all and perhaps we can explore this together.requests functionality so that other libraries can function!

requests functionality so that other libraries can function! 

requests will instantly not work in pyodide. there are different levels of shimming and hacks to get things working, whether someone patches the requests library or figures out some solution to the core http.client.
the main benefit for getting something like a shim'd requests isn't for normal use-case, but mostly to make nice with other libraries which use it.

requests more than just blocking / async stuff, particularly, it's based in sockets which don't make sense at all in a browser (or so I read from other threads).














<div id="id_div"></div>
<py-script>
div = Element("id_div")
html_card = create("div", classes="alert alert-success")
html_card.element.innerHTML = "<strong>Success!</strong> This alert could indicate a successful or positive action"
_ = div.element.appendChild(html_card.element)
</py-script>
Though personally, I think that's a little harder to read than just using some of the node attributes/methods directly:
<div id="id_div"></div>
<py-script>
card = document.createElement("div")
card.classList.add("alert", "alert-success")
card.innerHTML = "<strong>Success!</strong> This alert could indicate a successful or positive action"
_ = document.getElementById("id_div").appendChild(card)
</py-script>
_ = ... at the end of each block is to prevent Pyscript printing the return value of the final statement




pretty-midi, but it seems like it is not possible since it is not a pure python3 wheel


__init__.py file. For example, I have my html page, which gets its functionality from a main python file, like so: <py-script src="./main.py"></py-script>. That part works fine, but when that main.py file imports from a module like from my_module import my_function, then it fails. I have put a py-env tag in the head of the html file, which looks like this:<py-env>
- pandas
- paths:
- ./my_module
</py-env> in which mymodule is a folder containing an `_init.py` file. Pandas gets imported fine, but the my_module part produces a ModuleNotFound error. (edited)
<py-env>
- package1
- package1
</py-env>
Just read that to add packages you need this in your code. But I dont get the part where it says how to add packages that are not from the standard library.import json
import requests
from ruamel.yaml import YAML
import os
import time
import capitalize
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<h1>PyScript - HTTP Requests pyfetch</h1>
<label for="example">Let's submit some text</label>
<input type="text" id="test-input">
<input type="submit" value="Send">
<div id="request_output"></div>
<input type="text" id="test-input">
<py-button on_click>
<py-script>
from pyodide.http import pyfetch
import asyncio
varName = Element('test-input').element.value
varURL = "https://api.agify.io?name=" + varName
response = await pyfetch(url=varURL, method="GET")
output = f"{await response.json()}"
print(output)
</py-script>
</py-button>
</body>
</html> (edited)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<h1>PyScript - HTTP Requests pyfetch</h1>
<label for="example">Let's submit some text</label>
<input type="text" id="test-input">
<input type="submit" value="Send">
<div id="request_output"></div>
<input type="text" id="test-input">
<py-button on_click>
<py-script>
from pyodide.http import pyfetch
import asyncio
varName = Element('test-input').element.value
varURL = "https://api.agify.io?name=" + varName
response = await pyfetch(url=varURL, method="GET")
output = f"{await response.json()}"
print(output)
</py-script>
</py-button>
</body>
</html> (edited)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<h1>PyScript - HTTP Requests pyfetch</h1>
<label for="example">Let's submit some text</label>
<input type="text" id="test-input">
<button id="submit-btn" pys-onClick="submit_request">Submit</button>
<div id="request_output">Response Shown Here</div>
<py-script>
from pyodide.http import pyfetch
import asyncio
async def submit_request(*args):
varName = Element('test-input').element.value
varURL = "https://api.agify.io?name=" + varName
response = await pyfetch(url=varURL, method="GET")
output = f"{await response.json()}"
pyscript.write('request_output',output)
</py-script>
</body>
</html>

__init__.py file. For example, I have my html page, which gets its functionality from a main python file, like so: <py-script src="./main.py"></py-script>. That part works fine, but when that main.py file imports from a module like from my_module import my_function, then it fails. I have put a py-env tag in the head of the html file, which looks like this:<py-env>
- pandas
- paths:
- ./my_module
</py-env> in which mymodule is a folder containing an `_init.py` file. Pandas gets imported fine, but the my_module part produces a ModuleNotFound error. (edited)fetchs them one by one, and copies them into the same location in the browserโs virtual file system as the Python script is running in. The import statement finds other scripts in the same folder, but of course this breaks modules (edited)

get = requests.get(url,params={'key':'value'})
where get_params is a dictionary of information that I want; and when making a put request, I could have
put = requests.put(url,data={'key':'value'},headers={"Content-Type":"application/json"})
So, what are the equivalents of params, data, and headers for pyfetch? (edited)

get = requests.get(url,params={'key':'value'})
where get_params is a dictionary of information that I want; and when making a put request, I could have
put = requests.put(url,data={'key':'value'},headers={"Content-Type":"application/json"})
So, what are the equivalents of params, data, and headers for pyfetch? (edited)method key within the init argument to Pyfetch (its second argument).
Data can be including under the body key of the same unit object; similarly for headers.
Params can be passed in several ways, including by โmanuallyโ appending them to the request URL, but I believe within JS the current preferred way is using a URLSearchParams object, which takes a literal string or a sequence of key/value pairs - itโs toString() is the properly formatted params https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams

has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. I understand the general reason why this error appears, but the thing is, when I make the exact same request with the python requests module, it has no problem and makes the request just fine. I was wondering if maybe there is something to do with pyfetch that requires extra permissions or something? I am using an API key and a client ID to make this request, if that is relevant.
mode: cors to the init object? (edited)

JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/site-packages/_pyodide/_base.py", line 429, in eval_code .run(globals, locals) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 300, in run coroutine = eval(self.code, globals, locals) File "", line 5, in ModuleNotFoundError: No module named 'PIL' ) error, i have <py-env>
- Pillow
</py-env> in the html. why is PIL missing?


<py-env>
- Pillow
</py-env>

<py-env>
- Pillow
</py-env> 



www.someothersite.com/... it tries to fetch www.mydomain.com/www.someothersite.com/...




async def imageopenGETBYTES(text):
text = text.replace("\\","/")
text = text.replace("//","/")
text = text.replace("./","")
if( not text.startswith("http") ):
url = f"https://raw.githubusercontent.com/relt-1/WindowCreator/main/{text}"
else:
url = text
response = await pyfetch(url)
if response.status == 200:
return await response.bytes() it is a part from a pillow Image.open conversion































import json
def danm(*args, **kwargs):
username = document.getElementById("username").value
password = document.getElementById("password").value
print(username, password)
#take username and password and check if they are in the json file
#if they are,print user already exists
#if they aren't, add their username and password to the json file
#and print user created
with open(r"E:\codez\spiral\login.json","r") as f:
users = json.load(f)
if username in users:
print("user already exists")
else:
users[username] = password
print("user created")
with open(r"E:\codez\spiral\login.json", "w") as f:
json.dump(users, f)




import json
def danm(*args, **kwargs):
username = document.getElementById("username").value
password = document.getElementById("password").value
print(username, password)
#take username and password and check if they are in the json file
#if they are,print user already exists
#if they aren't, add their username and password to the json file
#and print user created
with open(r"E:\codez\spiral\login.json","r") as f:
users = json.load(f)
if username in users:
print("user already exists")
else:
users[username] = password
print("user created")
with open(r"E:\codez\spiral\login.json", "w") as f:
json.dump(users, f) <py-env> and paths rather than pyfetch directly. For example:
<py-env>
- paths:
- path/on/your_server/to/test.json
</py-env>
<py-script>
import json
with open("test.json","r") as f:
value = json.load(f)
print(value)
</py-script>paths places the located file "in the same folder as" the Python script, so you open the file as you would any adjacent file in Python as simply "test.json" as opposed to "the/fully/qualified/path." You can put fully qualified URL's in the paths section, but there's no guarentee they'll be loaded correctly - paths is intended for files you're hosting that are (relatively) likely to be fetched correctly
python3 bot.py ? and run it on my server? that would..be amazing and be a huge plus to my hosting service im offering!

python3 bot.py ? and run it on my server? that would..be amazing and be a huge plus to my hosting service im offering! 

python3 bot.py ? and run it on my server? that would..be amazing and be a huge plus to my hosting service im offering! 


bot.py is running on your server, youโd need some way for the what the client sees on their web interface to affect the status of behavior of that script. That sounds to me like making API calls to a server, thatโs going to handle those calls and decide how to affect the running scripts
options = {
'series': [44, 55, 13, 43, 22],
'chart': {
'width': 380,
'type': 'pie',
},
'labels': ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'],
'responsive': [{
'breakpoint': 480,
'options': {
'chart': {
'width': 200,
},
'legend': {
'position': 'bottom'
}
}
}]
}
chart = ApexCharts.new(document.querySelector("#chart"), options)
chart.render()
JsException: TypeError: Cannot read properties of undefined (reading 'type') )


options = {
'series': [44, 55, 13, 43, 22],
'chart': {
'width': 380,
'type': 'pie',
},
'labels': ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'],
'responsive': [{
'breakpoint': 480,
'options': {
'chart': {
'width': 200,
},
'legend': {
'position': 'bottom'
}
}
}]
}
chart_el = Element('chart')
chart_el.element.setAttribute('data-options', json.dumps(options))
ApexCharts.initOnLoad()<div id="chart" data-apexcharts data-options="">
</div>

import json
from js import ApexCharts
chart = ApexCharts.new(document.querySelector("#chart"), json.dumps(options))
chart.render()

.py file as src, you were right, that fails with 'cannot read properties of undefined' still

type keyword" issue then



from js import ApexCharts, Object
options = {
'series': [44, 55, 13, 43, 22],
'chart': {
'width': 380,
'type': 'pie',
},
'labels': ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'],
'responsive': [{
'breakpoint': 480,
'options': {
'chart': {
'width': 200,
},
'legend': {
'position': 'bottom'
}
}
}]
}
chart = ApexCharts.new(document.querySelector("#chart"), to_js(options, dict_converter=Object.fromEntries))
chart.render()


















crossorigin="anonymous"








<py-script> tag, so it just dumps the text into the DOM.

<py-script> tag, so it just dumps the text into the DOM. 





# main.py
def something():
print("from python")
<py-script src="./main.py"> </py-script>
<script>
function myFunction(){
something()
}
</script>
^ this doesn't work - Uncaught ReferenceError: something is not definedPython with JavaScript: Bi-directional communication between Python and Javascript objects and namespaces -- how can we achieve this?




customElementsRegistry is a window Global object; an iFrame is another window https://stackoverflow.com/a/67901528<py-script> <py-repl> etc) (edited)<py-script> tag within an iFrame as a Pyscript object (in Typescript) that actually has code that needs to run etc, since it doesn't know there are customElements inside the iframe<!-- hello_world.html -->
...
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<body>
<iframe src="frame.html" title="MyFrame" style="width: 100%;"></iframe>
<py-script>
print(f"{1 + 1 = }")
<py-script>
</body>
...
<!-- frame.html -->
<span>Hello from inside an iframe</span>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<py-script>
from datetime import datetime
now = datetime.now()
now.strftime("%m/%d/%Y, %H:%M:%S")
</py-script> (edited)




// add.mjs
function addTwoNumbers(a, b) {
return a + b;
}
<!-- index.html -->
<script src="add.mjs"></script>
<py-script>
from js import addTwoNumbers
print(f"{addTwoNumbers(1, 2)= }")
</py-script> (edited)import() though, assuming you actually want to do dynamic importsimport() directly?<script> tag with the statements you want to run, and append it to the DOM

import() directly, since it's not a function, just a keyword that looks like a function, but I could be wrong there (edited)


<style> input{ border-width: 4px; } </style>
<body>
<p>Type a string here to save it to file:</p>
<label for="Type a password here:"></label><input type="text" id="pwd">
<br><br>
<p>File name: </p>
<head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<label for="Type a password here:"></label><input type="text" id="filename">
<button id="download">Download</button>
<py-script>
from js import document, Blob, window
from pyodide import create_proxy
def _download_contents_of_field(field_name):
text_to_save = document.getElementById("pwd").value
blob_of_text = Blob.new(([text_to_save]))
url = window.URL.createObjectURL(blob_of_text)
file_name = document.getElementById("filename").value
link = document.createElement("a");
link.download = file_name;
link.href = url;
link.click()
download_contents_of_field = create_proxy(_download_contents_of_field)
document.getElementById("download").addEventListener("click", download_contents_of_field)
</py-script>
</body> (edited)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<!-- <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" /> -->
<title>Download Example</title>
</head>
<body>
<!-- String -->
<label for="string">Type a string here to save it to file:</label>
<br><br>
<input type="text" id="string">
<br><br>
<!-- Filename -->
<label for="filename">File name:</label>
<br><br>
<input type="text" id="filename">
<br><br>
<!-- Download Buttons -->
<button id="download">Download</button>
<div id="notification"></div><py-script>
from js import document, Blob, window
from pyodide import create_proxy
notification_area = Element('notification')
# Creates download function, passes
def _download_contents_of_field(field_name):
# JS grabs id string value, stores it
text_to_save = document.getElementById("string").value
# Saves string value to blob variable
blob_of_text = Blob.new(([text_to_save]))
# Stores blob in url to be made as link
url = window.URL.createObjectURL(blob_of_text)
# JS grabs id filename value, stores it
file_name = document.getElementById("filename").value
# Check inputs are not empty
if not text_to_save == "" and not blob_of_text == "":
# Creates a tag/attribute
link = document.createElement("a")
link.download = file_name
link.href = url
link.click()
notification_area.write('')
else:
notification_area.write('Inputs Empty')
# Download variable stores proxied download function
download_contents_of_field = create_proxy(_download_contents_of_field)
# Gets id download button, waits for click and passes download variable
document.getElementById("download").addEventListener("click", download_contents_of_field)
</py-script>
</body>
</html>

from fpdf import FPDF
import io
from js import document, window, Uint8Array, File
#Some very basic PDF creation, using the example on the fpdf documentation
pdf = FPDF()
pdf.add_page()
pdf.set_font('helvetica', size=12)
pdf.cell(txt="hello world")
#Create a BytesIO object (acts like a file in memory) to hold PDF output
my_stream = io.BytesIO()
#Write bytes of PDF to BytesIO object
pdf.output(my_stream)
#Create new File object (see JS File API).
#Casting to Uint8Array necessary to prevent my_stream's value from being interpretted
#as one giant number
pdf_file = File.new([Uint8Array.new(my_stream.getvalue())], "hello_world.pdf", {"type": "application/pdf"})
#Get a URL to reference this in-memory file object
url = window.URL.createObjectURL(pdf_file)
#Create link (wihtout placing it in DOM) with download attribute, point it at our URL, and click it
link = document.createElement("a")
link.download = 'hello_world.pdf'
link.href = url
link.text = "Download PDF"
_ = document.body.appendChild(link) #assignment prevents Pyodide/pyscript from printing return valuedownload attribute so the file downloads instead of just opening in the browser

from fpdf import FPDF
import io
from js import document, window, Uint8Array, File
#Some very basic PDF creation, using the example on the fpdf documentation
pdf = FPDF()
pdf.add_page()
pdf.set_font('helvetica', size=12)
pdf.cell(txt="hello world")
#Create a BytesIO object (acts like a file in memory) to hold PDF output
my_stream = io.BytesIO()
#Write bytes of PDF to BytesIO object
pdf.output(my_stream)
#Create new File object (see JS File API).
#Casting to Uint8Array necessary to prevent my_stream's value from being interpretted
#as one giant number
pdf_file = File.new([Uint8Array.new(my_stream.getvalue())], "hello_world.pdf", {"type": "application/pdf"})
#Get a URL to reference this in-memory file object
url = window.URL.createObjectURL(pdf_file)
#Create link (wihtout placing it in DOM) with download attribute, point it at our URL, and click it
link = document.createElement("a")
link.download = 'hello_world.pdf'
link.href = url
link.text = "Download PDF"
_ = document.body.appendChild(link) #assignment prevents Pyodide/pyscript from printing return value 

download attribute so the file downloads instead of just opening in the browser 

from fpdf import FPDF
import io
from js import document, window, Uint8Array, File
#Some very basic PDF creation, using the example on the fpdf documentation
pdf = FPDF()
pdf.add_page()
pdf.set_font('helvetica', size=12)
pdf.cell(txt="hello world")
#Create a BytesIO object (acts like a file in memory) to hold PDF output
my_stream = io.BytesIO()
#Write bytes of PDF to BytesIO object
pdf.output(my_stream)
#Create new File object (see JS File API).
#Casting to Uint8Array necessary to prevent my_stream's value from being interpretted
#as one giant number
pdf_file = File.new([Uint8Array.new(my_stream.getvalue())], "hello_world.pdf", {"type": "application/pdf"})
#Get a URL to reference this in-memory file object
url = window.URL.createObjectURL(pdf_file)
#Create link (wihtout placing it in DOM) with download attribute, point it at our URL, and click it
link = document.createElement("a")
link.download = 'hello_world.pdf'
link.href = url
link.text = "Download PDF"
_ = document.body.appendChild(link) #assignment prevents Pyodide/pyscript from printing return value 
link.click() to the end of your generate function, to have JS click the hidden download link it creates


download attribute so the file downloads instead of just opening in the browser pdf.image() etc. but I keep getting FileNotFoundError: [Errno 44] No such file or directory: 'cert.png' - but it's there!



requests and sockets, neither of which are directly available in a browser environment (edited)

pdf.image() etc. but I keep getting FileNotFoundError: [Errno 44] No such file or directory: 'cert.png' - but it's there! 
micropip.install(..., keep_going=True) to get a list of all packages with missing wheels.


pdf.image('image.png') - it's confusing because if I just navigate in the browser to localhost/image.png it's there, the browser can see it. But to have PyScript fetch that image.png file to then allow fpdf2 to use it, computer says no.
Even when reading/watching tutorials, everything explains user interaction is required, which makes sense. But in my case, sure the user selects 'generate' - but they're not uploading a file, the file is already there. Why is this so hard (for me)?

pdf.image('image.png') - it's confusing because if I just navigate in the browser to localhost/image.png it's there, the browser can see it. But to have PyScript fetch that image.png file to then allow fpdf2 to use it, computer says no.
Even when reading/watching tutorials, everything explains user interaction is required, which makes sense. But in my case, sure the user selects 'generate' - but they're not uploading a file, the file is already there. Why is this so hard (for me)? 

micropip.install(..., keep_going=True) to get a list of all packages with missing wheels. 

async and await ... but the program is freezing once the generate function is called. You can test it here to see what I mean: https://iwasthere.mrash.co/ (edited)


from js import ...
Example:
from js import console, Document
my_p_tag = Document.getElementById("first_paragraph")
console.log(f"first_paragraph contains {my_p_tag.innerHTML}"}
If you ended up logging JSProxy objects or PyProxy objects, the to_js and toPy functions from the pyodide API reference are helpful (https://pyodide.org/en/stable/usage/api-reference.html)





# Remove spaces and return with dashes for filename
fname, lname, event = rmvSpaces(fname), rmvSpaces(lname), rmvSpaces(event)
#link = document.getElementById('generate') Removed
link = document.createElement("a") # << Added
link.setAttribute('download', f'iwasthere-{fname}-{lname}-{event}-{time_now}.pdf'.lower())
link.setAttribute('href', url)
#link.setAttribute('text', 'Download')
link.click() # << Add this!
# link.setAttribute('class', 'button is-success')link object is the hidden link.onscreen_link = document.getElementById('generate')
onscreen_link.setAttribute('class', 'button is-success') (edited)

pdf.image() is taking ages to add the image data to the pdf... like 30-60 seconds for me. Downscaling that image or changing to a compressed file type like jpeg might help? 



pdf.image() is taking ages to add the image data to the pdf... like 30-60 seconds for me. Downscaling that image or changing to a compressed file type like jpeg might help? 





picture.jpeg):<head>
<link rel="stylesheet" href="https://unpkg.com/jcrop/dist/jcrop.css">
<script src="https://unpkg.com/jcrop"></script>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<img src="./picture.jpg" id="target">
<p id="output"></p>
<script>
var stage = Jcrop.attach('target');
</script>
<py-script>
from js import stage
from pyodide import create_proxy
def print_x(widget, evt):
pos = widget.pos
Element("output").write([pos.x,pos.y,pos.w,pos.h], append="True")
stage.listen('crop.change', create_proxy(print_x));
</py-script>
</body> (edited)
stage.listen from within pyscript? But its a JS method? does that work?
Is it because you did from js import stage?
new keyword in Python, you instantiate new JS objects in Python with x = Object.new() instead of the JS's x = new Object().




<py-env>
- paths:
- gradecalculations.py
- matplotlib
</py-env>
<py-script>
import gradecalculations
info = document.getElementById("search").innerHTML
info = info.strip().split()
x = gradecalculations.getCourse(info)
gradecalculations.generateCourseImage(x[0])
</py-script> courseList = []
for year in range(2022,1997,-1):
with open('gradedata/grades{}.csv'.format(year)) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
next(csv_reader)
for row in csv_reader:
course1 = Course(row[0],row[1],row[2],row[3],row[4],row[5],row[6],int(row[7]),int(row[8]),int(row[9]),int(row[10]),int(row[11]),float(row[12]))
courseList.append(course1)a.py, and another called b.py. i access a.py functions inside b.py, but i also want to use b.py functions. how would i go about using this proccess inside my pyscript?
<py-env> paths:...., so import works fine. But your various 'grades{}.csv' files are not, so with open('gradedata/grades{}.csv'.).... fails (edited)

paths, you can you pyodide.http.pyfetch https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.pyfetch to fetch them from the server and bring them into the file systempyfetch under the hood to load the files you specify in paths - the python code in loadFromFile is probably a good starting point https://github.com/pyscript/pyscript/blob/bd7a20309bab76347f0a1731cdb18192238c8420/pyscriptjs/src/interpreter.ts#L44-L61paths (or copy-pasting that python code) brings all the files into the same folder as your script in the virtual file system, so once it's fetched, you'd open ./grade1999.csv not ./gradedata/grade1999.csv, for example
<py-env>
- paths:
- gradedata/*
- gradecalculations.py
- matplotlib
</py-env>
for year in range(2022,1997,-1):
load_file_from_server(filename...)
with open('./grades().csv')....:
#do stuff localhost:5500/gradedata/ isn't a folder, it's a URL
plt.savefig("graph.png", bbox_inches='tight',pad_inches = .5). inside my gradecalculations.py file. can i simply access this inside my html file in my pyscript code?
matplotlib is in py-env and you have a tag with id "graphlocation" somewhere:
import matplotlib.pyplot as plt
from io import BytesIO
from js import document, File, Uint8Array, window
#create plot
plt.plot([1,2,3,4,10])
#Save plot to BytesIO (file-like in-memory object)
plot_file = BytesIO()
plt.savefig(plot_file, bbox_inches='tight',pad_inches = .5)
#Create File object JS knows how to work with, casting BytesIO to Uint8Array
processed_file = File.new([Uint8Array.new(plot_file.getvalue())], "graph.png", {type: "image/png"})
#Create img tag, point it at new File, add to DOM:
my_img = document.createElement("img")
my_img.src = window.URL.createObjectURL(processed_file)
destination = document.getElementById("graphlocation").appendChild(my_img);


import matplotlib.pyplot as plt
from js import document, File, Uint8Array, window
#create plot
plt.plot([1,2,3,4,10])
#Save plot to BytesIO (file-like in-memory object)
plt.savefig('graph.png', bbox_inches='tight',pad_inches = .5)
#Create File object JS knows how to work with, casting BytesIO to Uint8Array
with open("graph.png", 'rb') as infile:
processed_file = File.new([Uint8Array.new(infile.read())], "graph.png", {type: "image/png"})
#Create img tag, point it at new File, add to DOM, etc...savefig to save the file, and then using open( ... mode = 'rb') to read it back in again, which seems like an extra step to me, but that might also just be personal preference

import matplotlib.pyplot as plt
from js import document, File, Uint8Array, window
#create plot
plt.plot([1,2,3,4,10])
#Save plot to BytesIO (file-like in-memory object)
plt.savefig('graph.png', bbox_inches='tight',pad_inches = .5)
#Create File object JS knows how to work with, casting BytesIO to Uint8Array
with open("graph.png", 'rb') as infile:
processed_file = File.new([Uint8Array.new(infile.read())], "graph.png", {type: "image/png"})
#Create img tag, point it at new File, add to DOM, etc... pyscript.write('content', "hello")
plt.plot([1,2,3,4,9])
Element("content").write(plt)
<img id="content"> ?
savefig meethod specially and does this for you)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<py-env>
- matplotlib
</py-env>
</head>
<body>
<div id="content"></div>
<py-script>
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,10])
Element("content").write(plt)
</py-script>
</body>
</html>



onChange) to run a python function between lines of JS code?run PythonFunction() into a JavaScript chunk. Or am I taking the wrong approach here?
output_upload_pillow and file-upload-pillow to the new names, it was throwing a few exception errors when I tried it out. May confuse other beginners like me. 

<script>
function addTwoNumbers(x, y){
return x + y
}
</script>
<py-script>
from js import addTwoNumbers, console
console.log("Adding 1 and 2 in Javascript: " + str(addTwoNumbers(1, 2)))
</py-script>
JS Functions in Pyodide:
<script>
async function main() {
let pyodide = await loadPyodide()
result = pyodide.runPython(`
from js import addTwoNumbers, console
console.log("Adding 1 and 2 in Javascript: " + str(addTwoNumbers(1, 2)))
`)
}
main();
</script>
Python (Pyodide) Functions in JS:
<script type="module">
const pyodideRuntime = await loadPyodide()
pyodideRuntime.runPython(`
def multiplyTwoNumbers(x, y):
return (x * y)
`)
console.log("Multiplying 2 and 3 in Python: " + pyodideRuntime.globals.get('multiplyTwoNumbers')(2, 3))
</script>
But because PyScript doesn't currently expose its Pyodide instance, and since only one Pyodide instance can be running at a time, I don't believe there's a (non-hacky) way to access objects defined in a PyScript block directly in JavaScript.
There's an open issue about this which I hope someone picks up soon https://github.com/pyscript/pyscript/issues/494

output_upload_pillow and file-upload-pillow to the new names, it was throwing a few exception errors when I tried it out. May confuse other beginners like me. .py files that the page is running, so they'll always be in sync. 
<script>
function createObject(x, variableName){
let execString = variableName + " = x"
console.log("Running `" + execString + "`");
eval(variableName + " = x")
}
</script>










src tag in an html page references a (relative or absolute) URL, so you can't use it to reference files within the Emscripten file system (where your file saved to)src attribute to that. (It's virtual in that it doesn't exist anywhere on the web except in the browser window, but it can be referenced by an HTML element or other JavaScript as if it was)

async def share_eq():
base64url = document.getElementById('img').src
blob = await (await fetch(base64url)).blob()
file = File.new([blob], 'eq.png', {type: blob.type})
print("file", file)
navigator.share({
title: 'Generated EQ',
text: 'txt',
files: [file],
}) (edited)


Future exception was never retrieved\nfuture: <Future finished exception=JsException(TypeError: Failed to execute 'share' on 'Navigator': No known share data fields supplied. If using only new fields (other than title, text and url), you must feature-detect them first.)>









Future exception was never retrieved\nfuture: <Future finished exception=JsException(TypeError: Failed to execute 'share' on 'Navigator': No known share data fields supplied. If using only new fields (other than title, text and url), you must feature-detect them first.)> 


<button onclick="share()">Share Me</button>
<script>
function share() {
navigator.share({url: "http://www.example.com"})
}
</script> (edited)


<button onclick="share()">Share Me</button>
<script>
function share() {
navigator.share({url: "http://www.example.com"})
}
</script> (edited)
data argument to a variable and log it and see what type it isobject.fromEntries https://discord.com/channels/972017612454232116/972020206538997822/994302197674299443


<button onclick="share()">Share Me</button>
<script>
function share() {
navigator.share({url: "http://www.example.com"})
}
</script> (edited)










# type: ignore to remove the warning; ideally someday weโll have stronger tooling than this, but given thereโs not a way for an IDE to know whatโs going to be in the global browser scope at runtimeโฆ


web3py appears to make significant use of websockets. Because opening a socket from within a browser window is not supported by any browser (and is unlikely to be), web3py is not likely to work in PyScript/Pyodide any time soon.

web3py appears to make significant use of websockets. Because opening a socket from within a browser window is not supported by any browser (and is unlikely to be), web3py is not likely to work in PyScript/Pyodide any time soon. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css"/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
from pyodide.ffi import create_proxy
import js
import json
ws = js.WebSocket.new('wss://s1.ripple.com/')
def events(e=None):
if e.type == 'close':
js.console.log( e.type )
if e.type == 'error':
js.console.log( e.type )
if e.type == 'message':
m = json.loads(e.data)
js.console.log( m )
if e.type == 'open':
js.console.log( e.type )
# send message when connected
e.target.send(json.dumps( {
"id": 1,
"command": "server_info"
}))
js.console.log(e)
proxy = create_proxy(events)
ws.addEventListener('close',proxy)
ws.addEventListener('error',proxy)
ws.addEventListener('message',proxy)
ws.addEventListener('open',proxy)
</py-script>
</body>
</html>




python-sat, so that's what you'd want to include in your py-env/py-config https://pysathq.github.io/installation/import pysat.solvers or from pysat.solvers import ....

pypi.org doesn't have the proper CORS headers. But I'm not very familiar with this stuff so I might be wrong
pysat-solvers package (which doesn't exist on PyPI), so micropip tries to load https://pypi.org/pypi/pysat-solvers/json to get the metadata... and that page 404's, but it also sends back content with a malformed CORs header (edited)



pysat-solvers package (which doesn't exist on PyPI), so micropip tries to load https://pypi.org/pypi/pysat-solvers/json to get the metadata... and that page 404's, but it also sends back content with a malformed CORs header (edited)ModuleNotFoundError: No module named 'pysat'
Maybe it's not possible because to install pysat I have to make pip install pysat in my shell (edited)


<head> tag:
<py-config>
packages = ['python-sat']
</py-config>
That will cause micropip to load python-sat from PyPI




.whl, then add the wheel as a dependency in your py-config block. That's effectively the equivalent of pip importing your module; so in your python code, you can import module and use it as you would normally.




pyModbusTCP package from PyPI
importlib.metadata to retrieve name/version details about the packages that have been loaded. About 50% of the time, I get a failure from importlib.metadata saying that the package doesn't exist - but if you restart the webserver and reload, it works. It feels like some sort of race condition with interpreter startup, but I'm not sure where I'd start looking to investigate.


latest, which I believe is pinned to 2022.09.1)[pyscript/runtime] PyScript page fully initialized





<!DOCTYPE html>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css"/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<h3>
<py-script>
from pyodide.http import pyfetch
import asyncio
async def submit_request(*args):
varName = Element('test-input').element.value
response = await pyfetch(url="https://api.lanyard.rest/v1/users/852825042630475827", method="GET")
output = f"{await response.json()}"
pyscript.write('request_output', output)
</py-script>
</h3>
why this doesnt show anything?
Pyscript.write is the id of the html tag you want to write to, and it doesnโt look like you have a tag with id=โrequest_outputโ


requests...


outputfrom pyodide.http import pyfetch
import asyncio
response = await pyfetch(url="https://api.lanyard.rest/v1/users/852825042630475827", method="GET")
output = f"{await response.json()}"
output




output['data']['discord']['username']R3FL3X


from pyodide.http import pyfetch
import asyncio
response = await pyfetch(url="https://api.lanyard.rest/v1/users/852825042630475827", method="GET")
output = await response.json()
output['data']['discord_user']['username']





<py-script>
import mymodule
mymodule.myfunction()
</py-script> (edited)
<py-config> tag:
<py-config>
paths = ["./mymodule.py"]
</py-config>mymodule.py is at the same relative path as your HTML file (whether you're using a local live server, deploying to the web, etc... paths = ["https://example.com/path/to/some/resources/mymodule.py"]
<py-env>, so prexisting examples may use a similar syntax in that tag to load files)



pyodide.loadPackageemscripten_run_preload_plugins so it is not possible to compile a wasm assembly (.so > 4KiB ) library asynchronously







<py-script>
from js import console
from datetime import datetime
from request import request
</py-script> i have this in my html, but i still getting no module named "request". Why?
requests module?




requests from stdlib


pys-onClick="exec_func" is not getting fired

pys-onclick=โfooโ is py-click=โfoo()โ















<py-config>
packages = [
"bokeh",
"numpy",
"pandas",
"panel==0.13.1"
]
</py-config>

<py-config> is what determines which packages are installed in the page. It is basically the equivalent of pip install or conda install

<py-config> is what determines which packages are installed in the page. It is basically the equivalent of pip install or conda install 
<py-config> you don't import packages. In <py-config> you can specify many configurations options, and among those there is the packages = [...] option, which represents the list of packages which are installed by pyscript<py-config> tag is in TOML format (or optionally JSON), not python

<py-config>
packages = [
"bokeh",
"numpy",
"pandas",
"panel==0.13.1"
]
</py-config> 

<py-config>
packages = [
"bokeh",
"numpy",
"pandas",
"panel==0.13.1"
]
</py-config> 











formData = FormData.new(e.target.parentElement)
payload = {}
for entry in formData:
key = entry[0]
value = entry[1]
if key in payload:
if isinstance(payload[key], list):
payload[key].append(value)
else:
payload[key] = [payload[key], value]
else:
payload[key] = value (edited)





window.location.href, and make decisions based on that



window.location.href, and make decisions based on that 
from js import window
if window.location.href ...












window.location.href and decide what to do depending on it.
I guess that in JS there are libraries to automate that, but not in pyscript

window.location.href and decide what to do depending on it.
I guess that in JS there are libraries to automate that, but not in pyscript 

new Image() but what is the equivalent in pyscript? trying to call Image() I get an error.



new Image() but what is the equivalent in pyscript? trying to call Image() I get an error. new Image(some, args)
Pyodide: Image.new(some, args)

requests module in the stdlib works, it doesn't work natively in Pyodide/in the browser. Check out this howto in the documentation for other strategies for getting HTML content: https://docs.pyscript.net/latest/howtos/http-requests.html

requests module in the stdlib works, it doesn't work natively in Pyodide/in the browser. Check out this howto in the documentation for other strategies for getting HTML content: https://docs.pyscript.net/latest/howtos/http-requests.html 




.string()
I havenโt tried it yet so I am assuming from the docs https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.FetchResponse.string

.string()
I havenโt tried it yet so I am assuming from the docs https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.FetchResponse.string 


window.location.href and decide what to do depending on it.
I guess that in JS there are libraries to automate that, but not in pyscript 
<py-script src="/path/to/foo.py"></py-script> how do I teach Pylance about the location of the "js" module?











nvm so you don't have to upgrade the base node version (this allows you to have as many versions as you want) https://github.com/nvm-sh/nvm (edited)
proxy is in the pywidget any idea? 






py-click=loveCalc()>, not pys-onClick. Note also tht loveCalc() must be CALLED inside py-click


loveCalc functiondef loveCalc(*args, **kwargs):
cooltext = Element("test-input").value
cooltxt = str(cooltext)
Element("testlabel").element.innerText = cooltxt

def loveCalc(*args, **kwargs):
Element("testlabel").element.innerText = Element("test-input").value

cooltext is set once when the script runs and never again






async def fetch_data(event):
...

async def fetch_data(event):
... 



from pyodide.http import pyfetch
result = await pyfetch("http://www.example.com", mode="no-cors")
<script defer src="https://pyscript.net/latest/pyscript.js%22%3E</script> but no joy 

<script defer src="https://pyscript.net/latest/pyscript.js%22%3E</script> but no joy <script defer src="https://pyscript.net/latest/pyscript.js"></script> (edited)

<script defer src="https://pyscript.net/latest/pyscript.js"></script> (edited)<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>PyScript Hello World</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
Hello world! <br>
This is the current date and time, as computed by Python:
<py-script>
from datetime import datetime
now = datetime.now()
now.strftime("%m/%d/%Y, %H:%M:%S")
</py-script>
</body>
<script src="popup.js"></script>
</html>console.log("Script finished!")









https://pyscript.net/latest/pyscript.js
https://pyscript.net/latest/pyscript.css
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide_py.tar
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.asm.js
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.asm.data
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/repodata.json
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.asm.wasm
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/packaging-21.3-py3-none-any.whl
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/distutils.tar
https://cdn.jsdelivr.net/pyodide/v0.21.2/full/micropip-0.1-py3-none-any.whl
<py-config>
autoclose_loader = true
[[runtimes]]
src = "pyodide/pyodide.js"
name = "pyodide-0.21.2"
lang = "python"
</py-config> (edited)




setup.py to download the dependencies you listed, but suspect my hello.html has something wrong in the 'boiler-plate' code (edited)



from js import console, document, Image
img = Image.new()
img.src = "cg.png"
img.onload = lambda _: console.log("Loaded!")
document.body.appendChild(img)



functools.partial






py-env tag is still being used. One of my PR fixes and updates this but it isn't merged yet.
Basically, py-env is deprecated and py-config should be used.






py-box is only really used to add flex and width to a div right?
I'm just wondering since I started working on deprecating these elements and wonder what to suggest to users - a flexy div?

py-box is only really used to add flex and width to a div right?
I'm just wondering since I started working on deprecating these elements and wonder what to suggest to users - a flexy div? <py-box> that creates child divs with specified proportional flex-ness... but I'm not sure how much it's really been used. Personally I'd let it go https://github.com/pyscript/pyscript/blob/1345449d574d816a539bbe534d66650791a3f2b8/pyscriptjs/src/components/pybox.ts#L50-L66 (edited)

<py-box> that creates child divs with specified proportional flex-ness... but I'm not sure how much it's really been used. Personally I'd let it go https://github.com/pyscript/pyscript/blob/1345449d574d816a539bbe534d66650791a3f2b8/pyscriptjs/src/components/pybox.ts#L50-L66 (edited)




qrng package seems to have some poorly configured metadata - it should like 'qiskit' as a dependency but doesn't, so one seems to have to install it separately. This is what causes the ModuleNotFoundError: No module named 'qiskit' error if you only include qrng in <py-config> packages...qiskit in the packages leads to a new error: ValueError: Can't find a pure Python 3 wheel for 'qiskit-terra<0.8,>=0.7'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel That link explains more, but essentially, Pyodide (the default runtime used by PyScript) requires packages to either:
(a) have a released .whl that is only Python (i.e that ends in "py3-none-any.whl") or
(b) that has been specifically built for/with Pyodide, possibly with patches to account for some system resources that are missing/different from ones in a 'normal' desktop environment. That list is here: https://pyodide.org/en/stable/usage/packages-in-pyodide.html




@helpful could be collected?










<py-config type="json">
{
"fetch": [{
"from": "Hipparcos.csv",
"to_folder": "/home/pyodide",
"to_file": "Hipparcos.csv"
}]
}
</py-config>
<py-script>
import os
display(f"{os.getcwd()=}")
display(f"{os.listdir(os.getcwd())=}")
</py-script>to_folder defaults to "." and from defaults to "" (relative URL prefix), so if you want to just load a file from the relative URL "Hipparcos.csv" to a spot in the filesystem in the same folder that scripts are executed in, you can just do:
<py-config type="json">
{
"fetch": [{
"files": ["Hipparcos.csv"]
}]
}
</py-config> (edited)

to_folder defaults to "." and from defaults to "" (relative URL prefix), so if you want to just load a file from the relative URL "Hipparcos.csv" to a spot in the filesystem in the same folder that scripts are executed in, you can just do:
<py-config type="json">
{
"fetch": [{
"files": ["Hipparcos.csv"]
}]
}
</py-config> (edited)

<py-config type="json">
{
"fetch": [{
"from": "Hipparcos.csv",
"to_folder": "/home/pyodide",
"to_file": "Hipparcos.csv"
}]
}
</py-config>
<py-script>
import os
display(f"{os.getcwd()=}")
display(f"{os.listdir(os.getcwd())=}")
</py-script> 







/latest, or if we really want to keep it, we should never use it in our docs and examples/latest is something which works for 1 month and then it will be probably be broken forever





/latest, or if we really want to keep it, we should never use it in our docs and examples 
/latest altogether because I don't really understand what is its utility, but it might yet another case of antonios-unpopular-opinions 

/unstable corresponds to the origin/main, i.e. it's rebuilt every time we merge a PR
/latest corresponds to the latest release/unstable might have a value for testing purposes, but for /latest you could just use the explicit release







pyarrow or polars publish a pure python wheel (i.e. a *py3-none-any.whl), which pyodide relies upon to load a package from PyPI. (Though there's experimental support for Rust https://blog.pyodide.org/posts/rust-pyo3-support-in-pyodide/) So building those packages in a Pyodide-friendly way would probably need to be a first step (edited)







pyarrow or polars publish a pure python wheel (i.e. a *py3-none-any.whl), which pyodide relies upon to load a package from PyPI. (Though there's experimental support for Rust https://blog.pyodide.org/posts/rust-pyo3-support-in-pyodide/) So building those packages in a Pyodide-friendly way would probably need to be a first step (edited)






<py-script>
for i in range(9):
print(i)
def func():
print('function works')
</pyscript>
becomes
<py-script>for i in range(9): print(i) def func(): print('function works')</py-script>
and the indentation breaks.
As for how to fix it? 20 minutes of googling "How to not strip whitespace in next.js" didn't get me anywhere obvious 
<script>
<![CDATA[
var x = 1;
]]>
</script> (edited)<py-script> body


<py-script>
for i in range(9):
print(i)
def func():
print('function works')
</pyscript>
becomes
<py-script>for i in range(9): print(i) def func(): print('function works')</py-script>
and the indentation breaks.
As for how to fix it? 20 minutes of googling "How to not strip whitespace in next.js" didn't get me anywhere obvious 



<py-script>
for i in range(9):
print(i)
def func():
print('function works')
</pyscript>
becomes
<py-script>for i in range(9): print(i) def func(): print('function works')</py-script>
and the indentation breaks.
As for how to fix it? 20 minutes of googling "How to not strip whitespace in next.js" didn't get me anywhere obvious 

React.createElement with stripped white spaces
/*#__PURE__*/React.createElement("py-script", null, "for i in range(9): print(i) def func(): print('function works')");





<py-script>
for i in range(9):{"\n"}
{" "}{" "}print(i){"\n"}
{"\n"}
def func():{"\n"}
{" "}{" "}print('function works'){"\n"}
</py-script>
I'm totally not going into a rabbit hole trying to see if we can override jsx behaviour of striping newlines and spaces dangerouslSetInnerHTML to pass the python function:
const data = `
for i in range(9):
print(i)
def func():
print('function works')
`
return (
<py-script
dangerouslySetInnerHTML={{__html: data}}
/>data directly into __html: althoug I got some issues with whitespace so using a variable was a bit easier to deal with white space 


<py-script>
for i in range(9):{"\n"}
{" "}{" "}print(i){"\n"}
{"\n"}
def func():{"\n"}
{" "}{" "}print('function works'){"\n"}
</py-script>
I'm totally not going into a rabbit hole trying to see if we can override jsx behaviour of striping newlines and spaces 

const data = `
for i in range(9):
print(i)
def func():
print('function works')
`
return (
<py-script
dangerouslySetInnerHTML={{__html: data}}
/>
As for the files i was trying that first but next does some weird stuff with folders and I kept getting a file not found. Will need to poke at it a bit more (edited)

const data = `
for i in range(9):
print(i)
def func():
print('function works')
`
return (
<py-script
dangerouslySetInnerHTML={{__html: data}}
/>
As for the files i was trying that first but next does some weird stuff with folders and I kept getting a file not found. Will need to poke at it a bit more (edited)


<py-config> packages:... like so:
<py-config>
packages=['numpy']
</py-config>
<py-script>
import numpy as np
print(np.arange(15).reshape(3,5))
</py-script><py-config> pacakges=... uses a tool called micropip (a lot like pip, but Pyodide-specific) to install the list of packages





<py-script src=โโฆโ> to load the way from an external file

<py-script src=โโฆโ> to load the way from an external file 





[[fetch]] originally I was simply fetching the https://pyscript.net/examples/todo.py and utils and trying to import it, but things failed because Element was not defined.


pyscript.runtime.globals.get("x")
I'm using a dev version locally 

pyscript js module is part of an upcoming release, and isn't present in 2022.09.1 (the current /latest)eval() etc), but here's a simpler option that @hood illustrated for me:
<py-script>
import js
js.pyscriptGlobals = globals()
x = 42
</py-script>
<button onclick="showX()">Click Me to Get 'x' from Python</button>
<script>
function showX(){
console.log(`In Python right now, x = ${pyscriptGlobals.get('x')}`)
}
</script>





to_js, optionally with the dict_converter parameter, like so:
import js
from pyodide.ffi import to_js
my_dict = {
"pyscript": 1,
"is": 2,
"neat": 3
}
js.console.log(my_dict) # Proxy
js.console.log(to_js(my_dict)) #Map
js.console.log(to_js(my_dict, dict_converter=js.Object.fromEntries)) # Object

to_js, optionally with the dict_converter parameter, like so:
import js
from pyodide.ffi import to_js
my_dict = {
"pyscript": 1,
"is": 2,
"neat": 3
}
js.console.log(my_dict) # Proxy
js.console.log(to_js(my_dict)) #Map
js.console.log(to_js(my_dict, dict_converter=js.Object.fromEntries)) # Object 














mystem program is accessible; if it's binary only the only solution is to ask the authors of mystem to provide a WASM version)








.parquet files in pyodide? should I try it with pandas.read_parquet ?

.parquet files in pyodide? should I try it with pandas.read_parquet ? 
.parqet files, but for csv something like this works:
import pandas
from pyodide.http import open_url
data = pd.read_csv(open_url(url))
I wonder if opening a parquet file will complain

.parqet files, but for csv something like this works:
import pandas
from pyodide.http import open_url
data = pd.read_csv(open_url(url))
I wonder if opening a parquet file will complain <html>
<head>
<title>Chicago Crimes PyScript App</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<py-config>
packages = [
"pandas"
]
</py-config>
</head>
<body>
<div id="info"></div>
<py-script output="info">
import pandas as pd
from pyodide.http import open_url
from datetime import datetime
from js import console
from js import document
info_element = document.getElementById('info')
info_element.innerText = 'Loading data ...'
start_time = datetime.now()
# read 2022 crimes parquet data
data_url = (
'https://raw.githubusercontent.com/RandomFractals/chicago-crimes/main/data'
)
crimes_data_url = f'{data_url}/crimes-2022.parquet'
crimes = pd.read_parquet(open_url(crimes_data_url))
# calculate and display data load time
end_time = datatime.now()
load_time = (end_time - start_time).total_seconds()
status = f'load time: {load_time} seconds'
console.log(status)
info_element.innerText = status
</py-script>
</body>
</html>







from js import window
window.setTimeout(window.main, 0)
pass
(and on the js side, I define the window.main before the python script.)
Is this the way to go, or is there some other mechanism to have a callback run after initializing the python library?
async loadPythonLib(){
const py = await loadPyodide();
await py.loadPackage("micropip");
const micropip = py.pyimport("micropip");
await micropip.install("some_lib");
return pyodide.pyimport("some_lib");
}
const pythonLibPromise = loadPythonLib();
and then to get the lib you can await pythonLibPromise.
<py-config>

<py-script>
import js
js.document.dispatchEvent(js.Event.new(โpyscript-loadedโ)
</py-script>
<script>
document.addEventListener(โpyscript-loadedโ, () => {main()})
</script>
globalThis.pythonLibPromise = new Promise(resolve => globalThis.resolvePythonLibPromise = resolve);
and then in Python:
from js import resolvePythonLibPromise
resolvePythonLibPromise(thelib)






x = 42
import js
js.my_python_variable = x (edited)






# read 2022 crimes parquet data
data_url = (
'https://raw.githubusercontent.com/RandomFractals/chicago-crimes/main/data'
)
crimes_data_url = f'{data_url}/crimes-2022-slim.csv'
crimes = pd.read_csv(open_url(crimes_data_url),
parse_dates=['Date'],
cache_dates=True,
low_memory=False) (edited)
display(crimes) to the end gives: (edited)














https://pyscript.net/latest/pyscript.css




Element(โdiv idโ).inner_html you need to look at the dev tools for the div id, I donโt remember out of the top of my head


<py-config>
packages = ['pandas']
[[fetch]]
files = ['dogs.csv.zip']
</py-config>
<py-repl>
import pandas as pd
crimes_df = pd.read_csv('dogs.csv.zip')
display(crimes_df)
</py-repl> (edited)dogs.csv.zip is a zipped csv file with some data on good dogs

dogs.csv.zip is a zipped csv file with some data on good dogs 
paths= and print() in 2022.09.1, the data still loads into the dataframe but the output isn't as nice, just ends up as a string)







<py-config>
packages = ['pandas']
[[fetch]]
files = ['dogs.csv.zip']
</py-config>
<py-repl>
import pandas as pd
crimes_df = pd.read_csv('dogs.csv.zip')
display(crimes_df)
</py-repl> (edited)

<py-config>
packages = ['pandas']
[[fetch]]
files = ['dogs.csv.zip']
</py-config>
<py-repl>
import pandas as pd
crimes_df = pd.read_csv('dogs.csv.zip')
display(crimes_df)
</py-repl> (edited)[[fetch]] shorthand in your example. will see if I can find the docs on that


[[fetch]] shorthand in your example. will see if I can find the docs on that display(), which made me think you were working with the current build/unstable version. But I see youโre on /latest. Slightly different syntax for loading files in 2022.09.1 (latest), but same idea - moving files from the web into the emscriten local file system where Pandas etc can interact with them
<py-config>
paths=[โsome/abs/or/relative/url/to/file.txtโ]
</py-config>
At load, this creates a file called file.txt in the same local folder where scripts are run, so you could do with open(โfile.txtโ, โrโ) as fp()โฆ (edited)



import Vizzu inside Pyscript, chart = Vizzu.default.new("myVizzu") to create a new chart, and then uses chart's methods/attributes to control the chart within PyScript

import Vizzu inside Pyscript, chart = Vizzu.default.new("myVizzu") to create a new chart, and then uses chart's methods/attributes to control the chart within PyScript 
import lib_name from js to grab proxies for the JS library objects itself

import js or from js import treats the JS global namespace as a module to be imported from. As in from js import console or import js; js.document.getElementById(...). It's really niftyjs namespace to create objects in the js global namespace:
<py-script>
import js
x = 42
js.x_in_javascript = x
js.console.log(js.window)
</py-script>




py-status-message can you use that?

py-status-message can you use that? 

























from asyncio import Future
from pyodide.ffi import create_proxy
from pyodide_js import FS
import os
def mount_ibdfs(mountdir):
os.mkdirs(mountdir)
FS.mount(FS.filesystems.IDBFS, {}, mountdir)
async def initialize_idbfs():
"""This populates the mounted folder with the persisted files.
Wait for it to finish before trying to access the folder!
"""
fut = Future()
def set_result(err):
if err is None:
# If err is None, fs was successfully initialized.
# We should probably handle the other case??
fut.set_result(None)
FS.syncfs(True, create_proxy(set_result))
await fut
async def persist_idbfs():
"""This persists changes to the idbfs folder.
Wait for it to complete before exiting page or changes will be lost!
"""
fut = Future()
def set_result(err):
if err is None:
# If err is None, fs was successfully persisted.
# We should probably handle the other case??
fut.set_result(None)
FS.syncfs(True, create_proxy(set_result))
await fut
mount_ibdfs("/some/directory")
await initialize_idbfs()
p = Path("/some/directory/afile.txt")
if p.exists():
print(f"{p} exists, contains: {p.read_text()}")
else:
print(f"{p} does not exist")
import random
p.write_text(f"hello! {random.randint(0,100)}")
await persist_idbfs()




from asyncio import Future
from pyodide.ffi import create_proxy
from pyodide_js import FS
import os
def mount_ibdfs(mountdir):
os.mkdirs(mountdir)
FS.mount(FS.filesystems.IDBFS, {}, mountdir)
async def initialize_idbfs():
"""This populates the mounted folder with the persisted files.
Wait for it to finish before trying to access the folder!
"""
fut = Future()
def set_result(err):
if err is None:
# If err is None, fs was successfully initialized.
# We should probably handle the other case??
fut.set_result(None)
FS.syncfs(True, create_proxy(set_result))
await fut
async def persist_idbfs():
"""This persists changes to the idbfs folder.
Wait for it to complete before exiting page or changes will be lost!
"""
fut = Future()
def set_result(err):
if err is None:
# If err is None, fs was successfully persisted.
# We should probably handle the other case??
fut.set_result(None)
FS.syncfs(True, create_proxy(set_result))
await fut
mount_ibdfs("/some/directory")
await initialize_idbfs()
p = Path("/some/directory/afile.txt")
if p.exists():
print(f"{p} exists, contains: {p.read_text()}")
else:
print(f"{p} does not exist")
import random
p.write_text(f"hello! {random.randint(0,100)}")
await persist_idbfs() initialize_idbfs and persist_idbfs seems to be exactly the same code: is it intended or a typo?



pything = PyScript.globals.runtime.get('thing');
pything();
changing PyScript to pyscript or pyodide does not work either. some error about not defined

pything = PyScript.globals.runtime.get('thing');
pything();
changing PyScript to pyscript or pyodide does not work either. some error about not defined https://pyscript.net/unstable/pyscript.js you should be able to get it by doing pyscript.globals.runtime.get('thing') (note the lowercase it's important)

https://pyscript.net/unstable/pyscript.js you should be able to get it by doing pyscript.globals.runtime.get('thing') (note the lowercase it's important) Uncaught TypeError: pyscript.globals is undefined
pyscript.runtime.globals.get instead

pyscript.runtime.globals.get instead 

pyscript.runtime.globals.get instead 



unstable is very close to be the upcoming 2022.12.1 releaseunstable changes every time we merge a PR

unstable will be frozen into a release.

/latest which points to the latest release. So now /latest is a synonim for 2022.09.1, but soon will point to 2022.12.1



packages = ['newspaper3k'] and it will be downloaded if it contains a pure python 3 wheel which from your message seems like it does 












unstable so once we release, you wont see the error message latest for now














<py-script src="..."> attribute to load your code from a separate python file. We've seen examples here of frameworks (next/React) that strip whitespace from all files, which mangles all inline python inside <py-script> tags in horrible ways.
There's a fair bit of documentation on the various pyscript functions is included in the upcoming release, and the recommended means of writing to a page element has been wrapped into a new display() function. If you want to see what that can do to simplify your workflow, point your source links to:
<link rel="stylesheet" href="https://pyscript.net/snapshots/2022.12.1.RC1/pyscript.css"/>
<script defer src="https://pyscript.net/snapshots/2022.12.1.RC1/pyscript.js"></script>
And check out this tutorial that @FabioRosado wrote on Writing Content to an Element: https://docs.pyscript.net/unstable/tutorials/writing-to-page.html. (It refers to functionality, like display() and <py-terminal> only present in that upcoming release)
There's often a performance hit for using Python vs vanilla js, though it's a bit hard to quantify. For simple user interactions, like processing/downloading a file on a button click, I wouldn't sweat it too much, but that's just me. (edited)







paths = in py-config to get variable_form.html?
<py-config>
[[fetch]]
from = "https://raw.githubusercontent.com/pyscript/pyscript/main/pyscriptjs/src/python/"
files = ["pyscript.py"]
[[fetch]]
from = "https://gist.githubusercontent.com/laralice/3d47cad6522da9f1b46382c9a4d397dc/raw/c83b003788f3692a20ce901a37fcf6956090cbb1/insts.html"
files = ["insts.html"]
</py-config>
[[fetch]] is only a feature in in unstable (unreleased) currently



<py-script src="...."?


python <py-script src="desktop/test.py" can be accessed, then any local files referencded within test.py should also be accessible 
<py-script>
import os
for root, dirs, files in os.walk("/", topdown=False):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print(os.path.join(root, name))
</py-script>open(), import(), os.walk etc all work with the virtual filesystem)

python <py-script src="desktop/test.py" can be accessed, then any local files referencded within test.py should also be accessible [[fetch]] (and its predecessor paths=) do - they load content from the web and download into the virtual filesystem (edited)<py-config>
[[fetch]]
from = "https://gist.githubusercontent.com/laralice/3d47cad6522da9f1b46382c9a4d397dc/raw/c83b003788f3692a20ce901a37fcf6956090cbb1/insts.html"
to_file = "insts.html"
</py-config>

to_file, not files)

<py-script>
from bs4 import BeautifulSoup
from js import document
def beaty_soup(html): ## this is me being a noob with the 'html' variable from the js script
page_html = html ## this is me being a noob with the 'html' variable from the js script
soup = BeautifulSoup(page_html, 'html.parser')
def print_self_and_children(tag, indent = 0):
print("_" * indent + str(tag.name))
if hasattr(tag, 'children'):
for child in tag.children:
if hasattr(child, 'name') and child.name is not None: print_self_and_children(child, indent = indent + 2)
print_self_and_children(soup)
</py-script>beaty_soup(html);


.gz instead of 20MB of CSV data. This shaves a few more seconds and loads that app data in about 8 secs total with runtime. See updated app: https://randomfractals.github.io/chicago-crimes/apps/pyscript/ Gzip data loading I added in PyScript: # read slimmed down 2022 crimes CSV data in gzip format
data_url = 'https://raw.githubusercontent.com/RandomFractals/chicago-crimes/main/data'
crimes_data_url = f'{data_url}/crimes-2022-slim.csv.gz'
data_response = await fetch(crimes_data_url)
crimes_data = await data_response.arrayBuffer()
crimes = pd.read_csv(BytesIO(crimes_data.to_py()),
sep=',',
compression='gzip',
parse_dates=['Date'],
cache_dates=True,
low_memory=False) (edited)


import asyncio
async def solution(n1, n2):
answer = 0
for i in range(100000000000000):
print(i)
solution_task = asyncio.create_task(solution(1, 2))
solution_ask.add_done_callback(do_something_with_result)

while True: pass loop, for example, you must close/crash and re-open the tab. The same is true of JavaScript, incidentally.
The long-term solution for PyScript is likely going to be running the Python code in a Web Worker (i.e. separate thread), so that long-running loops don't lock up th whole window

while True: pass loop, for example, you must close/crash and re-open the tab. The same is true of JavaScript, incidentally.
The long-term solution for PyScript is likely going to be running the Python code in a Web Worker (i.e. separate thread), so that long-running loops don't lock up th whole window 


while True: pass loop, for example, you must close/crash and re-open the tab. The same is true of JavaScript, incidentally.
The long-term solution for PyScript is likely going to be running the Python code in a Web Worker (i.e. separate thread), so that long-running loops don't lock up th whole window 



js.navigator.clipboard.writeText()
works great to copy to the users clipboard, but
js.navigator.clipboard.readText()
just gives AttributeError: readText when trying to paste from the clipboard


<div id="output"></div>
<button id="btn" py-click="paste_to_div()">Click to Log</button>
<py-script>
import js
from pyodide.ffi import to_js
async def paste_to_div(*args):
div = js.document.getElementById("output")
div.innerText += await js.navigator.clipboard.readText()
</py-script>

<div id="output"></div>
<button id="btn" py-click="paste_to_div()">Click to Log</button>
<py-script>
import js
from pyodide.ffi import to_js
async def paste_to_div(*args):
div = js.document.getElementById("output")
div.innerText += await js.navigator.clipboard.readText()
</py-script> 
RuntimeError: asyncio.run() cannot be called from a running event loop
For context, I'm trying to use the ffmpeg_streaming video.dash.output() which seems to use asyncio

pything = PyScript.globals.runtime.get('thing');
pything();
changing PyScript to pyscript or pyodide does not work either. some error about not defined Uncaught ReferenceError: pyscript is not defined (edited)https://pyscript.net/releases/2022.12.1/pyscript.js
that is the link I am using (edited)

RuntimeError: asyncio.run() cannot be called from a running event loop
For context, I'm trying to use the ffmpeg_streaming video.dash.output() which seems to use asyncio asyncio.run. I.e.
import asyncio
asyncio.run = asyncio.ensure_future
...video.dash.output no longer crashes with this reassignment. No idea if it does what it's supposed to though



Uncaught ReferenceError: pyscript is not defined (edited)


js.document.getElementById().click() in pyscript?
Element(<el id>).element.click

Element(<el id>).element.click 







PyProxy.get_buffer() to directly reference the underlying data in Web Assembly and pass that data to the File constructor without copying.









python
# read slimmed down 2022 crimes CSV data in gzip format
data_url = 'https://raw.githubusercontent.com/RandomFractals/chicago-crimes/main/data'
crimes_data_url = f'{data_url}/crimes-2022-slim.csv.gz'
data_response = await fetch(crimes_data_url)
crimes_data = await data_response.arrayBuffer()
crimes = pd.read_csv(BytesIO(crimes_data.to_py()),
sep=',',
compression='gzip',
parse_dates=['Date'],
cache_dates=True,
low_memory=False) see: https://github.com/RandomFractals/chicago-crimes/blob/main/apps/pyscript/index.html (edited)

python -m http.server 8080 is explicitly make files on your computer available on the network, using a server program. The exact URL those files are available at will depend on what location you run that command from, but assuming your terminal is within your pyscript_practice folder when you run it, your image file will be available at localhost:8080/image.png





"runtimes": [{
"src": "/pyodide/pyodide.js",
"name": "pyodide-0.22.0a3",
"lang": "python"
}],



await import(/* webpackIgnore: true */ "node-fetch")).default,
But 0.22.0a3 removed the webpackIgnore, just wonder if maybe that can cause some problems 


































document.getElementsByTagName("py-terminal")[0].innerHTML = โโ

document.getElementsByTagName("py-terminal")[0].innerHTML = โโ 
height or min-height should also keep it visible?py-terminal class

height or min-height should also keep it visible? 

py-terminal class 


sys.displayhook to clear the py-terminal before writing new content to it?

sys.displayhook to clear the py-terminal before writing new content to it? 


























<div id="result"></div>
<py-script>
from pyscript import display
from pyodide.http import pyfetch
import asyncio
async def get_api_result(url, **kwargs):
result = await pyfetch(url, **kwargs)
display(f"Request Status: {result.status}", target="result")
body = await result.json()
display(f"Request Body: {body}", target="result")
asyncio.ensure_future(get_api_result('https://reqres.in/api/users/2'))
</py-script> (edited)







response.json()



__init__.py file in the code folder and add it to the fetch config as well?
Since you are importing things such as data from main I wonder if maybe you are having issues with the imports.
But again I havenโt really tested it looked much in-depth at the code








fromarray() method, to create a PIL image as in their documentation https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.fromarray











fetch in your py-config.
Hereโs the link to the fetch reference docs: https://docs.pyscript.net/latest/reference/elements/py-config.html#a-name-fetch-fetch-a
Thereโs also a tutorial that shows you how to use it https://docs.pyscript.net/latest/tutorials/py-config-fetch.html
Let us know if this helps 

python3 -m http.server from the base directory will work, or many IDEโs have server extensions that serve the same purpose. (edited)








__builtins__ to be available https://pyodide.org/en/stable/usage/faq.html#how-can-i-execute-code-in-a-custom-namespace (edited)

__builtins__ to be available https://pyodide.org/en/stable/usage/faq.html#how-can-i-execute-code-in-a-custom-namespace (edited)
display(), the HTML class, and the pyscript module) may need to be imported in your script as well (edited)

from js import document
list = document.createElement("li");
anchor = document.createElement("a");
list.appendChild(anchor)
Element(anchor).write("Test")
document.getElementById("lists").appendChild(list) (edited)

<py-config> and its not working. but when I use the same code on a different html file the file the importing works perfectly.

<py-config> and its not working. but when I use the same code on a different html file the file the importing works perfectly. 
<py-config>
packages = ['Pillow']
paths = ['Roboto-Black.ttf']
</py-config>
Not Working code
<py-config>
packages = ['Pillow']
paths = ['Roboto-Black.ttf']
</py-config> (edited)


paths was replaced by fetch configurations: https://docs.pyscript.net/latest/reference/elements/py-config.html#a-name-fetch-fetch-a

<button id="Submit" py-onClick()="initial">Submit</button>
but the function below is not getting called:
def initial(*args, **kwargs):
pyscript.write("output", "Hello")
I am really new to this, spent a lot of time on trying to solve this issue. Would be great if someone could help me out on this. Thanks in advance. (edited)
py-click = "initial('foo', 'bar')", Note that the name of the attribute is py-*, where * is the name of a browser event, and the value is a string of executable Python code


tinydb on the page) you're using <py-env>, which was deprecated in version 2022.11.1 and removed in version 2022.12.1. The tag is now called <py-config>, as in:
<py-config>
packages = ['tinydb']
</py-config>


tinydb on the page) you're using <py-env>, which was deprecated in version 2022.11.1 and removed in version 2022.12.1. The tag is now called <py-config>, as in:
<py-config>
packages = ['tinydb']
</py-config> (PY1001): Unable to install package(s) 'tinydb,datetime,pytz,time,os'. Reason: Can't find a pure Python 3 Wheel for package(s) 'tinydb,datetime,pytz,time,os'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel for more information.

(PY1001): Unable to install package(s) 'tinydb,datetime,pytz,time,os'. Reason: Can't find a pure Python 3 Wheel for package(s) 'tinydb,datetime,pytz,time,os'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel for more information. 

<py-config>
packages = ["tinydb", "pytz"]
</py-config>

import datetime

import datetime Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "<exec>", line 136, in <module>
IndexError: list index out of range

async def, using await asyncio.sleep(), and schedule them using one of the loop methods: https://jeff.glass/post/pyscript-asyncio/ (edited)



Setting up virtual environment.... I managed to track it down to pyodide.runPython just freezing on iOS 15.4.1 Safari, although it's working on all other phones I tested. Switching Pyodide versions 0.21.3 to 0.22.0 made it work on my phone and was wondering when we could expect an update?https://pyscript.net/2022.12.1/pyscript.js

https://pyscript.net/2022.12.1/pyscript.js https://pyscript.net/releases/{version}/pyscript.jshttps://pyscript.net/releases/2022.12.1/pyscript.js

print(โhello world?โ)? If itโs indeed a Pyodide issue Iโm sure theyโd love to know about it.



<py-config>
packages = ["prettytable", ]
</py-config>
You may need to add all the other dependencies that you may be using.


FS.writeFile but if I use python's open to write the file, it doesn't get added into the file system 

FS.writeFile but if I use python's open to write the file, it doesn't get added into the file system FS.syncfs() is async? https://github.com/pyodide/pyodide/blob/main/src/tests/test_filesystem.py (edited)
FS.syncfs(True...)... but in the Chrome developer tools I can see it being written to the indexedDB (application tab)import pyodide_js
import pyodide
import js
import asyncio
from datetime import datetime
FS = pyodide_js.FS
def j(d: dict):
return pyodide.ffi.to_js(d, dict_converter=js.Object.fromEntries)
def error(err):
js.console.log(err)
mount_dir = '/data'
print("hi")
async def synctest(writeonce = False):
if not FS.isDir(mount_dir):
FS.mkdir(mount_dir)
FS.mount(FS.filesystems.IDBFS, j({}), mount_dir)
if not writeonce:
js.console.log("Reading from FS")
await FS.syncfs(True, pyodide.ffi.create_proxy(error)) #True => load from file system
js.console.log("done")
js.console.log("Writing to embedded fs")
filename = mount_dir + '/' + ''.join([char for char in str(datetime.now()) if char.isalnum()]) + '.txt'
with open(filename, 'w') as fp:
fp.write(f"Written at {filename}")
js.console.log("done")
js.console.log(f"{FS.readdir(mount_dir)= }")
js.console.log("Syncing to IDBFS")
await FS.syncfs(False, pyodide.ffi.create_proxy(error))
js.console.log("done")
asyncio.ensure_future(synctest(writeonce=False))

from pyodide.code import run_js
from pyodide_js import FS
tmp = run_js("(FS, dir) => () => new Promise((res) => FS.syncfs(dir, res))")
load_from_disk = tmp(FS, True)
save_to_disk = tmp(FS, False)
await load_from_disk()
# ...
await save_to_disk()

FS.syncfs(True...)... but in the Chrome developer tools I can see it being written to the indexedDB (application tab) writeFile seems to work, but now i can't load it on refresh. From your code I think I missed some important steps haha
TypeError:ย objectย NoneTypeย can'tย beย usedย inย 'await'ย expression. I don't think invalidate_caches should matter here
op_factory).
Each time the page loads, it loads the existing files from IDBFS, prints them, writes one more, syncs back to IDBGFS, and prints everything again. (edited)


def debounce(delay: float):
def decorator(func):
def wrapper(*args, **kwargs):
if hasattr(wrapper, "_handle"):
wrapper._handle.cancel()
to_call = functools.partial(func, *args, **kwargs)
wrapper._handle = pyscript.loop.call_later(delay, to_call)
return wrapper
return decorator (edited)

def debounce(delay: float):
def decorator(func):
def wrapper(*args, **kwargs):
if hasattr(wrapper, "_handle"):
wrapper._handle.cancel()
to_call = functools.partial(func, *args, **kwargs)
wrapper._handle = pyscript.loop.call_later(delay, to_call)
return wrapper
return decorator (edited)import js
from pyscript.events import handler,debounce
@handler
@debounce
def foo():
js.console.log("foo called")
@handler
@debounce
def boo(e):
js.console.log("boo called with event")
js.console.log( e )
@handler
@debounce
def loo(*e):
js.console.log("loo called with *event")
js.console.log( e[0] )
js.console.log( e[1] )
@handler(event="click")
@debounce
def doc_click(*e):
js.console.log("doc_click called with *event")
js.console.log( e[0] ) (edited)
@handler be used?@handler(id="some-elem", event="click") which does add_event_listener underneath (edited)




<button py-click="logHello()" disabled>Click me</button>
<py-script>
def logHello():
import js
js.console.log("HI!")
</py-script>

<button py-click="logHello()" disabled>Click me</button>
<py-script>
def logHello():
import js
js.console.log("HI!")
</py-script> 


<button py-click="logHello()" id="btn">Click me</button>
<py-script>
import js
js.document.getElementById("btn").disabled = True
def logHello():
js.console.log("HI!")
</py-script> (edited)


<button class="send-tab-send-button" id="send-tab-send-button" py-onclick="sendTx()" type="button">Send</button>
async def sendTx():
send_button = Element("send-tab-send-button")
if send_button.element.disabled:
print("hello")
send_button.element.disabled = True
this will never print hello 


<button class="send-tab-send-button" id="send-tab-send-button" py-onclick="sendTx()" type="button">Send</button>
async def sendTx():
send_button = Element("send-tab-send-button")
if send_button.element.disabled:
print("hello")
send_button.element.disabled = True
this will never print hello send_button.element.disabled is always False... unless when you set it to True like you're doing in the last line
same behaviour in JS:
function jssendTx() {
let sendButton = document.getElementById("send-tab-send-button");
if (sendButton.disabled) {
console.log("hello");
}
sendButton.disabled = true;
}
I think you might want a different thing in this function (edited)

send_button.element.disabled is always False... unless when you set it to True like you're doing in the last line
same behaviour in JS:
function jssendTx() {
let sendButton = document.getElementById("send-tab-send-button");
if (sendButton.disabled) {
console.log("hello");
}
sendButton.disabled = true;
}
I think you might want a different thing in this function (edited)



import os
os.environ["SOME_VAR"] = โvalueโ
import lib_that_needs_env_vars
โฆ (edited)



/latest, would you try pointing your script tag at https://pyscript.net/unstable/pyscript.js and seeing if using append = False works?

/latest, would you try pointing your script tag at https://pyscript.net/unstable/pyscript.js and seeing if using append = False works? 



sockets. For shimming requests, you could look at pyodide-http


<!-- pyscript 2022.12.1 -->
<button py-click="helloWorld()" id="myBtn">Say Hi</button>
<py-script>
def helloWorld():
print("hello, world!")
</py-script> (edited)onClick syntax:
<!-- pyscript 2022.12.1 -->
<button onClick="javascriptSaysHi()">Say Hi</button>
<script>
function javascriptSaysHi(){
console.log("You could do other things with JS here");
const pythonFunc = pyscript.runtime.globals.get("helloWorld");
pythonFunc();
}
</script>
<py-script>
def helloWorld():
print("hello, world!")
</py-script> (edited)pyscript.runtime isn't a valid object until the Interpreter has loaded - if you try to get that attribute before PyScript has completed loading, you'll get a "No attribute called runtime..." error. But with a button, which the user probably isn't clicking until PyScript has loaded, you should be ok? May be something you have to account for though. (edited)

<!-- pyscript 2022.12.1 -->
<button py-click="helloWorld()" id="myBtn">Say Hi</button>
<py-script>
def helloWorld():
print("hello, world!")
</py-script> (edited)py-click require id to be defined?

py-click require id to be defined? runtime, but that's being renamed to interpreter in the next release; fixed that in the example too




object.click() to click on various elements of the DOM, though, just not move the "physical" mouse pointer


pip install pyodide-build
2. git clone https://github.com/emscripten-core/emsdk.git
3. ./emsdk/emsdk install $(pyodide config get emscripten_version)
4. source emsdk/emsdk_env.sh
5.pyodide build
This should build a wheel. Then you need to serve the wheel and put the wheel url in py-config, and you should be able to import and use it. (edited)


pip install pyodide-build
2. git clone https://github.com/emscripten-core/emsdk.git
3. ./emsdk/emsdk install $(pyodide config get emscripten_version)
4. source emsdk/emsdk_env.sh
5.pyodide build
This should build a wheel. Then you need to serve the wheel and put the wheel url in py-config, and you should be able to import and use it. (edited)

1




1





index.html inside it, you can navigate to the page.
If you want to serve a completely different domain into /test then you need to create some dns records for it





index.html inside it, you can navigate to the page.
If you want to serve a completely different domain into /test then you need to create some dns records for it index.html in different folder?
Like I would have a index.html file in the test folder for a subdirectory /site and a index.html in the main one?

index.html in different folder?
Like I would have a index.html file in the test folder for a subdirectory /site and a index.html in the main one? 






socket = WebSocket.new(url)
socket.binaryType = 'arraybuffer'
socket.onopen = create_proxy(socket_connected)socket.onopen = function (e) {
socket.send(username+":" + response.ticket + "\n");
terminalState = terminalStates.connected;
};



create_proxy needed with pyodide wrappers?


create_proxy needed with pyodide wrappers? create_proxy, and why itโs necessary, and the wrappers at one point at one point: https://jeff.glass/post/pyscript-why-create-proxy/
1


print of my python code... All the text is sent at once when the script stops, which is a bit problematic because we have to enter a value each time and it has to return a certain sentence to continue the operation.




afterStartup() method https://github.com/pyscript/pyscript/blob/25809660efab80046d75314b14c08ff2c5d6194e/pyscriptjs/src/main.ts#L197








<py-terminal auto><py-terminal> change the behavior at all?

<py-terminal auto><py-terminal> change the behavior at all? 

print of my python code... All the text is sent at once when the script stops, which is a bit problematic because we have to enter a value each time and it has to return a certain sentence to continue the operation. 

ImportError: cannot import name 'Mapping' from 'collections' (/lib/python3.10/collections/__init__.py) since Python 3.10 removed Mapping from Collections

ImportError: cannot import name 'Mapping' from 'collections' (/lib/python3.10/collections/__init__.py) since Python 3.10 removed Mapping from Collections import collections
collections.Mapping = collections.abc.Mapping
leads to other broken dependencies, like the scipy.maxentropy module

import collections
collections.Mapping = collections.abc.Mapping
leads to other broken dependencies, like the scipy.maxentropy module 
Pyodide 0.17.0 was the last version to use Python 3.8. But the Pyodide API has changed significantly over time (and continues to), so each release of PyScript tends to be pinned to a specific Pyodide version (Pyodide 2022.12.1 uses Pyodide 0.21.3, for example). (edited)0.17.0 (by coincidence) which is still too recent, if I'm understanding the import errors from gensim right
1 copy.jpg using the PIL moduledef make_greyscale():
from PIL import Image
img=Image.open('1.jpg')
pixels=img.load()
width,height=img.size
output=Image.new('RGB',(width,height))
pixels_out=output.load()
for y in range(height):
for x in range(width):
avg_colors=tuple([sum([pixels[x,y][i] for i in range(3)])//3 for i in range(3)])
pixels_out[x,y]=avg_colors
output.save('1 copy.jpg')
alert("Votre image a รฉtรฉ modifiรฉe avec succรจs.")







import pdb to your code and breakpoint() where you need
I think we're gonna be able to offer a better solution once the webworker patch gets in 
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
from js import document
from pyodide.ffi.wrappers import add_event_listener
test1 = document.getElementById("TEST")
def testevent():
print(test1)
</py-script>
<input id="TEST" />
<button py-click="testevent()" id="new-task-btn" class="py-button">TEST111</button>
</body>
</html>

value attribute of the HTML element to get the user-entered value:
def testevent():
print(test1.value)

testevent method:
<py-script>
from js import document
test1 = document.getElementById("TEST")
def testevent():
print(test1.value)
</py-script>
<input id="TEST" />
<button py-click="testevent()" id="new-task-btn" class="py-button">TEST111</button> (edited)

<py-script> works with the infamous dangerouslySetInnerHTML={{__html:<py-script>...</py-script>}} . But how do I get py-repl to work? Any advice on this or any projects you could refer me to? Or should I abandon react for this project and use something different?
Thanks.
Any advice is appreciated.


clickevent = ',' + '"clickEvent"' +':{'+'"action":'+ f'"{events[event_input]}"' ',' + '"value"' ":" + f'"{value}"' '}'
the f'"{events[event_input]}"' should be
f'"{events[events.index(event_input.value)]}"'#Colour check
for x in color_list:
if color == x:
print(command)
should be
#Colour check
for x in color_list:
if color.value == x:
print(command)
because you need to get the value of the element (edited)













str(strikethrough.checked).lower()




<py-script> works with the infamous dangerouslySetInnerHTML={{__html:<py-script>...</py-script>}} . But how do I get py-repl to work? Any advice on this or any projects you could refer me to? Or should I abandon react for this project and use something different?
Thanks.
Any advice is appreciated. 






[[fetch]]
from = "https://raw.githubusercontent.com/bleach86/material-dashboard/master/"
files = ["composer.json"] (edited)import json
with open('composer.json') as f:
file = json.loads(f.read()) (edited)



[[fetch]]
files = ['/tellraw.py'] (edited)



<py-script src="..."> fetches the file for you
1




<script src="https://pyscript.net/latest/pyscript.js"> Or alpha? Or something else?

<script src="https://pyscript.net/latest/pyscript.js"> Or alpha? Or something else? 

<head>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css">
</head>
<body>
<py-script>
def hello():
print("HI!")
</py-script>
<button id="btn" py-click="hello()">Click me!</button>
</body>
</html><head>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css">
</head>
<body>
<py-script src="demo.py"></py-script>
<button id="btn" py-click="hello()">Click me!</button>
</body>
</html>
#demo.py
def hello():
print("HI!") (edited)

<head>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css">
</head>
<body>
<py-script>
def hello():
print("HI!")
</py-script>
<button id="btn" py-click="hello()">Click me!</button>
</body>
</html> 








src="./demo.py? with the "./" (edited)

src="./demo.py? with the "./" (edited)tellraw as name it wouldnt work



<py-script src="./tellraw.py"> does work for me





tellraw.py still works for me, so I suspect it's something in your environment rather than an issue with PyScript specifically

<input>?value attribute. In that case:
test = Element("text")
my_value = test.element.value


pyodide-http module - thereโs a brand new guide on it here: https://docs.pyscript.net/latest/tutorials/requests.html







panel from packages array in <py-config , everything works. but question is it was working fine even with panel 3 days ago.
<py-script src="hello.py"></py-script>
how do i import the namespace to get some nice IDE tooltips/typehints and autocompletion? and how do i install the library for my IDE to look this up?
I tried pip install pyscript but this only seems to have the cli.
this minimal file is
import pyscript
def display_hello(*args,**kwargs):
display("Hello World", target="helloDiv")
but neither the import nor the display methods can be resolved by pylance despite it is running as expected.

panel from packages array in <py-config , everything works. but question is it was working fine even with panel 3 days ago. 

(PY1001): Unable to install package(s) 'altair,bokeh,numpy,pandas,scikit-learn,panel'. Reason: Can't find a pure Python 3 Wheel for package(s) 'altair,bokeh,numpy,pandas,scikit-learn,panel'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel for more information. Still getting same error. even after removing version of panel..



/latest version, that would have changed a number of things underneath you. (edited)https://pyscript.net/releases/2022.12.1/pyscript.js

https://pyscript.net/releases/2022.12.1/pyscript.js 2022.12.1
latest comes with Pyodide 0.23 (if I remember correctly)



pyscript-local-runtime can be achieved by downloading and unpacking the pyodide-core tar file from github releases:
https://github.com/pyodide/pyodide/releases/download/0.22.1/pyodide-core-0.22.1.tar.bz2

pyscript-local-runtime can be achieved by downloading and unpacking the pyodide-core tar file from github releases:
https://github.com/pyodide/pyodide/releases/download/0.22.1/pyodide-core-0.22.1.tar.bz2 








Can't find a pure Python 3 Wheel for package

Can't find a pure Python 3 Wheel for package -none-any.whl
For packages that *do *have extensions that must be compiled for a specific system, you can think of the web runtime "platform" (CPython running compiled to Web Assembly running in the browser) as being comparable to other platforms that Python packages are compiled to run on, like Windows + AMD64, or maxosx+intel etc. In order to run, packages that have extensions in C, Rust etc must be built for the webassembly environment. Many packages have indeed been pre-built this way by the Pyodide team (see https://pyodide.org/en/stable/usage/packages-in-pyodide.html). If you reference any from that list in your packages key in <py-config>, it will be installed from the Pyodide distribution's prebuilt packages instead of PyPI.
But if you have a package that does require additional compilation and has not yet been built for Pyodide, your options are: try to build it yourself https://pyodide.org/en/stable/development/new-packages.html - and if you do, please submit it as a patch for Pyodide! Or, open a package request issue on the Pyodide repo https://github.com/pyodide/pyodide.

-none-any.whl
For packages that *do *have extensions that must be compiled for a specific system, you can think of the web runtime "platform" (CPython running compiled to Web Assembly running in the browser) as being comparable to other platforms that Python packages are compiled to run on, like Windows + AMD64, or maxosx+intel etc. In order to run, packages that have extensions in C, Rust etc must be built for the webassembly environment. Many packages have indeed been pre-built this way by the Pyodide team (see https://pyodide.org/en/stable/usage/packages-in-pyodide.html). If you reference any from that list in your packages key in <py-config>, it will be installed from the Pyodide distribution's prebuilt packages instead of PyPI.
But if you have a package that does require additional compilation and has not yet been built for Pyodide, your options are: try to build it yourself https://pyodide.org/en/stable/development/new-packages.html - and if you do, please submit it as a patch for Pyodide! Or, open a package request issue on the Pyodide repo https://github.com/pyodide/pyodide. 















IDM options. A quick googling shows me that it is Internet Download Manager, so I guess it's an extension which interferes with webpages?
from js import document and document.createElement) instead of hardcoding them inside <template> tags + using clone?
Context: I want to generate HTML tags on-the-fly without having to specify them in code beforehand (e.g., the kind of tag can come from user input via text field), but I want to avoid figuring out how to add type stubs for js, document, and document.createElement.
Edit: pyodide has a readily available type stub (https://github.com/pyodide/pyodide/blob/main/src/py/js.pyi), but I have to install the completely unrelated js package so Pylance doesn't raise an error about the js package not being installed. I'd still rather avoid having to import js altogether. (edited)



(PY1001): Unable to install package(s) 'requests,browser-cookie3,ctypes,wmi'. Reason: Can't find a pure Python 3 Wheel for package(s) 'requests,browser-cookie3,ctypes,wmi'. See: https://pyodide.org/en/stable/usage/faq.html#micropip-can-t-find-a-pure-python-wheel for more information. (edited)

requests should still still install fine from pypi, but it'll break on usage. I'd suggest looking at pyodide-http to patch requests at runtime
make setup?

make setup? make setup will double check and yell at you if you donโt have them

from pyscript import Element to the top of the file

<script defer src="https://pyscript.net/latest/pyscript.js"></script>
pyscript/build and then serve the build folder./pyscript.jsmake examples and then looking in the pyscriptjs/examples folder
make build and it's the file you said (./pyscript.js)

https://pyscript.net/latest/pyscript.js?
git fetch --tags










requests should still still install fine from pypi, but it'll break on usage. I'd suggest looking at pyodide-http to patch requests at runtime requests?
import sys
if "pyodide" in sys.modules:
import pyodide_http
pyodide_http.patch_all()

requests?
import sys
if "pyodide" in sys.modules:
import pyodide_http
pyodide_http.patch_all() requests to end users in a REPL or similar. But if it gives you the functionality you need, go for it

requests?
import sys
if "pyodide" in sys.modules:
import pyodide_http
pyodide_http.patch_all() 



pyodide in github actions








<button py-click="foo()"></button>
<py-script>
def foo():
print("Hi!")
</py-script>
Where the py-click attribute takes a string of executable Python code, to be executed in the global namespace when the event is triggeredpy-click, py-mouseover, py-focus etc




























<py-repl auto-generate="true" id="repl">
</py-repl>
const repl = document.getElementById("repl");
repl.innerText = 'var = "Imagine I am dynamic"'; (edited)




npm module to import and use? how do you see/think that would work, when there's python code to deal with, and not JS/TS? really curious about this request, thank you!

cv2.VideoCapture(cam_port)









<py-script src="./run_browser.py"></py-script>
#run_browser.py
import ball_mgmt





py-env but the word env is something I am exploring and still you'll need a config there to bootstrap such "env" 
py-env was an old API and was deprecated, the new thing in town is fetch section within py-config

py-env was an old API and was deprecated, the new thing in town is fetch section within py-config 


from js import getPyScriptContext, getPyScriptId
context = getPyScriptContext(getPyScriptId()) (edited)

from js import getPyScriptContext, getPyScriptId
context = getPyScriptContext(getPyScriptId()) (edited)



<script defer src="https://pyscript.net/releases/2023.03.1/pyscript.js"></script>
<py-script id="foo" src="demo.py">
</py-script>
<py-script id="bar" src="demo.py">
</py-script>
<py-script id="baz" src="demo.py">
</py-script>
#demo.py
from pyscript import get_current_display_target
print(get_current_display_target._id)foo bar baz


from pyscript._internal import DISPLAY_TARGET
print(DISPLAY_TARGET) (edited)



<py-config> tag's [[fetch]] syntax: https://docs.pyscript.net/latest/reference/elements/py-config.html#a-name-fetch-fetch-a





window.pyscript.pyScript.interpreter.run(code, outputId); and everything I had worked flawlessly!! (edited)
from pyecharts.charts import Bar
from pyscript._html import HTML
bar = Bar()
bar.add_xaxis(["่กฌ่กซ", "็พๆฏ่กซ", "้ช็บบ่กซ", "่ฃคๅญ", "้ซ่ท้", "่ขๅญ"])
bar.add_yaxis("ๅๅฎถA", [5, 20, 36, 10, 75, 90])
# render ไผ็ๆๆฌๅฐ HTML ๆไปถ๏ผ้ป่ฎคไผๅจๅฝๅ็ฎๅฝ็ๆ render.html ๆไปถ
# ไนๅฏไปฅไผ ๅ
ฅ่ทฏๅพๅๆฐ๏ผๅฆ bar.render("mycharts.html")
display(HTML(bar.render_embed()))
should I be importing pyscript._html import HTML or something else? It would be great if we have some examples of how to encode different MIME types.
display(plt) and display(fig) is just too magical. I guess there are three ways of rendering: an image, HTML, or some json for client side JS to render (like THREE or plotly, bokeh)? (edited)
run_pyscript so I don't need that import, fair enough.
panel.extension('echarts') had the same issue.. eventually figured out that I needed to add:
<script type="text/javascript" src="https://assets.pyecharts.org/assets/v5/echarts.min.js"></script> (edited)
display and Element /DOM in general to work in web-workers? (edited)

display and Element /DOM in general to work in web-workers? (edited)






packages key in <py-config>, like so:
<py-config>
packages = ['openpyxl']
</py-config>openpyxl does appear to work in PyScript, in that at least trying some of the sample code from their homepage works.


























document and anything else in the main thread, I suggest you to not use the execution_thread flag until we can grant/offer a better alternative ... which I'm working on, and it would fix your issue, but it's not part of current offer, sorry.


py-config element ... you can though orchestrate through a build step behind the scene the fetching of such file and be aware that file, once reachable from your public site, won't be private anymore.





config.toml file that points at the file you are after, automating the process, still never making that access token readable to anyone, including people behind that confluence page ... ask IT would be my answer, you have security policies in place and it shouldn't be PyScript responsibility (ever?) to bypass such security policies. I hope this makes sense to you, I am just trying to help the best I can. (edited)


.env to expose these tokens, bu we don't get to decide when these files or env variables are available from the Web and trust me, not only we don't want to know, it's a good security feature we can't know too (imagine an accidental error stack where involved code which includes that private token is revealed in the wild). I hope you'll manage to provide that file behind your confluence curtains, if there's anything else I can try to help with though, just let me know 





<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css"/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<title>Document</title>
</head>
<body>
<py-script>
import random
def guess_the_number():
secret_number = random.randint(1, 250)
attempts = 0
while True:
attempts += 1
guess = int(input("Guess a number between 1 and 250: "))
if guess < secret_number:
print("Too low, Try Again!")
elif guess > secret_number:
print("Too high!")
else:
print(f"Congratulations! You guessed the number in {attempts} attempts.")
break
guess_the_number()
</py-script>
</body>
</html>





xterm option useful 


AttributeError on the d3 example ?
beforePyReplExec and afterPyReplExec and some of its arguments such as src. My code below throws errors when I use it.
from pyscript import Plugin
from js import console
class PyReplTestLogger(Plugin):
def beforePyReplExec(self, interpreter, outEl, src, pyReplTag):
console.log(f'beforePyReplExec called')
console.log(f'before_src:{src}')
console.log(f'before_id:{pyReplTag.id}')
def afterPyReplExec(self, interpreter, src, outEl, pyReplTag, result):
console.log(f'afterPyReplExec called')
console.log(f'after_src:{src}')
console.log(f'after_id:{pyReplTag.id}')
console.log(f'result:{result}')
plugin = PyReplTestLogger()
I get the following browser console error:
Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/home/pyodide/myplugin.py", line 8, in beforePyReplExec
console.log(f'before_src:{src}')
^^^^^^^^^^^^^^^^^^^
TypeError: __str__ returned non-string (type pyodide.ffi.JsProxy) (edited)

beforePyReplExec and afterPyReplExec and some of its arguments such as src. My code below throws errors when I use it.
from pyscript import Plugin
from js import console
class PyReplTestLogger(Plugin):
def beforePyReplExec(self, interpreter, outEl, src, pyReplTag):
console.log(f'beforePyReplExec called')
console.log(f'before_src:{src}')
console.log(f'before_id:{pyReplTag.id}')
def afterPyReplExec(self, interpreter, src, outEl, pyReplTag, result):
console.log(f'afterPyReplExec called')
console.log(f'after_src:{src}')
console.log(f'after_id:{pyReplTag.id}')
console.log(f'result:{result}')
plugin = PyReplTestLogger()
I get the following browser console error:
Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/home/pyodide/myplugin.py", line 8, in beforePyReplExec
console.log(f'before_src:{src}')
^^^^^^^^^^^^^^^^^^^
TypeError: __str__ returned non-string (type pyodide.ffi.JsProxy) (edited)

<script defer src="https://pyscript.net/latest/pyscript.js"></script> , but I can see from the browser console that the corresponding versions are PyScript 2022.12.1.dev with Pyodide pyodide-0.23.2 @Jeff Glass (edited)
https://pyscript.net/latest/pyscript.js. Possibly something could be broken on the CICD as the latest code on GitHub appears to be newer? (edited)

<script defer src="https://pyscript.net/latest/pyscript.js"></script> , but I can see from the browser console that the corresponding versions are PyScript 2022.12.1.dev with Pyodide pyodide-0.23.2 @Jeff Glass (edited)latest, thatโs the right one - the baked-in version number didnโt get updated before the release 
py-repl to have the dark theme?





pyscript.interpreter.runPython available once it bootstrap, if not I think using "raw pyodide" would work too.

js.d3 isn't being found because d3 isn't loaded?












<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css"/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
print('hello world!')
</py-script>
<div>
<center><h2>code your python</h2></center>
<div><center><h3>pro tip: press <b>shift + enter</b> to execute the code</h3></center></div>
<py-repl id="my-repl" auto-generate="true">
</py-repl>
</div>
</body>
</html>
why is the hello world output is behind in a seperate box like terminal









async def connect(self):





execs its provided string as code https://3748111e-bd36-4293-8467-08ca7d447289.pyscriptapps.com/499b2a08-fa90-489a-b68f-4eb7de971c77/latest/




import { env } from 'polyscript';
const interpreter = await env.pyodide;
// or env.micropython
// or env.wasmoonpolyscript is a module that exports a few things, including an env Proxy that resolves whenever a script with type xyz is bootstrapped on the page, or whenever a specific env is used ... if you don't specify any specific env, grabbing the interpreter is just env.pyodide and you don't need any hook ... and BTW, hooks are not shared globally, so I am not sure I understood your solution, but glad it worked anyway 

polyscript is a module that exports a few things, including an env Proxy that resolves whenever a script with type xyz is bootstrapped on the page, or whenever a specific env is used ... if you don't specify any specific env, grabbing the interpreter is just env.pyodide and you don't need any hook ... and BTW, hooks are not shared globally, so I am not sure I understood your solution, but glad it worked anyway <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="micropython"></script>
<script type="module">
import { env } from 'https://esm.sh/polyscript';
const { runPython } = await env.micropython;
runPython(`from js import document;document.body.textContent = "Hello There"`);
</script>
</head>
</html> (edited)
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test Prodigio v0.1</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="container">
Loading...
</div>
<py-config src="./pyscript.json" type="json"></py-config>
<py-script src="./main.py"></py-script>
</body>
</html>
and this is my main.py:
from pyscript import Element
Element("container").write("It's working")
Unfortunately I receive this error. How to solve it? The same code works perfectly on pyscript.com as you can find and see at this link: https://12bbb25e-4e45-499b-8cab-e628d34b80e0.pyscriptapps.com/b2dd9786-5716-4539-bf06-0ba0eeaab8d3/latest/
Thanks if you can help me to understand what is wrong. (edited)









.py files and AFAIK any other "normal hosting area" ... why would your server block serving python? I understand maybe the mime type can be just text instead of the proper one, but blocking it feels weird ... as if there's anything able to execute it in the server if accessed by a browser (which is never the case)main.py to main.txt and see what happens there, as AFAIK (and IIRC) we don't check extensions there, we just fetch these files (edited)





pyscript module?!? (edited)


.txt somehow, except the right mime-type should be provided. (edited)


<!-- original -->
<input id="htest" type="hidden" value="0" />
<!-- new value -->
<input id="htest" type="hidden" value="1" />
I tried to use this code in pyscript:
from pyscript import Element
Element("htest").write("1")
but I obtained only a version like this:
<input id="htest" type="hidden" value="0">1</input>
I searched in the manual a solution but without success. Any idea?
Thanks
from pyscript import Element
el = Element("htest")
el.element.value = "1"
Thank anyway
<input id="htest" type="hidden" value="0">1</input>


<script type="module">
import { XWorker } from 'https://esm.sh/polyscript';
new XWorker('./your-project.py', {
type: 'pyodide',
config: {
fetch: ['./a.py', './b.py'],
packages: ['numpy']
}
});
</script>
this will create a worker that botstraps pyodide once and the main difference with main thread is that to reach the document you need to from polyscript import xworker; document = xworker.window.documentdocument, likely exposing that xworker.window.document reference in the global so that code using js.document would still work without changes.















pyodide.setStdout https://pyodide.org/en/stable/usage/api/js-api.html#pyodide.setStdout
class MyWriter(io.StringIO):
def write(self, text):
xworker.sync.display(text)
sys.stdout = MyWriter()
sys.stderr = MyWriter() (edited)

worker.onerror = ({error}) => { do what you want }; after you create XWorker('./file.py') and the whole dance behind the scene is done automatically. That allows you, and us, to show errors from both main and worker in the page ... otherwise, in general, yes, Workers on the Web works only out of postMessage orchestration (optionally + Atomics + Proxy as we do here). (edited)

class MyWriter(io.StringIO):
def write(self, text):
xworker.sync.display(text)
sys.stdout = MyWriter()
sys.stderr = MyWriter() (edited)from pyodide_js import setStdout

from pyodide_js import setStdout xworker.sync.showError(...) and there is a counter part, that'd work for errors or generic logs


postMessage out of the blue ... you need sync there, otherwise the listener ignores any request (security reasons) .... but I am not sure I follow the multiple scripts question ... you mean multiple workers? @ntoll did a demo of dozen pompom landing on main out of dozen workers, I am sure the details are maybe blocking, but it should be already possible, whatever you are doing. P.S. to run async stuff, just pass the async option as true when creating XWorker ... it's _async in pyodide, in case you spin workers from pyodide from the main thread, instead of JS

postMessage out of the blue ... you need sync there, otherwise the listener ignores any request (security reasons) .... but I am not sure I follow the multiple scripts question ... you mean multiple workers? @ntoll did a demo of dozen pompom landing on main out of dozen workers, I am sure the details are maybe blocking, but it should be already possible, whatever you are doing. P.S. to run async stuff, just pass the async option as true when creating XWorker ... it's _async in pyodide, in case you spin workers from pyodide from the main thread, instead of JS const pyWorker = XWorker("./empty.py", { type: "pyodide" });
export function execPyCode(code, divId) {
try {
await pyWorker.execAsync(code, { context: { divId } });
} catch (e) { showError(divId, e); }
I got this to work with webR (and pyscript on main-thread), just for fun here is the code:
const webR: WebR = new WebR();
// This will throw an error if code execution failed!
export async function webRExec(code: string, id: string, options: WebRScriptOptions) {
// bootstraps webR interpreter only when this is called, which is nice. for pyscript it always loads pyodide on page load unfortunately. not sure about workers.
await webR.init();
const elem = document.getElementById(id);
await webR.installPackages(options.packages);
const env = await new webR.REnvironment({ context: options.context });
await webR.evalRVoid(code, { env });
const msgs = await webR.flush();
... handle canvasImage and canvasNewPage messages ...
} (edited)
once: trueis set to true here so i can only exec one code block for each worker https://github.com/pyscript/polyscript/blob/0bb0a5cb0a311cdff2939a92be096dd0d6feb2d3/esm/worker/_template.js#L40. it'd be nice to support multiple executions (edited)
js module in VSCode?
I was looking into source code and all imports from js import ... are wrapped like at attached screenshot.
Does anyone have any tips? 

once: trueis set to true here so i can only exec one code block for each worker https://github.com/pyscript/polyscript/blob/0bb0a5cb0a311cdff2939a92be096dd0d6feb2d3/esm/worker/_template.js#L40. it'd be nice to support multiple executions (edited)sync and from the main thread you can await xworker.sync.execute_thing({some, data}) ... the sync.execute_thing in the worker must be a callback (sync or async) and it will receive thta object with some data fields ...sync utility allows dual way exchanges but in the worker it can be sync (unless you explicitly return a Promise from main) while in the main you inevitably need to await results, if needed, because main can't block the thread.


pyodide which offers runPythonAsync (can't remember if that's the exact name) so your execute_thing python function would accept data or any string from the main or from where you fetch such data and pass it to the worker that can evaluate python ... the worker is just a "regular" pyodide env and the xworker is there to facilitate these kind of use cases
from polyscript import xworker
import pyodide
import micropip
document = xworker.window.document
async def run_async(code):
return await pyodide.code.eval_code_async(code)
async def micropip_install(packages):
return await micropip.install(packages)
xworker.sync.runAsync = run_async
xworker.sync.micropipInstall = micropip_install

from polyscript import xworker
import pyodide
import micropip
document = xworker.window.document
async def run_async(code):
return await pyodide.code.eval_code_async(code)
async def micropip_install(packages):
return await micropip.install(packages)
xworker.sync.runAsync = run_async
xworker.sync.micropipInstall = micropip_install pyodide.runPythonAsync in both polyscript and pyscript next, maybe that works better?async declaration, neither await in return ... from main, those functions will be always async, and the returned promise will fulfill out of the box:
def run_async(code):
return pyodide.code.eval_code_async(code)
def micropip_install(packages):
return micropip.install(packages) async anyway in JSawait results, so maybe your code is just fine, as it requires less back and forward from the two worlds.

py-repl tag. It seems like some reveal-js styles are being applied to py-repl tag and that results in input window looking bad.




const options = {
type: 'pyodide',
config: {},
onWorkerReady: function(interpreter, worker) { console.log(interpreter, worker);},
};
new XWorker('./worker.py', options);
gives error core.js:1 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Worker': function(interpreter, worker) { console.log(interpreter, worker); } could not be cloned.
Edit: I added a xworker.sync.onWorkerReady and got unblocked here.. (edited)




<py-config type="toml">
packages = ["no-api-sdk"]
</py-config>
I think that also you don't really need if __name__ == "__main__": statement (edited)

<py-config type="toml">
packages = ["no-api-sdk"]
</py-config>
I think that also you don't really need if __name__ == "__main__": statement (edited)
<button py-click="on_click()">Click me..</button>
if show_h1:
<h1>Hello World</h1>
<py-script>
def on_click():
show_h1 = True
</py-script>
Comming from the Blazor world this is normal, is it like this in pyscript as well?


// python
import asyncio
async def hello():
return 1
// export hello to JavaScript..
console.log(await hello())

// python
import asyncio
async def hello():
return 1
// export hello to JavaScript..
console.log(await hello()) import js
async def hello():
return 1
js.hello_func = hello
console.log(await hello_func())

import js
async def hello():
return 1
js.hello_func = hello
console.log(await hello_func()) 
js that way, the object is a pyproxy, but that pyproxy is awaitable/thenable. Under the hood, thereโs a bunch of feature detection that happens (is the python object callable, enumerable, iterable, etc) and a JavaScript PyProxy object is created with โmatchingโ characteristics
<py-script>
import js
import asyncio
import time
class Test:
def __init__(self):
self.val = 1
async def run(self):
while True:
self.val += 1
time.sleep(1)
js.test = Test()
</py-script>
<script>
(function runTest(){
if(window.test){
console.log("Starting");
test.run();
console.log("Started");
setInterval(() => console.log(test.val), 1000); // this never logs?? <----------
}else{
setTimeout(runTest, 100);
}
})()
</script>
My console freezes running this, and the tab uses 100% of CPU? Should I be using an alternative to time.sleep? (edited)

<py-script>
import js
import asyncio
import time
class Test:
def __init__(self):
self.val = 1
async def run(self):
while True:
self.val += 1
time.sleep(1)
js.test = Test()
</py-script>
<script>
(function runTest(){
if(window.test){
console.log("Starting");
test.run();
console.log("Started");
setInterval(() => console.log(test.val), 1000); // this never logs?? <----------
}else{
setTimeout(runTest, 100);
}
})()
</script>
My console freezes running this, and the tab uses 100% of CPU? Should I be using an alternative to time.sleep? (edited)await asyncio.sleep()





time.sleep is a busy loop:
https://github.com/emscripten-core/emscripten/blob/main/system/lib/pthread/library_pthread_stub.c#L392-L401

<py-script>
import js
import asyncio
import time
class Test:
def __init__(self):
self.val = 1
async def run(self):
while True:
self.val += 1
await asyncio.sleep(1)
js.test = Test()
</py-script>
<script>
(function runTest(){
if(window.test){
console.log("Starting");
test.run();
console.log("Started");
setInterval(() => console.log(test.val), 1000);
}else{
setTimeout(runTest, 100);
}
})()
</script> (edited)

<py-script>
import js
import asyncio
import time
class Test:
def __init__(self):
self.val = 1
async def run(self):
while True:
self.val += 1
await asyncio.sleep(1)
js.test = Test()
</py-script>
<script>
(function runTest(){
if(window.test){
console.log("Starting");
test.run();
console.log("Started");
setInterval(() => console.log(test.val), 1000);
}else{
setTimeout(runTest, 100);
}
})()
</script> (edited)


<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"
}
}
</script>
"works" (exactly as it should, and used to), to the extent that I see [plugins/importmap] Registering JS module three in the browser console, but there is absolutely no hint as to how to actually import it into Python. The previous from three import (AmbientLight, etc... does NOT work (nor does any other obvious syntax). Note that simply sourcing three works perfectly, but three are planning to deprecate everything but modules Real Soon Now.



PyScript Next preview?


PyScript Next preview?
https://pyscript.net/releases/2023.05.1/pyscript.js





<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"
}
}
</script>
"works" (exactly as it should, and used to), to the extent that I see [plugins/importmap] Registering JS module three in the browser console, but there is absolutely no hint as to how to actually import it into Python. The previous from three import (AmbientLight, etc... does NOT work (nor does any other obvious syntax). Note that simply sourcing three works perfectly, but three are planning to deprecate everything but modules Real Soon Now. 

<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script type="module">
import * as three from 'three';
globalThis.three = three;
</script>
<py-script>
from js import three
print(three.AmbientLight)
</py-script>


<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script type="module">
import * as three from 'three';
globalThis.three = three;
</script>
<py-script>
from js import three
print(three.AmbientLight)
</py-script> globalThis.three = three; !!! OMG... TYSM, that's what I was missing![plugins/importmap] Registering JS module three do?

[plugins/importmap] Registering JS module three do? import 'three' in your JS code (not in Workers, because Web development gotta suck somehow anyway)
No 'Access-Control-Allow-Origin' header is present on the requested resource. error. Is there any way around it?

<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script type="module">
import * as three from 'three';
globalThis.three = three;
</script>
<py-script>
from js import three
print(three.AmbientLight)
</py-script> 



<!doctype html>
<html lang="en">
<head><!-- Use one of the examples below--></head>
<body>
<script type="module">
import * as three from 'three';
globalThis.three = three;
</script>
<py-script>
from js import three, document, Object, requestAnimationFrame
from pyodide.ffi import to_js, create_once_callable
scene = three.Scene.new()
camera = three.PerspectiveCamera.new(75, 1, 0.1, 1000)
renderer = three.WebGLRenderer.new()
renderer.setSize(400,400)
document.body.appendChild(renderer.domElement)
geometry = three.BoxGeometry.new(1,1,1)
material = three.MeshBasicMaterial.new(to_js({'color': 0x00ff00}, dict_converter=Object.fromEntries))
cube = three.Mesh.new(geometry, material)
scene.add(cube)
camera.position.z = 5
def animate(*args):
requestAnimationFrame(create_once_callable(animate))
cube.rotation.x += 0.01
cube.rotation.y += 0.01
renderer.render(scene, camera)
animate()
</py-script>
</body>
</html><head> you can use either the PyScript Next core current release (in beta):
<head>
<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@pyscript/core@0.1.10/dist/core.js"></script>
</head>
or PyScript Classic:
<head>
<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script defer src="https://pyscript.net/releases/2023.05.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2023.05.1/pyscript.css">
</head>

<head> you can use either the PyScript Next core current release (in beta):
<head>
<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@pyscript/core@0.1.10/dist/core.js"></script>
</head>
or PyScript Classic:
<head>
<script type="importmap">
{"imports": {"three": "https://cdn.jsdelivr.net/npm/three@0.154.0/build/three.module.js"}}
</script>
<script defer src="https://pyscript.net/releases/2023.05.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2023.05.1/pyscript.css">
</head> 
import { OrbitControls } from 'OrbitControls'; (with the {} object destructuring)

<script type="module">
import * as three from 'three';
globalThis.three = three;
import { OrbitControls } from 'OrbitControls';
globalThis.OrbitControls = OrbitControls;
</script>

<script type="module">
import * as three from 'three';
globalThis.three = three;
import { OrbitControls } from 'OrbitControls';
globalThis.OrbitControls = OrbitControls;
</script> 



<py-config>
[[fetch]]
files = ["/request.py"]
</py-config> (edited)

















xworker.postMessage('init') and the python side listen to the message.
But now I wonder whether this is guaranteed to work or if there is a possible error condition


xworker.postMessage('init') and the python side listen to the message.
But now I wonder whether this is guaranteed to work or if there is a possible error condition 



















xworker.postMessage('init') and the python side listen to the message.
But now I wonder whether this is guaranteed to work or if there is a possible error condition py:ready event now that is triggered on the main thread for whenever main scripts or workers are ready to run/execute the code ... the event is triggered right before so that using a queueMicrotask(callback) to use anything from the worker would do ... and btw, sync uses an async guard so in general on main you can always use it to define whatever you like but I haven't tried the other way around ... although I think, by design, it should work.postMessage('init') from @antocuni shouldn't be needed at all anymore




open, file.read(), file.write, os.listdir/cwd/chdir etc) work normally with this filesystem. Just remember that nothing in this filesystem is persistent - it all goes away when the page unloads, so if you need to persist data, you may need to use a more persistent filesystem like IndexDB, or have the user download the file(s), or use a more web ish solution like a database backing your application.


pydom package https://fpliger.pyscriptapps.com/pyweb/latest/pydom.html

from pyscript import document to make you're threads worker-friendly. Basically, in the main thread, document is js.document, and in a worker, it's a proxy for the main thread/page's document.

requests library using pyodide-http to make get, post requests: https://github.com/pyscript/pyscript/blob/2023.05.1/docs/tutorials/requests.mdpyfetch from Pyodide directly:
https://github.com/pyscript/pyscript/blob/2023.05.1/docs/tutorials/requests.md
https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.pyfetchrequest function is a little much IMHO, and the name collision with requests has been troublesome. I'd just patch requests or use pyfetch, depending on whether you want blocking or non-blocking.


env export and await env['py-script'] when you have pyodide there and you can do whatever you want with it, as that's the interpreter you were after before. Please note with workers the story is a bit different as there is a sync utility instead but that's very new and probably not what you are looking for at this point.window.addEventListener('py:ready', clalback) event which receives the node that bootstrapped ... or you can import hooks from the module, add any onInterpreterReady or onBeforeRun callback which will be invoked with the node and the wrapper with all the utilities, including the interpreter.import { hooks } form '@pyscript/core';
hooks.onInterpreterReady.add((wrap, element) => { console.log(wrap); });
as example. (edited)wrap.interpreter will be pyodide with its own API https://pyscript.github.io/polyscript/#custom-scripts-wrappers

js module:
import js
def foo(arg):
print(arg)
js.fooFunc = foo
Will create a JS object in the global scope called fooFunc that is a proxy for the Python function foofrom pyscript import window to always grab a reference to the main threadโs global scope, even if your python code is running in a worker, but I havenโt tested if assigned to that works the same as assigning to js




js module:
import js
def foo(arg):
print(arg)
js.fooFunc = foo
Will create a JS object in the global scope called fooFunc that is a proxy for the Python function foo 

from pyscript import window to always grab a reference to the main threadโs global scope, even if your python code is running in a worker, but I havenโt tested if assigned to that works the same as assigning to js 
main thread global context you use from pyscript import window instead of import js ... js is still there but it refers to the global context in the worker, unreachable by main out of the box.

js module is always a reference to the current global scope. When run in a worker, that means that worker's global scope, which isn't available to js in the main thread
from pyscript import window in main, you get the equivalent of js ... so that when the main world is desired, always use from pyscript import window instead, and you'll have portable code for both workers and main thread.
from pyscript import document always reference's the main thread's document. A lot of older PyScript (and Pyodide) examples import document, so this is a handy "drop in" fix to make them work in workers







js module is just a "wormhole" in the space/time (browser) continuum that connects the Python world with the parallel reality that is JavaScript (and vice versa). Stuff is sent to/from the wormhole between the two worlds. But the js module in Python itself is only the wormhole layer, the actual work is happening over in the JavaScript world (it works both ways).js wormhole (and the js wormhole is passing stuff to/from the JavaScript world behind the scenes).









packages = ["https://github.com/pygame-web/archives/blob/main/repo/pkg/panda3d-1.11.0-cp311-cp311-wasm32_bi_emscripten.whl" ]
(Lemme just try)(PY1001): Unable to install package(s) 'https://github.com/pygame-web/archives/blob/main/repo/pkg/panda3d-1.11.0-cp311-cp311-wasm32_bi_emscripten.whl'. Reason: Traceback (most recent call last): File "/lib/python3.11/site-packages/micropip/_micropip.py", line 576, in install await transaction.gather_requirements(requirements) File "/lib/python3.11/site-packages/micropip/_micropip.py", line 342, in gather_requirements await gather(*requirement_promises) File "/lib/python3.11/site-packages/micropip/_micropip.py", line 353, in add_requirement wheel.check_compatible() File "/lib/python3.11/site-packages/micropip/_micropip.py", line 134, in check_compatible raise ValueError( ValueError: Wheel was built with Emscripten vwasm32.bi.emscripten but Pyodide was built with Emscripten v3.1.32 . Please open an issue at https://github.com/pyscript/pyscript/issues/new if you require help or you think it's a bug.















run_until_complete is a synonym for asyncio.ensure_future. There's some notes in their source about why and possible alternatives: https://github.com/pyodide/pyodide/blob/5dbb91a769862c79d42835614df70ecf4041752e/src/py/pyodide/webloop.py#L248-L264 (edited)

alpha release is almost 18 months old, the most recent release is https://pyscript.net/releases/2023.05/1/pyscript.js (edited)input is tricky in the browser - it relies on blocking the python thread, waiting for the terminal to pass along input from another thread... but the browser only has one thread*, so things lock up

input is tricky in the browser - it relies on blocking the python thread, waiting for the terminal to pass along input from another thread... but the browser only has one thread*, so things lock up 

input is tricky in the browser - it relies on blocking the python thread, waiting for the terminal to pass along input from another thread... but the browser only has one thread*, so things lock up 

2023.09.1.RC1. Essentially a beta release. That one's actually a from-the-ground-up rewrite of the entire core of pyscript.

run_until_complete is a synonym for asyncio.ensure_future. There's some notes in their source about why and possible alternatives: https://github.com/pyodide/pyodide/blob/5dbb91a769862c79d42835614df70ecf4041752e/src/py/pyodide/webloop.py#L248-L264 (edited)

<script defer src=โ:https//pyscript.net/alpha/pyscript.jsโ></script> I am not sure where you copied the example code but all quotes are broken as these should be " and not โ or โ plus your URLs start with a : colon ... nothing in that HTML is strictly valid so maybe the issue is your IDE?

<script defer src=โ:https//pyscript.net/alpha/pyscript.jsโ></script> I am not sure where you copied the example code but all quotes are broken as these should be " and not โ or โ plus your URLs start with a : colon ... nothing in that HTML is strictly valid so maybe the issue is your IDE? 


pyodide.ffi has no attribute wrappers (edited)





from pyscript import document
import time
def printTutorial(event):
# input label #input id tag name # get value from input input_text.value
input_text = document.querySelector("#input")
# this is for output id name #output div tag
output_div = document.querySelector("#output")
output_div.innerText += " " + input_text.value + "\n"
if input_text.value == "yes":
output_div = document.querySelector("#output")
output_div.innerText += "no this is not yes" + "\n"
input_text.value = ""
if __name__ == "__main__":
currentTime = time.localtime()
#Hour/Minute/Second
clock = document.querySelector("#time")
clock.innerText = time.strftime("%H:%M:%S", currentTime)
# day/month/Year
day = document.querySelector("#cal")
day.innerText = time.strftime("%d.%m.%Y", currentTime) 
<link rel="stylesheet" href="https://pyscript.net/snapshots/2023.09.1.RC2/core.css" />
<script type="module" src="https://pyscript.net/snapshots/2023.09.1.RC2/core.js"></script> (edited)

<link rel="stylesheet" href="https://pyscript.net/snapshots/2023.09.1.RC2/core.css" />
<script type="module" src="https://pyscript.net/snapshots/2023.09.1.RC2/core.js"></script> (edited)
<py-repl> being one of them.
It's coming... (and it'll be much closer to a "normal" Python REPL than the previous version).
<py-script output="pytest">
from datetime import datetime
now = datetime.now()
print("Hello world!\nThis is the current date and time, as computed by Python:")
print(now.strftime("%m/%d/%Y, %H:%M:%S"))
</py-script>

<py-script output="pytest">
from datetime import datetime
now = datetime.now()
print("Hello world!\nThis is the current date and time, as computed by Python:")
print(now.strftime("%m/%d/%Y, %H:%M:%S"))
</py-script> output but you can always use the display utility

output but you can always use the display utility 

<py-script>
from pyscript import display
from datetime import datetime
now = datetime.now()
display("Hello world!\nThis is the current date and time, as computed by Python:", target="pytest")
display(now.strftime("%m/%d/%Y, %H:%M:%S"), target="pytest")
</py-script>

output but you can always use the display utility 

<py-script>
from pyscript import display
from datetime import datetime
now = datetime.now()
display("Hello world!\nThis is the current date and time, as computed by Python:", target="pytest")
display(now.strftime("%m/%d/%Y, %H:%M:%S"), target="pytest")
</py-script> 

output attribute but for your use case I think display would dodisplay is there out of the box, you don't need to import it also because there is no pyscript module AFAIK.










Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 499, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 340, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 11, in <module>
NameError: name 'pyscript' is not defined

<head>, theyโre linking to the alpha release from last Mayโฆ but in theory you can use the latest release candidate by changing those tags to point at https://pyscript.net/releases/2022.05.1/pyscriptโjs (and pyscript.css, or to the new west release candidate at https://pyscript.bet/releases/2023.09.1.RC2/core.js (and core.css)

<head>, theyโre linking to the alpha release from last Mayโฆ but in theory you can use the latest release candidate by changing those tags to point at https://pyscript.net/releases/2022.05.1/pyscriptโjs (and pyscript.css, or to the new west release candidate at https://pyscript.bet/releases/2023.09.1.RC2/core.js (and core.css) 

Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 499, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 340, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 11, in <module>
NameError: name 'pyscript' is not defined import pyscript
Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 499, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 340, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 12, in <module>
AttributeError: module 'pyscript' has no attribute 'run_until_complete'Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 491, in eval_code
CodeRunner(
File "/lib/python311.zip/_pyodide/_base.py", line 268, in __init__
self.ast = next(self._gen)
^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 145, in _parse_and_compile_gen
mod = compile(source, filename, mode, flags | ast.PyCF_ONLY_AST)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 46
pass
IndentationError: unexpected indent

Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 491, in eval_code
CodeRunner(
File "/lib/python311.zip/_pyodide/_base.py", line 268, in __init__
self.ast = next(self._gen)
^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 145, in _parse_and_compile_gen
mod = compile(source, filename, mode, flags | ast.PyCF_ONLY_AST)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 46
pass
IndentationError: unexpected indent 
run_until_complete method.run_until_compete doesnโt really work in Pyodide, since you canโt block the main execution thread while waiting for a coroutine. In Pyodide itโs just a proxy for ensure_future

run_until_compete doesnโt really work in Pyodide, since you canโt block the main execution thread while waiting for a coroutine. In Pyodide itโs just a proxy for ensure_future async attribute to allow top level async code in Pyodide so be sure your script/tag has an async when the code is going to run is async too.

async attribute to allow top level async code in Pyodide so be sure your script/tag has an async when the code is going to run is async too. async tag is essentially:
<script type="py" async>
# your code here
import asyncio
await asyncio.sleep(1) # 'await' outside an async function == top level await
print("done")
</script>
<!-- is equivalent to-->
<script type="py">
async def _temp():
# your code here
import asyncio
await asyncio.sleep(1)
print("done")
asyncio.ensure_future(_temp())
</script>
So depending on what you're doing, using an async tag is a really convenient way to run coroutines on the page. But if you're running tasks/coroutines manually in some way anyway, it doesn't add anything on top of that.

async tag is essentially:
<script type="py" async>
# your code here
import asyncio
await asyncio.sleep(1) # 'await' outside an async function == top level await
print("done")
</script>
<!-- is equivalent to-->
<script type="py">
async def _temp():
# your code here
import asyncio
await asyncio.sleep(1)
print("done")
asyncio.ensure_future(_temp())
</script>
So depending on what you're doing, using an async tag is a really convenient way to run coroutines on the page. But if you're running tasks/coroutines manually in some way anyway, it doesn't add anything on top of that. 

async tag is essentially:
<script type="py" async>
# your code here
import asyncio
await asyncio.sleep(1) # 'await' outside an async function == top level await
print("done")
</script>
<!-- is equivalent to-->
<script type="py">
async def _temp():
# your code here
import asyncio
await asyncio.sleep(1)
print("done")
asyncio.ensure_future(_temp())
</script>
So depending on what you're doing, using an async tag is a really convenient way to run coroutines on the page. But if you're running tasks/coroutines manually in some way anyway, it doesn't add anything on top of that. 

>>> import asyncio
await asyncio.sleep(2)
print("FOO")
Into the Pyodide console, it will "sleep" asynchronously for 2 seconds then print. That's not possible unless you have top level await available (edited)


fut = asyncio.ensure_future(_temp()) since Futures/Tasks that don't have a referenced held to them can be cleaned up by GC basically whenever, even if they're still running

fut = asyncio.ensure_future(_temp()) since Futures/Tasks that don't have a referenced held to them can be cleaned up by GC basically whenever, even if they're still running await _temp() prints fine so it threw me off, but makes sense (edited)

await _temp(). ensure_future just schedules the task and await blocks..
demo: https://bugzpodder.pyscriptapps.com/piratical-copy-copy/latest/. 'done3' is printed before 'done' (edited)
await waits on the promise to resolve, and ensure_future just schedules it in to the event loop and doesn't block... let me look at your demo...async attribute in your tags...

await waits on the promise to resolve, and ensure_future just schedules it in to the event loop and doesn't block... let me look at your demo... 
async attribute, the other in a separate tag

asyncio.ensure_future(_temp()) followed by print('done3'). i wanted print to happen after _temp() is completed by i guess this is not possible unless i create another async function and run it in main. like: async main():\n await _temp()\n print('done3') and use asyncio.ensure_future(main())
await your awaitable (where possible), or wrap them in another awaitable like you say. (edited)async tag?async tag?

async tag? 




/latest and the RC2 candidate. You should only use one or the other - if you want to use pydom, it should be the release candidate

/latest and the RC2 candidate. You should only use one or the other - if you want to use pydom, it should be the release candidate 






pydom. Basically, instead of Element("input1") you should use pydom["#input1"]
I'm out right now but can check it out later.

pydom. Basically, instead of Element("input1") you should use pydom["#input1"]
I'm out right now but can check it out later. 

value attribute directly to the returned collection (and Element) in pydom. I'll put a PR to improve things tomorrow.
Obrigado!!



value attribute directly to the returned collection (and Element) in pydom. I'll put a PR to improve things tomorrow.
Obrigado!! 

value to pydom.Element yet (we'll be adding attributes gradually because we want to be careful, keeping the API small and focused on the part of the HTML API that is most use). Element in your example is strictly focused on input elements [value attribute] and, yes, it's not the same use case but once we add value to pydom.Element you'll be able to simply do pydom["#input1"].value.

repl in the upcoming release and we'd love to understand the many possible use cases are... It's likely that we'll have a simpler repl (probably being renamed to terminal and we'll add another type for more complex use cases)



repl in the upcoming release and we'd love to understand the many possible use cases are... It's likely that we'll have a simpler repl (probably being renamed to terminal and we'll add another type for more complex use cases) 
<script type="py>... (maybe @Andrea Giammarchi has other ideas...)
This type of need is something we were looking at anyway but it hasn't been prioritized in this next release. Probably something we'll be making it easier to support in the future.




























goslate package is not part of the running code so you should likely add that to a py-config tag or literal object, depending on how you bootstrap pyscript ... none of that looks like a security concern and be assured the erros you see in your devtool console are yours to read ... we don't know, store, read, anything happining locally in your browser/site/env.

























https://pyscript.net/unstable/core.js
TypeError: Cannot read properties of undefined (reading 'call')
at Object.ct [as runEvent] (_python.js:36:22)
at HTMLButtonElement.Ht (listeners.js:42:17)











<py-repl> in pyscript classic used a shadow DOM to wrap up the CodeMirror editor, output section, etc, if you wanted to look at an example of what that looked like. https://github.com/pyscript/pyscript/blob/2023.05.1/pyscriptjs/src/components/pyrepl.ts In the Next release, weโre not doing that much DOM manipulation, so not sure how maintaining a virtual DOM would speed anything up, and thereโs not much to โhideโ with a shadow DOMโฆ








.
|-- aksharamukha
| |-- Convert.py
| |-- transliterate.py
|-- demo.py
|-- requirements.txt
|-- test-server
| |-- __init__.py
| |-- config.json
| |-- index.html
| `-- main.py
test-server/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Script Transcription</title>
<!-- PyScript CSS -->
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css">
<!-- This script tag bootstraps PyScript -->
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="root"></div>
<div id="jsroot"></div>
<textarea id="hi">เคงเคฐเฅเคฎ เคญเคพเคฐเคค เคเฅ </textarea>
<textarea id="kn"></textarea>
<button id="transliterate">Transliterate</button>
<py-config type="json" src="config.json"></py-config>
<script type="py" src="main.py" config="config.json"></script>
<script>
window.show = (fromTxt, translated, map) => {
const root = document.getElementById('jsroot')
console.info({fromTxt, translated, map})
}
</script>
<py-repl>import os
print(os.listdir())
print(os.listdir('./pyscript'))</py-repl>
</body>
</html>
test-server/config.josn
{
"packages":[
"regex",
"Flask>=2.0.3",
"Flask-CORS>=3.0.6",
"Requests>=2.20.1",
"pyyaml>=5.4.1",
"regex>=2021.8.3",
"fonttools[unicode]>=4.27",
"lxml"
],
"fetch": [{
"files": [
"../test-server/__init__.py",
"../test-server/main.py",
"../aksharamukha/Convert.py",
"../aksharamukha/transliterate.py",
...rest of the files...
]
}]
}
I am getting No module named 'aksharamukha' Errorfrom js import window, document
from pyodide.ffi import to_js, create_proxy
import os
print(os.listdir())
print(os.listdir('./pyscript'))
from aksharamukha import transliterate
def handler(e):
fromTxt = document.getElementById('hi').value
translated = transliterate.process('hindi', 'kannada', fromTxt, param="lang_name")
# translated = "HI"
print(fromTxt, translated)
window.show(fromTxt, translated, [])
document.getElementById('transliterate').addEventListener('click', create_proxy(handler))import os
print(os.listdir())
print(os.listdir('./pyscript'))
gives ```['pyscript']
['html.py', '__init.py', '_plugin.py', '_mime.py', '_deprecated_globals.py', '_event_loop.py', '_internal.py', '_event_handling.py']```
meaning noting is getting loaded into browser's python env even though I am getting log of these files loading, am I setting this incorrectly?
@when('click', "#transliterate") now everything is working, surprisingly even importing create_proxy is working, I guess I was importing it from a wrong place before, sorry for confusion.








interpreters that allows you to specify a Pyodide version https://github.com/pyscript/pyscript/blob/2023.05.1/docs/reference/elements/py-config.md#interpreter

interpreters that allows you to specify a Pyodide version https://github.com/pyscript/pyscript/blob/2023.05.1/docs/reference/elements/py-config.md#interpreter 


from pyscript import window
def hello(name):
print(f"Hello {name}")
window.helloInJS = hello
<script>
helloInJs("Rust-Ninja-Sabi")
</script>

from pyscript import window
def hello(name):
print(f"Hello {name}")
window.helloInJS = hello
<script>
helloInJs("Rust-Ninja-Sabi")
</script> 

from pyscript import window
def hello(name):
print(f"Hello {name}")
window.helloInJS = hello
<script>
helloInJs("Rust-Ninja-Sabi")
</script> 

2023.09.1.RC2 (the current release candidate), the simplest thing to do is add an event listener for the py:all-done event (edited)
onInterpreterReady is currently the way to know when everything is going to be executed for that specific script or tag node, the all:done is for when all things have finished so it might be too late to the pipe, but I am not 100% sure that was the question about lifecyclepy:ready event dispatched per each <script type="py"> or <py-script> content, so that's where you want to do more before the code gets executed, if that makes sense. (edited)
plugins.js:3
GET http://localhost:8000/static/pyscript.core2023.09.1.RC2/error-e4fe78fd.js net::ERR_ABORTED 404 (Not Found)
error @ plugins.js:3
(anonymous) @ config.js:117
login/:1
Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/pyscript.core2023.09.1.RC2/error-e4fe78fd.js
core.js:223
Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/pyscript.core2023.09.1.RC2/error-e4fe78fd.js
await (async)
(anonymous) @ custom.js:151
Promise.then (async)
zt @ custom.js:83
Vt @ custom.js:232
(anonymous) @ core.js:129
Show 3 more frames
Show less (edited)


dist folder where anything that can be lazy loaded will be lazy loaded. To fully have PyScript offline you need to fork the project and point at that dist folder. However, maybe for simplicity sake, we could also publish, together with the npm module a pyscript.zip file that contains the dist folder. @Jeff Glass @ntoll @antocuni anything against that? It's just another artifact to land at build time ... and it could also be just dist.zip for simplicity sake.


dist folder where anything that can be lazy loaded will be lazy loaded. To fully have PyScript offline you need to fork the project and point at that dist folder. However, maybe for simplicity sake, we could also publish, together with the npm module a pyscript.zip file that contains the dist folder. @Jeff Glass @ntoll @antocuni anything against that? It's just another artifact to land at build time ... and it could also be just dist.zip for simplicity sake. 


cryptography is listed among the officially supported pyodide packages, so it should just work out of the box: https://pyodide.org/en/stable/usage/packages-in-pyodide.html

cryptography is listed among the officially supported pyodide packages, so it should just work out of the box: https://pyodide.org/en/stable/usage/packages-in-pyodide.html 











from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
# 1. Generate private key.
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
# 2. Generate public key from the private key
public_key = private_key.public_key()
# 3. Serialize the public key into session data so as to be able to access it in template file.
self.request.session["loginPublicKey"] = public_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
).decode()<script type="py" src="encryption.py" config="pyscript.json"></script>
<py-script>
def on_click_of_submit_button(event):
public_key = {{request.session.loginPublicKey|safe}}
encrypt(public_key)
</py-script>encrypt(public_key) function being defined in encryption.py as follows:
from pyscript import document
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import base64
def encrypt(public_key):
# 1. Get the plain-text password.
plainTextPassword = document.querySelector("#id_password").value
# 2. Deserialize the public key into cyrptography library's public_key object
public_key_object = serialization.load_pem_public_key(public_key.encode())
# 3. Encrypt the plain-text password using the deserialized public key.
encryptedPasswordInBytes = public_key_object.encrypt(
plainTextPassword,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 4. Change the encrypted password's byte-encoding to base 64 so as to be able to serialize it into UTF-8 text.
encryptedPasswordInUTF8Text = base64.b64encode(encryptedPasswordInBytes).decode('utf-8')
document.querySelector("#id_password").value = encryptedPasswordInUTF8Textself.request.session["loginPublicKey"] is of the form:
'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6xFbS2+0frRUFoFYGXla\nfONlN+3vvGtoyQN/h/uxgIo2HJnlJ4dlRhRgyN8FBUPADgeKz7rApaezeVnHAkRG\nYt6A2GgWGfqqWNLwobGadvTcxGx9kgOiur0+6MKvIUahfy3E+FkMb/2hCtHNKoIf\nm3fV1hLIxqUkf8B6GsuAi3oMBfD8M6wMPiKM4bds2mM/Pb8jnvnNI+tolmO+GjwO\nuhEOy+gBt/Of7L5t2AmVFRh1ZmVTKz3xC3oNlvsF6oFsiiDcPRWwK4HZGZ84Kyha\n4Pk95+3Oq5pMhzGLyvWB7JrAiO97udL43YiELsVrcc6pXKc2R3sGIcGzJl/3319H\nswIDAQAB\n-----END PUBLIC KEY-----\n'<py-script>
public_key = -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyAWBZHwC33EBnhY0GHM9
TEwflddhf3ZQIx8uF0uB95ihkegXSBsqorKp11MzPZqVAYS8ByHAV7TF6lH5i6FH
ACZOHjxsJcWfNmwk5RHyOxFBc8JmcHjY8uLsw/en6r3FeAzES8tZhyahWSVLK2wn
WBA3b6gCPDXVqcU6mO3LEur2aAbZY8nsdFr9PmKW5D3PchaFWCCKJZQzZ8ozUdIl
vAnkVZt123UzVcLAEk2XYwbuns+Bz67CTdDKFUPd6b5bGG1xI/CfgFgMJB8HNVrN
+T8qpLptk3EP2yHCGpuMh51d4Zk6/HTG8UExS98bUMEhrmVrb3YKeg68eDTQXmHw
xQIDAQAB
-----END PUBLIC KEY-----
</py-script> (edited)error.js:15 PythonError: Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 491, in eval_code
CodeRunner(
File "/lib/python311.zip/_pyodide/_base.py", line 268, in __init__
self.ast = next(self._gen)
^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 145, in _parse_and_compile_gen
mod = compile(source, filename, mode, flags | ast.PyCF_ONLY_AST)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 2
public_key = -----BEGIN PUBLIC KEY-----
^^^^^^
SyntaxError: invalid syntax (at pyodide.asm.js:9:12519)
at new_error (pyodide.asm.js:9:12519)
at pyodide.asm.wasm:0x158827
at pyodide.asm.wasm:0x15892c
at Module._pythonexc2js (pyodide.asm.js:9:640895)
at Module.callPyObjectKwargs (pyodide.asm.js:9:81856)
at Proxy.callKwargs (pyodide.asm.js:9:97507)
at Object.runPython (pyodide.asm.js:9:118859)
at Object.it [as run] (_python.js:12:28)
at a.<computed> [as run] (custom.js:110:51)
at HTMLElement.connectedCallback (core.js:259:17)
e.onInterpreterReady.add.t.io.stderr @ error.js:15
it @ _python.js:15
a.<computed> @ custom.js:110
connectedCallback @ core.js:259
await in connectedCallback (async)
(anonymous) @ core.js:266
Show 2 more frames
Show less (edited)
{% autoescape off %}
<py-script>
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
</py-script>
{% endautoescape %}
Although the output didn't change (it still doesn't show the newline (\n) characters, but all the errors on page load are gone. (edited)

<py-script>
public_key = -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyAWBZHwC33EBnhY0GHM9
TEwflddhf3ZQIx8uF0uB95ihkegXSBsqorKp11MzPZqVAYS8ByHAV7TF6lH5i6FH
ACZOHjxsJcWfNmwk5RHyOxFBc8JmcHjY8uLsw/en6r3FeAzES8tZhyahWSVLK2wn
WBA3b6gCPDXVqcU6mO3LEur2aAbZY8nsdFr9PmKW5D3PchaFWCCKJZQzZ8ozUdIl
vAnkVZt123UzVcLAEk2XYwbuns+Bz67CTdDKFUPd6b5bGG1xI/CfgFgMJB8HNVrN
+T8qpLptk3EP2yHCGpuMh51d4Zk6/HTG8UExS98bUMEhrmVrb3YKeg68eDTQXmHw
xQIDAQAB
-----END PUBLIC KEY-----
</py-script> (edited)<py-script> or, even better, <script type="py"> ... the "even better" is that <script> never suffers from DOM parsing, while custom elements do.

{% autoescape off %}
<py-script>
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
</py-script>
{% endautoescape %}
Although the output didn't change (it still doesn't show the newline (\n) characters, but all the errors on page load are gone. (edited)<script type="py"> instead?

<script type="py"> instead? 
<script type="py">
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
</script>
{% autoescape off %}
<script type="py">
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
<script type="py">
{% endautoescape %}


{% autoescape off %}
<script type="py">
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
<script type="py">
{% endautoescape %} 


<script type="py">
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
</script> 

error.js:15 PythonError: Traceback (most recent call last):
File "<exec>", line 3, in on_click_of_submit_button
NameError: name 'encrypt' is not defined
at new_error (pyodide.asm.js:9:12519)
at pyodide.asm.wasm:0x158827
at pyodide.asm.wasm:0x15892c
at Module._pythonexc2js (pyodide.asm.js:9:640895)
at Module.callPyObjectKwargs (pyodide.asm.js:9:81856)
at Module.callPyObject (pyodide.asm.js:9:82066)
at Proxy.call (pyodide.asm.js:9:97213)
at Object.ct [as runEvent] (_python.js:36:22)
at HTMLInputElement.Dt (listeners.js:42:17)
e.onInterpreterReady.add.t.io.stderr @ error.js:15
ct @ _python.js:39
Dt @ listeners.js:42
Show 2 more frames
Show less

<script type="py">
def on_click_of_submit_button(event):
encrypt("""-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsgN0/gotEGvYkgKK2LNw
Zas+ys9P86JNfE0T2iqjpllzLYc0e0VKZdlS9vTHvdkSlEw5uP5VAHAPLryWvVws
zch74NfSNBjd25IJNnAcMXZhwTnFGajN1qVwWczC3EoCaoKsrRog+pkHmPxZ2o4M
7jp74kLuL5x90aGfAIFGOc+Cu+2oRoaUqnU8u2bYMv9oPxa9GcMVUkX+81H/T0xm
nwKeutfI85ZcsCIr8Ghn1MCxEPrLtamZxeay/BFdHvs8pnLp07B10J6FOEsQ146S
OBa1GpyOWlw3dKC2YaAMC4lIIosBX4h5MZV+ITRhdnuTbwPoP1b8RzNlVu7W9udL
VQIDAQAB
-----END PUBLIC KEY-----
""")
</script>
encrypt come from?NameError: name 'encrypt' is not defined
encrypt() is there in encryption.py
<script type="py" src="encryption.py" config="pyscript.json"></script>
encryption.py in the py-config as file to fetch, then in the page you need to from encryption import encrypt then you should be good when you invoke that

encrypt function (or if it does, it's not the suggested approach here) (edited)<script type="py" src="encryption.py" config="pyscript.json"></script>encrypt from it, then you should be OK

encrypt from it, then you should be OK 
encrypt from encryption.py file ... you don't want to execute 2 script type py, you want a single script with a config that also brings in the encryption.py file in the filesystem so you can import encrypt from it.

pyscript.json you need to add a fetch that points at encryption.py so you can then from encryption import encrypt and call it a day ... so that encrypt is available.

<script type="py" config="pyscript.json">
from encryption import encrypt
def on_click_of_submit_button(event):
encrypt("""{{request.session.loginPublicKey|safe}}""")
</script> (edited)"fetch": ["./encryption.py"] in the pyscript.json config (edited)




pyscript.json:
{
"packages": ["cryptography"],
// "files": {
// // "AdminApp/static/AdminApp/py/encryption.py" : "encryption.py"
// }
"fetch" : [ "AdminApp/static/AdminApp/py/encryption.py" ]
} (edited)
error.js:15 PythonError: Traceback (most recent call last):
File "<exec>", line 4, in on_click_of_submit_button
File "/home/pyodide/encryption.py", line 14, in encrypt
encryptedPasswordInBytes = public_key_object.encrypt(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.11/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 539, in encrypt
return _enc_dec_rsa(self._backend, self, plaintext, padding)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.11/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 95, in _enc_dec_rsa
return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.11/site-packages/cryptography/hazmat/backends/openssl/rsa.py", line 157, in _enc_dec_rsa_pkey_ctx
res = crypt(pkey_ctx, buf, outlen, data, len(data))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: initializer for ctype 'unsigned char *' must be a bytes or list or tuple, not str
at new_error (pyodide.asm.js:9:12519)
at pyodide.asm.wasm:0x158827
at pyodide.asm.wasm:0x15892c
at Module._pythonexc2js (pyodide.asm.js:9:640895)
at Module.callPyObjectKwargs (pyodide.asm.js:9:81856)
at Module.callPyObject (pyodide.asm.js:9:82066)
at Proxy.call (pyodide.asm.js:9:97213)
at Object.ct [as runEvent] (_python.js:36:22)
at HTMLInputElement.Dt (listeners.js:42:17)




TypeError: initializer for ctype 'unsigned char *' must be a bytes or list or tuple, not str
<script type="py" config="/static/InfrastructureApp/pyscript.core2023.09.1.RC2/pyscript.json"></script>
<script type="py">
from encryption import encrypt
def on_click_of_submit_button(event):
encrypt("""-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsAD64DBNQdk5ZNlfI0cf
SV6fMs5t2/Oq7kXuFrIh/UZqVhLbt5f6MIznQWJiqkipQaV7DItzsSa3oz0E6EQ1
m7Ds+1W2emjJUwq+Nc9jWhojlMEtvb7fm5MY13uUriiDdLjkptQJuO5O6/1jtBEY
n5eeqH+jIBnTM8B6bCCoQop4PTLWgjoz/n1y3HVPqMIVH+kf3DZeUzFAFv3wxeTQ
UApdJ08Mvairmys1k5YS5vtuLGSU7buV6IuU8uM8YXNpViGuXCeaSQkYaEsvx/4d
GbBOFsJQaIQgc5sBYwvFeCSPw2ncEEPsUI4masii+eFA8vs89nSU9AHIk3sutsqr
EwIDAQAB
-----END PUBLIC KEY-----
""")
</script>
TypeError: initializer for ctype 'unsigned char *' must be a bytes or list or tuple, not str

-----END PUBLIC KEY-----
""""\n" manually though, if that's your concern, but the error is clearly about you passing a string, the new line eventually comes after as issue
<script type="py" config="pyscript.json"></script>
<script type="py">
from encryption import encrypt
def on_click_of_submit_button(event):
public_key = """{{request.session.loginPublicKey|safe}}"""
encrypt(public_key)
</script>encryption.py, I have:
from pyscript import document
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import base64
def encrypt(public_key):
# 1. Get the plain-text password.
plainTextPassword = document.querySelector("#id_password").value
# 2. Deserialize the public key into cyrptography library's public_key object
public_key_object = serialization.load_pem_public_key(public_key.encode())
# 3. Encrypt the plain-text password using the deserialized public key.
encryptedPasswordInBytes = public_key_object.encrypt(
plainTextPassword,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
# 4. Change the encrypted password's byte-encoding to base 64 so as to be able to serialize it into UTF-8 text.
encryptedPasswordInUTF8Text = base64.b64encode(encryptedPasswordInBytes).decode('utf-8')
document.querySelector("#id_password").value = encryptedPasswordInUTF8Text
bytes(string, 'utf-8') or something, I am also out for today ... btw, it's:
<script type="py" config="pyscript.json">
from encryption import encrypt
def on_click_of_submit_button(event):
public_key = """{{request.session.loginPublicKey|safe}}"""
encrypt(public_key)
</script>
the cases you want or need two pyscript tags on the same page are really close to zero ... this is not one of themencrypt(bytes(public_key)) changes anything in therepublic_key_object = serialization.load_pem_public_key(public_key.encode())

bytes(string, 'utf-8') or something, I am also out for today ... btw, it's:
<script type="py" config="pyscript.json">
from encryption import encrypt
def on_click_of_submit_button(event):
public_key = """{{request.session.loginPublicKey|safe}}"""
encrypt(public_key)
</script>
the cases you want or need two pyscript tags on the same page are really close to zero ... this is not one of them <script type="py" config="pyscript.json">
from encryption import encrypt
def on_click_of_submit_button(event):
public_key = """{{request.session.loginPublicKey|safe}}"""
encrypt(public_key)
</script>
plainTextPassword as first argument ... then again, I am closing for today, maybe others can help ... I don't know this API, sorry.





packages = ["matplotlib", "scipy",]
name = "Matplotlib"
as my pyconfig and I'm using latest pyscript (I believe)

<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
/latest uses Pyodide 0.23.2, which pins Matplotlib 3.5.2. Is it possible the get_corners function was introduced in a newer version?

interpreters that allows you to specify a Pyodide version https://github.com/pyscript/pyscript/blob/2023.05.1/docs/reference/elements/py-config.md#interpreter


pyscript.interpreter.runPythonAsync(code) to run some code on demand, is that still valid in NEXT?
My existing code doesn't work and I am wondering if pyscript is still available in the window or if I have to do something else to access it. (edited)

pyscript.interpreter.runPythonAsync(code) to run some code on demand, is that still valid in NEXT?
My existing code doesn't work and I am wondering if pyscript is still available in the window or if I have to do something else to access it. (edited)onInterpreterReady. Sorry Iโm on mobile and canโt prep a demo, but check out the PolyScript documentation on Hooks for some pointers

onInterpreterReady. Sorry Iโm on mobile and canโt prep a demo, but check out the PolyScript documentation on Hooks for some pointers 
Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "<exec>", line 3, in <module>
File "/lib/python3.10/site-packages/panel/__init__.py", line 48, in <module>
from . import layout # noqa
File "/lib/python3.10/site-packages/panel/layout/__init__.py", line 31, in <module>
from .accordion import Accordion # noqa
File "/lib/python3.10/site-packages/panel/layout/accordion.py", line 5, in <module>
from .base import NamedListPanel
File "/lib/python3.10/site-packages/panel/layout/base.py", line 13, in <module>
from ..reactive import Reactive
File "/lib/python3.10/site-packages/panel/reactive.py", line 33, in <module>
from .viewable import Layoutable, Renderable, Viewable
File "/lib/python3.10/site-packages/panel/viewable.py", line 25, in <module>
from .config import config, panel_extension
File "/lib/python3.10/site-packages/panel/config.py", line 417, in <module>
config = _config(**{k: None if p.allow_None else getattr(_config, k)
File "/lib/python3.10/site-packages/panel/config.py", line 216, in __init__
super().__init__(**params)
File "/lib/python3.10/site-packages/param/parameterized.py", line 4139, in __init__
if not isinstance(self._param__private, _InstancePrivate):
File "/lib/python3.10/site-packages/panel/config.py", line 289, in __getattribute__
init = super().__getattribute__('initialized')
AttributeError: '_config' object has no attribute 'initialized'
Did pyscript receive an update lately that couldve broke panel ?

Traceback (most recent call last):
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 435, in eval_code
.run(globals, locals)
File "/lib/python3.10/site-packages/_pyodide/_base.py", line 304, in run
coroutine = eval(self.code, globals, locals)
File "<exec>", line 3, in <module>
File "/lib/python3.10/site-packages/panel/__init__.py", line 48, in <module>
from . import layout # noqa
File "/lib/python3.10/site-packages/panel/layout/__init__.py", line 31, in <module>
from .accordion import Accordion # noqa
File "/lib/python3.10/site-packages/panel/layout/accordion.py", line 5, in <module>
from .base import NamedListPanel
File "/lib/python3.10/site-packages/panel/layout/base.py", line 13, in <module>
from ..reactive import Reactive
File "/lib/python3.10/site-packages/panel/reactive.py", line 33, in <module>
from .viewable import Layoutable, Renderable, Viewable
File "/lib/python3.10/site-packages/panel/viewable.py", line 25, in <module>
from .config import config, panel_extension
File "/lib/python3.10/site-packages/panel/config.py", line 417, in <module>
config = _config(**{k: None if p.allow_None else getattr(_config, k)
File "/lib/python3.10/site-packages/panel/config.py", line 216, in __init__
super().__init__(**params)
File "/lib/python3.10/site-packages/param/parameterized.py", line 4139, in __init__
if not isinstance(self._param__private, _InstancePrivate):
File "/lib/python3.10/site-packages/panel/config.py", line 289, in __getattribute__
init = super().__getattribute__('initialized')
AttributeError: '_config' object has no attribute 'initialized'
Did pyscript receive an update lately that couldve broke panel ? 



<script
defer
src="https://pyscript.net/releases/2022.12.1/pyscript.js"
></script>
panel is using 0.13

<script
defer
src="https://pyscript.net/releases/2022.12.1/pyscript.js"
></script>
panel is using 0.13 




<py-config type="toml">
packages = ["numpy", "pandas", "panel==0.13.1a2", "activejson", "./crcmod-1.7-py3-none-any.whl", "ndspy", "more_itertools", "ordered_set"]
terminal = false
[[fetch]]
files = ["./randomizer_py.zip"]
</py-config>
v0.21.3 there ... have you looked for issues with your specific library? ./crcmod-1.7-py3-none-any.whl doens't fully help here neither, sorry.panel==0.13.1a2 should guarantee at least that bit is sealed in time

0 might mean breaking changes




<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<py-config>
packages=['panel==0.13.1a2']
</py-config>
<py-script>
import panel
</py-script>





param had a 2.0.0 release yesterday... that seems suspicious, given that the error message mentioned param/pameterized.py...

param had a 2.0.0 release yesterday... that seems suspicious, given that the error message mentioned param/pameterized.py... 

<script type="py" config="{% static 'InfrastructureApp/pyscript.core2023.09.1.RC2/pyscript.json' %}">
from pyscript import document
from encryption import encrypt
def on_click_of_submit_button(event):
if (document.getElementById('id_username').value.strip() != "") and (document.getElementById('id_password').value.strip() != ""):
public_key = """{{request.session.loginPublicKey|safe}}"""
encrypt(public_key)
return True
else:
return False
</script>
The intent is that:
false from the function.
else:
event.preventDefault()event ... you can omit the return True or return False entirely.
encryption.py with the following two functions:
def formValidation():
pass
def encrypt(public_key):
pass{
"files": {
"{DOMAIN}": "http://localhost:8000",
"{DOMAIN}/static/py/encryption.py" : "./encryption.py"
},
"packages": ["cryptography"]
}<script type="py" config="pyscript.json">
from pyscript import document, window
from encryption import formValidation, encrypt
</script>PythonError: Traceback (most recent call last):
File "/lib/python311.zip/_pyodide/_base.py", line 499, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 340, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 3, in <module>
ImportError: cannot import name 'formValidation' from 'encryption' (/home/pyodide/encryption.py) (edited)encryption.py, if I change my pyscript script to only import the encrypt function, everythin works fine.pass statements.<script type="py" config="pyscript.json">
from pyscript import document, window
from encryption import formValidation
from encryption import encrypt
</script>

encryption.py, but your changes in the second version busted the cache and caused things to work. Just a guess



File > Open in a web browser, using a local dev server... ?

File > Open in a web browser, using a local dev server... ? 



encryption.py in different lines to be able to work on other stuff.

encryption.py in different lines to be able to work on other stuff. 


encryption.py, do all three have to be imported on separate lines? (edited)
from encryption import formValidation, encrypt, thirdfunction
doesn't break.from encryption import formValidation, encrypt doesn't break either. 




passwordInputElement = document.getElementById('id_password')
When the HTML doesn't have any id_password field, javascript returns a null. In case of pyscript, passwordInputElement would be None?if passwordInputElement is None, right?

if passwordInputElement is None, right? if not passwordInputElement should work too
def tst():
js.alert('I work')
persistent_fct = js.create_proxy(tst)
my_image = grab_element_by_id("test_image")
my_image.addEventListener('click', persistent_fct) I imported (all) js and grab_element_by_id() is just a custom made, a bit fancier function on top of the js.document.querySelector, that returns the selected tag object. However I am getting this traceback: AttributeError: create_proxy. Is there another built in function I should be using to create a persistent proxy? (edited)
create_proxy isn't a JS function, it's something that Pyodide adds on the Python side. You'll want to add from pyodide.ffi import create_proxyimport js
from pyodide.ffi.wrappers import add_event_listener
def tst():
js.alert('I work')
my_image = grab_element_by_id("test_image")
add_event_listener(my_image, 'click', tst)

create_proxy isn't a JS function, it's something that Pyodide adds on the Python side. You'll want to add from pyodide.ffi import create_proxy 

add_event_listener is a thin wrapper around JS's add_event_listener and does the proxy management for you

add_event_listener is a thin wrapper around JS's add_event_listener and does the proxy management for you 

import js
from pyodide.ffi.wrappers import add_event_listener
def tst():
js.alert('I work')
my_image = grab_element_by_id("test_image")
add_event_listener(my_image, 'click', tst) 


hooks.worker.onReady hook?

hooks.worker.onReady hook? window property:
<p id="foo">Hello!</p>
<script type="module">
import { config, hooks } from "https://pyscript.net/unstable/core.js"
hooks.worker.onReady.add((wrap, xw) => {
const p = xw.window.document.getElementById("foo")
console.log("Content is: ", p.textContent)
})
</script>
<script type="py" worker>
# Just a tag to make the above hook run
</script>









enum is in the python standard lib, and does not need to be included in packages


alert pop-up area?

dist folder where anything that can be lazy loaded will be lazy loaded. To fully have PyScript offline you need to fork the project and point at that dist folder. However, maybe for simplicity sake, we could also publish, together with the npm module a pyscript.zip file that contains the dist folder. @Jeff Glass @ntoll @antocuni anything against that? It's just another artifact to land at build time ... and it could also be just dist.zip for simplicity sake. 

dist.zip folder with all files in there ... however, you are in charge of downloading your own pyodide and use that as interpreter in the py-config


dist.zip.
I did the following:
npm i @pyscript/core on local windows terminalC:\Users\username\node_modules\@pyscript\core\dist folder



enum is in the python standard lib, and does not need to be included in packages 





<form id="my_form" method="post">
{% csrf_token %}
<input id="my_data_field" type="text" name="my_field">
<input type="submit">
</form>
<p id="my_answer_p">No data</p>
<script>
document.getElementById("my_form").addEventListener("submit", function(event) {
event.preventDefault();
var my_data_in_field = document.getElementById("my_data_field").value;
const formData = {'my_field': my_data_in_field};
fetch('{% url "quest_populate_log" %}', {
method: 'POST',
body: JSON.stringify(formData),
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRFToken': getCookie('csrftoken')
}
})
.then(response => response.json())
.then(data => {
document.getElementById("my_answer_p").innerText = data.answer;
})
.catch(error => console.error('Error:', error));
});
function getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length === 2) return parts.pop().split(";").shift();
} (edited)



pyodide.http.pyfetch - itโs a pretty thin wrapper around fetch, with a slightly more pythonic API https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.pyfetchawait js Thenables directly in pyscript - see the section on calling Js functions in Python https://pyodide.org/en/stable/usage/type-conversions.html#calling-javascript-functions-from-python

core.js definitely has them. Just need a CTRL+F cdn.jsdelivr.

script.py in my root folder that I want to import in my main.py inside a subdirectory where the Pyscript files are stored.
.
โโโ script.py
โโโ demo-website
โโโ index.html
โโโ main.js
โโโ main.py
โโโ pyscript.toml
In my main.py I import as follows
from script import ...
Assuming the web server runs from the directory demo-website/, is it possible to import script.py?pyscript.toml like this:
[[fetch]]
files = ["../script.py"]
to_folder = "project"
and when I ran the web server from the root dir, it works. But I'm hoping to deploy this to GitHub Pages where it runs the webserver from demo-website/ instead because that's where index.html is stored. But like earlier, it doesn't work. Any ideas?

pyscript.toml like this:
[[fetch]]
files = ["../script.py"]
to_folder = "project"
and when I ran the web server from the root dir, it works. But I'm hoping to deploy this to GitHub Pages where it runs the webserver from demo-website/ instead because that's where index.html is stored. But like earlier, it doesn't work. Any ideas? {
"files": {
"https://domain.com/directory/script.py" : "./script.py"
}
} (edited)

core.js definitely has them. Just need a CTRL+F cdn.jsdelivr. interpreter to point at those ... the only foreign dependency is the lazy toml parser but has also been moved in the dist recently and XTerm will do the same unless we make that lazy dist import too ... which we could.

interpreter to point at those ... the only foreign dependency is the lazy toml parser but has also been moved in the dist recently and XTerm will do the same unless we make that lazy dist import too ... which we could. interpreter option in the user guid here (https://docs.pyscript.net/2023.09.1.RC1/user-guide).
Are you referring to <script type = "mpy"...> and <script type = "py"...> ?

interpreter option in the user guid here (https://docs.pyscript.net/2023.09.1.RC1/user-guide).
Are you referring to <script type = "mpy"...> and <script type = "py"...> ? 

{Project_Root_Directory}/InfrastructureApp/static/InfrastructureApp/pyodide_full_0.24.1/
Then, I wrote my JSON as follows:
{
"interpreter": "http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs",
"files": {
"{DOMAIN}": "http://localhost:8000",
"{DOMAIN}/static/ADSSAdminApp/py/encryption.py" : "./encryption.py"
},
"packages": ["cryptography"]
}
Now, when I load my homepage (http://localhost:8000), Chrome's Dev Tools show these errors:
pyodide.mjs:1 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec.
login/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs
login/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs
However, when I right-click --> "Open in new tab" to that link related to pyodide.mjs, it does load that javascript file. (edited)

pyodide.http.pyfetch - itโs a pretty thin wrapper around fetch, with a slightly more pythonic API https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.pyfetch 
pyodide.mjs got a 200 OK.

{Project_Root_Directory}/InfrastructureApp/static/InfrastructureApp/pyodide_full_0.24.1/
Then, I wrote my JSON as follows:
{
"interpreter": "http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs",
"files": {
"{DOMAIN}": "http://localhost:8000",
"{DOMAIN}/static/ADSSAdminApp/py/encryption.py" : "./encryption.py"
},
"packages": ["cryptography"]
}
Now, when I load my homepage (http://localhost:8000), Chrome's Dev Tools show these errors:
pyodide.mjs:1 Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/plain". Strict MIME type checking is enforced for module scripts per HTML spec.
login/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs
login/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:8000/static/InfrastructureApp/pyodide_full_0.24.1/pyodide.mjs
However, when I right-click --> "Open in new tab" to that link related to pyodide.mjs, it does load that javascript file. (edited)


Strict MIME type checking is enforced for module scripts per HTML spec.
so either you are not running your server in localhost:8000 or your Django version doesn't understand .mjs file extension as application/javascript which is required ... I've raised this concern ages ago when they proposed this extension and here we are with the issue I've raised myself. you can rename that file to .js instead and see if that works, overwriting eventually the other .js file if present, as it'll be useless.

Strict MIME type checking is enforced for module scripts per HTML spec.
so either you are not running your server in localhost:8000 or your Django version doesn't understand .mjs file extension as application/javascript which is required ... I've raised this concern ages ago when they proposed this extension and here we are with the issue I've raised myself. you can rename that file to .js instead and see if that works, overwriting eventually the other .js file if present, as it'll be useless. pyodide.js. Lemme try with that.pyodide.js:17 Uncaught (in promise) TypeError: e is not a function
at Object.engine (pyodide.js:17:13)
at interpreters.js:41:24
engine @ pyodide.js:17
(anonymous) @ interpreters.js:41
Promise.then (async)
sn @ custom.js:83
define @ custom.js:234
(anonymous) @ core.js:259
Promise.then (async)
(anonymous) @ core.js:129
Show 4 more frames
Show less
pyodide.js:17 Uncaught (in promise) TypeError: e is not a function
at Object.engine (pyodide.js:17:13)
at interpreters.js:41:24
engine @ pyodide.js:17
(anonymous) @ interpreters.js:41
Promise.then (async)
Qt @ listeners.js:66
define @ custom.js:233
(anonymous) @ core.js:259
Promise.then (async)
(anonymous) @ core.js:129
Show 4 more frames
Show less

pyodide.js:17 Uncaught (in promise) TypeError: e is not a function
at Object.engine (pyodide.js:17:13)
at interpreters.js:41:24
engine @ pyodide.js:17
(anonymous) @ interpreters.js:41
Promise.then (async)
sn @ custom.js:83
define @ custom.js:234
(anonymous) @ core.js:259
Promise.then (async)
(anonymous) @ core.js:129
Show 4 more frames
Show less
pyodide.js:17 Uncaught (in promise) TypeError: e is not a function
at Object.engine (pyodide.js:17:13)
at interpreters.js:41:24
engine @ pyodide.js:17
(anonymous) @ interpreters.js:41
Promise.then (async)
Qt @ listeners.js:66
define @ custom.js:233
(anonymous) @ core.js:259
Promise.then (async)
(anonymous) @ core.js:129
Show 4 more frames
Show less .mjs into .js instead.

.mjs is standard IANA matter https://datatracker.ietf.org/doc/rfc9239/.mjs files are pretty common these days, even if nobody technically needs these on the Web (and ultimately in NodeJS neither).
application/javascript MIME-type instead of being served with text/plainMIME-type, right? (edited)

application/javascript MIME-type instead of being served with text/plainMIME-type, right? (edited).js and .mjs identically.mjs is surely used in the wild a lot but it cannot be served as text/plain because that's not standard so browsers complain (edited)
application/javascript or as text/plain?
Published specification: [ECMA-262]
Applications that use this media type: Script interpreters as
discussed in RFC 9239.
Additional information:
Deprecated alias names for this type: application/javascript,
application/x-javascript, text/javascript1.0, text/
javascript1.1, text/javascript1.2, text/javascript1.3, text/
javascript1.4, text/javascript1.5, text/jscript, text/
livescript
Magic number(s): N/A
File extension(s): .js, .mjs
Macintosh File Type Code(s): TEXT
text/javascript the correct one ... but again, whatever Django does for .js should be the same for .mjs




.mjs is a standard extension that should be served as text/javascript. All servers do that. The whole Web does that. If your Django or Django doesn't do that it's a Django problem, not a PyScript one. Have you fixed your issue? We have an RC to release soon and I can't really help further here, sorry.

.mjs is a standard extension that should be served as text/javascript. All servers do that. The whole Web does that. If your Django or Django doesn't do that it's a Django problem, not a PyScript one. Have you fixed your issue? We have an RC to release soon and I can't really help further here, sorry. settings.py:
import mimetypes
mimetypes.add_type("text/javascript", ".mjs", True)

.mjs in its built-in mimetype module?>>> import mimetypes
>>> mimetypes.guess_type('test.mjs')
('text/javascript', None)




socket.py is because that module is specifically a minimal stub in Pyodide (PyScript's primary Python runtime). See https://pyodide.org/en/stable/usage/wasm-constraints.html#included-but-not-working-modules for other modules that fall into this category, and other limitations.
PyScript is a frontend framework for writing Python into your HTML/page. For the backend, you'd be better off with simply Python, in some form.

socket.py is because that module is specifically a minimal stub in Pyodide (PyScript's primary Python runtime). See https://pyodide.org/en/stable/usage/wasm-constraints.html#included-but-not-working-modules for other modules that fall into this category, and other limitations.
PyScript is a frontend framework for writing Python into your HTML/page. For the backend, you'd be better off with simply Python, in some form. 


files
dir() my way through




pyscript package is laid out.
Maybe we need a "cover page" describing the layout of this package, and making users aware that they can access the Pyodide ffi as well https://pyodide.org/en/stable/usage/api/python-api.html.
Going to ping @ntoll here who's been heading up a lot of the docs, though he's out of touch until next week.




pyodide.http.open_url to open a remote page and then parse that page with beautifulsoup to obtain some links

defer in the script tag, I'm guessing you're using PyScript classic. In that case, you can grab the input element directly and read it's value:
<script defer src="https://pyscript.net/releases/2023.05.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2023.05.1/pyscript.css">
<input id="inputword" type="text" placeholder="Enter a word" >
<button py-click="handle_word()">Submit</button>
<script type="py">
import js
def handle_word():
value = js.document.getElementById("inputword").value
print(f"The value is {value}")
</script>pydom package, with is somewhat more Pythonic. Though the above syntax will still work. Note too that the py-*event syntax is a little different in this case.
Once we fix our CI and actually get the unstable package built, you can use pydom like so:
<script type="module" src="https://pyscript.net/unstable/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/unstable/core.css">
<input id="inputword" type="text" placeholder="Enter a word" >
<button py-click="handle_word">Submit</button>
<script type="py">
from pyweb import pydom
def handle_word(event):
input_el = pydom['#inputword'][0]
print(f"The value is {input_el.value}")
</script> (edited)value attribute of pydom was only added two days ago and we haven't successfully published an unstable release since then, so this will be broken for a couple days at least https://github.com/pyscript/pyscript/actions/runs/6721728371/job/18268073117


<script type="py" worker>)

<script type="py" worker>) js.document, in workers, it'd be the proxied equivalent of js.document on main













event.touches.item(0)














pyscript package is laid out.
Maybe we need a "cover page" describing the layout of this package, and making users aware that they can access the Pyodide ffi as well https://pyodide.org/en/stable/usage/api/python-api.html.
Going to ping @ntoll here who's been heading up a lot of the docs, though he's out of touch until next week. 



from pyscript import window. Window, in this case, is the JavaScript global namespace in the main window. You can assign objects to it, and they will be accessible in JavaScript.

df.to_json() go from there. you can either inspect the result of runPythonAsync, or do ython -> js call
I personally prefer runPythonAsync, but you'll need to hook into one of the polyscript hooks like main.onReady such as this
i also built the exact same thing so feel free to ask any questions (edited)












pyscript.__version__ Is there a way to get it now ?
from pyodide import create_proxy
enable_wallet_btn = document.querySelector('#enable-wallet-btn')
enable_wallet_btn.addEventListener('click', create_proxy(enable_nami))
if await nami.isEnabled():
enable_wallet_btn.click()
And also have await in the global scope.
Now it throws these 2 errors:
SyntaxError: 'await' outside function
ImportError: cannot import name 'create_proxy' from 'pyodide' (/lib/python311.zip/pyodide/__init__.py)
Anyone know a fix for this?
create_proxy issue, new import is from pyiodide.ffi import create_proxy
pyscript.write() been deprecated? Error in console: AttributeError: module 'pyscript' has no attribute 'write'

from pyodide import create_proxy
enable_wallet_btn = document.querySelector('#enable-wallet-btn')
enable_wallet_btn.addEventListener('click', create_proxy(enable_nami))
if await nami.isEnabled():
enable_wallet_btn.click()
And also have await in the global scope.
Now it throws these 2 errors:
SyntaxError: 'await' outside function
ImportError: cannot import name 'create_proxy' from 'pyodide' (/lib/python311.zip/pyodide/__init__.py)
Anyone know a fix for this? 



pyscript.write() been deprecated? Error in console: AttributeError: module 'pyscript' has no attribute 'write' 

pyscript.write('wait-txs', '<h4>Fetching transactions...</h4>') (edited)


pyscript.write('wait-txs', '<h4>Fetching transactions...</h4>') (edited)

pyscript.write('wait-txs', '<h4>Fetching transactions...</h4>') (edited)display() and the HTML helper:
<div id="wait-txs"></div>
<script type="py">
from pyscript import display, HTML
display(HTML("<h4> This is an h4 tag! </h4>"), target="#wait-txs")
</script>display tries to escape what you give it so it appears as written. HTML bypasses this, so you can write tags in your string)



"fetch": [{
"from": "webresources/almanac",
"to_folder": "almanacfiles",
"files": [
"__init__.py",
"Hipparcos.csv",
"finals2000A.all",
"de421.bsp",
"almanac.py"
]
}], (edited) from almanacfiles.almanac import * (edited)






<script type="module" src="https://pyscript.net/releases/2023.11.1/core.js"></script>

from pyweb import pydom
create_proxy() from pyodide.ffi?

create_proxy() from pyodide.ffi? from pyodide.ffi import create_proxy in Micropython as well.



utils.py loaded via py-config, using either [[fetch]] or [files]? Those are the two keys that allow for fetching resources from URLs and moving them into the virtual filesystem where Python can use themtodo-pylist example has this a a py-config:
<py-config>
[[fetch]]
files = ["./utils.py"]
</py-config>packages is for installing full Python packages from elsewhere - think of it as the equivalent of pip install


<!-- 2023.05.1 -->
<button py-click="foo()">Click me</button>
<py-script>
def foo():
print("HI!")
</py-script>
<!-- 2023.11.1 -->
<button py-click="foo">Click me</button>
<script type="py">
def foo(evt):
print("HI!")
</script>



main.py - they should be in your index.html document.






pydom.ids.foo when I have a <div id="foo"></div> above my script in index.html
but not working for me. Domscope defined like this:
class DomScope:
def __getattr__(self, __name: str) -> Any:
element = document[f"#{__name}"]
if element:
return element[0]`
Tried interrogating pydom.ids directly but can't find anything. What am I misunderstanding ?
RuntimeError: index out of bounds for a Python module with over a thousand lines and believe it's this issue: https://github.com/micropython/micropython-esp32/issues/205
I tried print(1) at the top and it didn't work. Can we configure MicroPython to allow more memory for compilation? Does mpy-cross work for PyScript/WebAssembly? Is this the right fork/branch to start from? https://github.com/dpgeorge/micropython/tree/webassembly-add-modjs


RuntimeError: index out of bounds for a Python module with over a thousand lines and believe it's this issue: https://github.com/micropython/micropython-esp32/issues/205
I tried print(1) at the top and it didn't work. Can we configure MicroPython to allow more memory for compilation? Does mpy-cross work for PyScript/WebAssembly? Is this the right fork/branch to start from? https://github.com/dpgeorge/micropython/tree/webassembly-add-modjs 















mpy_change). But this means that the default value is encoded both in the HTML (as the radio button with the checked attribute), and in the Python (as the default value of favourite_song_id). I usually try to avoid repetition like this (https://en.wikipedia.org/wiki/Don't_repeat_yourself).announce_favourite (called when the button is pressed) that reads the current state of the radio buttons, but couldn't quickly work out how to do this. I see various approaches at https://stackoverflow.com/questions/9618504/how-to-get-the-selected-radio-button-s-value, but I don't know how best to do this in PyScript. Ideally, I'd prefer something Pythonic, because that's the language my son is studying.

announce_favourite (called when the button is pressed) that reads the current state of the radio buttons, but couldn't quickly work out how to do this. I see various approaches at https://stackoverflow.com/questions/9618504/how-to-get-the-selected-radio-button-s-value, but I don't know how best to do this in PyScript. Ideally, I'd prefer something Pythonic, because that's the language my son is studying. def announce_favourite(event):
#Find the first radio button with type "radio" that is checked:
selected = document.querySelector('input[type="radio"]:checked')
favourite_song_id = selected.id
announce_text = f"Oh yes I really like {favourite_song_id} \u2764\uFE0F\n"
outputElement.innerText += announce_textsong_radio_change function entirely


time_ns-based methods currenly are.['sleep', 'sleep_ms', 'sleep_us', 'ticks_add', 'ticks_cpu', 'ticks_diff', 'ticks_ms', 'ticks_us'] (edited)









<py-config> packages key: https://docs.pyscript.net/2023.11.1/user-guide/configuration/#packages
Almost all of the standard library is usable, with some notable exceptions due to the restrictions that the browser has around networking (i.e. you can't open a raw socket) and UI access (i.e. turtle/tkinter try to grab low-level windowing optoins which aren't available in the browser.) For more on the standard lib, see here: https://pyodide.org/en/stable/usage/wasm-constraints.html

<py-config> packages key: https://docs.pyscript.net/2023.11.1/user-guide/configuration/#packages
Almost all of the standard library is usable, with some notable exceptions due to the restrictions that the browser has around networking (i.e. you can't open a raw socket) and UI access (i.e. turtle/tkinter try to grab low-level windowing optoins which aren't available in the browser.) For more on the standard lib, see here: https://pyodide.org/en/stable/usage/wasm-constraints.html 

input_text = document.querySelector("#english")
my question is is there a place i can see all of the stuff like querySelector, and what they're used for and all that


-none-any.whl on PyPI. The none means no particular reliance on a C ABI, and the any means any platform. You can check the published files on PyPI to see if there's a wheel like that that. (edited)packages and you get an error about "couldn't find a pure-Python wheel", it means a wheel file like that couldn't be found on PyPI

input_text = document.querySelector("#english")
my question is is there a place i can see all of the stuff like querySelector, and what they're used for and all that document.querySelector.
Earlier in that example, you'll see from pyscript import document. That 'document' is a transparent proxy for the Browser's document object https://developer.mozilla.org/en-US/docs/Web/API/Document. PyScript (and under the hood, Pyodide and Micropython+WASM) allow you to import objects directly from JavaScript and use them like normal Python objects

-none-any.whl on PyPI. The none means no particular reliance on a C ABI, and the any means any platform. You can check the published files on PyPI to see if there's a wheel like that that. (edited)

document.querySelector.
Earlier in that example, you'll see from pyscript import document. That 'document' is a transparent proxy for the Browser's document object https://developer.mozilla.org/en-US/docs/Web/API/Document. PyScript (and under the hood, Pyodide and Micropython+WASM) allow you to import objects directly from JavaScript and use them like normal Python objects output_div.innerText
when i search for innerText on the web docs page you sent it seems to be from something called HTMLElement, but i never imported this at the start, only document (edited)




def announce_favourite(event):
#Find the first radio button with type "radio" that is checked:
selected = document.querySelector('input[type="radio"]:checked')
favourite_song_id = selected.id
announce_text = f"Oh yes I really like {favourite_song_id} \u2764\uFE0F\n"
outputElement.innerText += announce_text 








event.target is the element that originally dispatched that event.
Try this:
<button py-click="foo">A Button</button>
<button py-click="foo">Another Button</button>
<script type="py">
def foo(evt):
print(f"The target's text is {evt.target.innerText}")
</script>
from pyweb import pydom
from pyscript import display, document, window, HTML, when
docbody = pydom["body"][0] # Element ('body' can be any selector)
I can create a new element:
baz = pydom.create("div", classes=["baz"])
docbody.append(baz)
I have to add an id inorder to use display or to assign using baz.content= ..id=.. option in create.baz.id = 'baz'
I want to add a pyclick="mycallback" but no options at create to do so.
I expect I have to assign the innerHTML directly or craft something using HTML(..)
What's an actual working (pyscript code) example where I can create a div or a button with a py-click event on it and maybe a css style please... (edited)

from xworker import XWorker
sync = XWorker("worker.py", config="pyscript.toml", type="micropython")
But pretty sure you don't need what's in your .toml file.. But as I say - can't work it out either.from xworker import xworker
document = xworker.window.document (edited)
from polyscript import XWorker
sync = XWorker("worker.py", config="pyscript.toml", type="pyodide").sync
def hello(arg):
print(arg)
sync.hello = hello
and
from polyscript import xworker
xworker.sync.hello(xworker.window.document.title) (edited)config= and type= parameters did the trick?









fixed instead? py:ready is an event globally dispatched (no need to hook into ... hooks :P) and that the <dialog> is probably the best element to use, as it doesn't require CSS hackery around it ... overall, it's a great demo on why we don't have the splash screen by default: with workers, the main thread is never blocked, there's no need to pause the world until py-script runs + with MicroPython instead of pyodide, the delay is irrelevant, and flushing a huge splash screen makes little sense, it'd be actually just disturbing. I hope this explain the current reason we don't py-splash anymore.





from pyweb import pydom
from pyscript import display, document, window, HTML, when
docbody = pydom["body"][0] # Element ('body' can be any selector)
I can create a new element:
baz = pydom.create("div", classes=["baz"])
docbody.append(baz)
I have to add an id inorder to use display or to assign using baz.content= ..id=.. option in create.baz.id = 'baz'
I want to add a pyclick="mycallback" but no options at create to do so.
I expect I have to assign the innerHTML directly or craft something using HTML(..)
What's an actual working (pyscript code) example where I can create a div or a button with a py-click event on it and maybe a css style please... (edited)





main: Div = Div(pydom["body"][0], id="main")
in the top of my app file, then everything plays nice after that (edited)









<script> tag, I donโt know of an editor/IDE that fully handles it. (Maybe PyCharm?). But Iโd recommend using the src attribute and put your source in a separate Python file where it will be properly highlighted

<script> tag, I donโt know of an editor/IDE that fully handles it. (Maybe PyCharm?). But Iโd recommend using the src attribute and put your source in a separate Python file where it will be properly highlighted py-click='name' not being highlighted right

<script type="py"> or <script type="mpy"> tag ... not <py-script> as that's full of hidden issues ... even if it kinda works as it used to ... I will try to check that entry source code and help improving it but I wanted to say: please use <script type="py"> in the present/future instead and be sure no surprises ever happen.src works well and has no issues in general with either approaches, but that also doesn't need any special VS Code/ium plugin 

py-click='name' not being highlighted right 






<textarea id="area" py-keydown="keyhandle"></textarea>
<script type="py">
def keyhandle(evt):
if evt.key == "Enter":
print("Hey it's the enter key!")
</script><textarea id="area"></textarea>
<script type="py">
from pyscript import when
@when('keydown', '#area')
def keyhandle(evt):
if evt.key == "Enter":
print("Hey it's the enter key!")
</script>

<textarea id="area" py-keydown="keyhandle"></textarea>
<script type="py">
def keyhandle(evt):
if evt.key == "Enter":
print("Hey it's the enter key!")
</script> <input type="text"> instead? (edited)
<input> when you hit enter, then clears that input box:
<input type="text" id="area">
<script type="py">
from pyscript import when
@when('keydown', '#area')
def keyhandle(evt):
if evt.key == "Enter":
print(f'You hit enter with "{evt.target.value}"" in the text input')
evt.target.value = ""
</script><input type="text" py-keydown="keyhandle">, like in the first example)




<script type="py"> (or the old style <py-script> tag), you're running code with Pyodide.<script type="mpy"> tag to run code with Micropython-compiled-to-webassemblytype="py" tag, and a limited subset of it is available in Micropython (very much a work-in-progress there)


-none-any.whl.
If one doesn't exist, you can try:



-none-any.whl.
If one doesn't exist, you can try:



form pyscript import window
window.addEventListener('load', print)onload event already happened, unless you have really heavy images down the page.





form pyscript import window
window.addEventListener('load', print) 

mpy equivalent would be:
<script type="mpy">
from pyscript import display, window
def callback(event):
display("This will run when all mpy script tags are complete")
display(f"{event.type=}")
window.addEventListener("py:all-done", callback)
</script>mpy:all-done event, but I guess it's signalling completion of PYscript's tags, not the tags of a particular interpreter type?


mpy equivalent would be:
<script type="mpy">
from pyscript import display, window
def callback(event):
display("This will run when all mpy script tags are complete")
display(f"{event.type=}")
window.addEventListener("py:all-done", callback)
</script> 



SpeechSynthesisUtterance needs to be created with new in JavaScript, and I haven't dug into the code enough to see if this is possible with PyScript yet. So I left it to JavaScript to create the object.

SpeechSynthesisUtterance needs to be created with new in JavaScript, and I haven't dug into the code enough to see if this is possible with PyScript yet. So I left it to JavaScript to create the object.


SpeechSynthesisUtterance needs to be created with new in JavaScript, and I haven't dug into the code enough to see if this is possible with PyScript yet. So I left it to JavaScript to create the object.




js : https://pyscript.com/@sadukie/gentle-sound-no-js/latest



<script type="importmap">
{ "imports": { "perf_hooks": "./perf_hooks.js" } }
</script>
foo = parent.create('div')
and I add a button with py-click by setting the foo.html to say:
'<button py-click="btnrndm" class="rndbtn" btntype="foo1" >R</button>'
Then btnrndm function is called with evt. Working fine.
But the evt.target is not an element. Its an [object HTMLButtonElement] (which is presented as a list when printed but its not a list but that's another issue.)
How do I add further elements under this object HTMLButtonElement using pydom. Or do I move wholesale over to js ?
all the methods dir() seem to be javascript.
Is there a pydom way to add the attributes like py-click="btnrndm" and btntype="foo1" to an exisiting element? (edited)

[[fetch]] at all, it seems.
I have 3 files:
scripts/main.py:import my_module
my_module.my_f()scripts/my_module.py:def my_f():
print("Code works?")index.html<html>
<head>
<!-- this part just works; I simply have PyScript itself stored on my computer locally -->
<link rel="stylesheet" href="pyscript/pyscript.css"/>
<script defer src="pyscript/pyscript.js"></script>
</head>
<body>
<!-- this is the part that does not work -->
<py-config>
[[fetch]]
files = ['scripts/main.py', 'scripts/my_module.py']
to_folder = 'scripts'
</py-config>
<py-script src="scripts/main.py"></py-script>
</body>
</html>
The 2 Python files are simply put in a folder called inner.
My problem is simple. I am getting this error:
ModuleNotFoundError: No module named 'my_module'
Even though my_module should work, just like it would if I ran Python outside of PyScript.

[[fetch]] at all, it seems.
I have 3 files:
scripts/main.py:import my_module
my_module.my_f()scripts/my_module.py:def my_f():
print("Code works?")index.html<html>
<head>
<!-- this part just works; I simply have PyScript itself stored on my computer locally -->
<link rel="stylesheet" href="pyscript/pyscript.css"/>
<script defer src="pyscript/pyscript.js"></script>
</head>
<body>
<!-- this is the part that does not work -->
<py-config>
[[fetch]]
files = ['scripts/main.py', 'scripts/my_module.py']
to_folder = 'scripts'
</py-config>
<py-script src="scripts/main.py"></py-script>
</body>
</html>
The 2 Python files are simply put in a folder called inner.
My problem is simple. I am getting this error:
ModuleNotFoundError: No module named 'my_module'
Even though my_module should work, just like it would if I ran Python outside of PyScript. 
fetch.
from = 'scripts/'
files = ['main.py', 'my_module.py']

from = 'scripts/'
files = ['main.py', 'my_module.py'] main.py in your files. The src attribute of a PyScript tag loads the Python code from the given URL, not from the virtual filesystem where fetch puts them
py-click="foo(5, 2)" instead of py-click="foo"
Is this even possible right now?
Currently, for the latter, we define foo as:
def foo(event):
pass
With arguments of course, the function definition would be something like:
def foo(x, y):
pass
It was possible with the โclassicโ version if I remember correctlyโฆ

py-click="foo(5, 2)" instead of py-click="foo"
Is this even possible right now?
Currently, for the latter, we define foo as:
def foo(event):
pass
With arguments of course, the function definition would be something like:
def foo(x, y):
pass
It was possible with the โclassicโ version if I remember correctlyโฆ 



data-row and data-column and use those

<button data-color='red' py-click="select_color">Red</button>
<button data-color='green' py-click="select_color">Green</button>
<button data-color='blue' py-click="select_color">Blue</button>
<script type="py">
def select_color(event):
print(f"Setting color to: {event.target.getAttribute('data-color')}")
</script>

<button data-color='red' py-click="select_color">Red</button>
<button data-color='green' py-click="select_color">Green</button>
<button data-color='blue' py-click="select_color">Blue</button>
<script type="py">
def select_color(event):
print(f"Setting color to: {event.target.getAttribute('data-color')}")
</script> 
int or float in Python or parseInt or parseFloat in JS, when it comes to number, might help too, as all attributes on the DOM are strings


















<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="module" src="https://pyscript.net/releases/2023.11.2/core.js"></script>
</head>
<body>
<script type="mpy">
from pyscript import display
print("Hello World")
display("Hello World")
</script>
</body>
</html>

print() statement will do what it's supposed to but you're not seeing the output. You have:
<script type="py">
# But this website can run Python
print("Hello world")
</script>
What you need is a way to capture the output where you can see it. The terminal attribute on the <script> tag will help in this case:
<script type="py" terminal>
# But this website can run Python
print("Hello world")
</script>
This will get you a terminal output like the attached image. (edited)type="py". This terminal doesn't work with MicroPython (type="mpy") yet - that's called out in the docs page for terminal. (edited)display() is another way of displaying output. There's more info on display() in the pyscript.display doc. (edited)


animation.FuncAnimation out on PyScript.com and am running into issues with the TimerWasm in the Pyodide implementation of Matplotlib not having a _timer attribute. This is the error that comes across:
AttributeError: 'TimerWasm' object has no attribute '_timer'
Maybe someone here will have more insight for you. (edited)

animation.FuncAnimation out on PyScript.com and am running into issues with the TimerWasm in the Pyodide implementation of Matplotlib not having a _timer attribute. This is the error that comes across:
AttributeError: 'TimerWasm' object has no attribute '_timer'
Maybe someone here will have more insight for you. (edited)




config attribute like in the following snippet?
<script config='{"files":{"main.py":""}}' type="py">
import main
main.printage()
</script>
If that works, consider using a TOML configuration file. Described in the documentation: https://pyscript.github.io/docs/2023.12.1/user-guide/configuration/.<script> was supported back then. If possible, try using 2023.12.1 as well.<script type="module" src="https://pyscript.net/releases/2023.12.1/core.js"></script>
Corresponding CSS can be dropped.

printf debugging before and after import.


terminal.clear() , but doesn't look like PyScript exposes the Terminal to call this method
for _ in range(1000): print("") 

sys.stdout might work. Doesn't rely on Pyscript implementation details.
https://stackoverflow.com/questions/63925727/how-to-enable-print-after-disabling-it


element.textContent = ''; but it's a good idea to expose the terminal reference that points at Xterm or at least some of its helpers, like .clear() to smooth out the experience. The inevitable question after would be ... did you mean to clear just the terminal or the whole env? In the first case, it's easy and cheap/fast, in the latter one, you need to await the bootstrap of a whole new pyodide or micropython interpreter, if that's what you're after, which is not 100% clear from your request. (edited)

element.textContent = ''; but it's a good idea to expose the terminal reference that points at Xterm or at least some of its helpers, like .clear() to smooth out the experience. The inevitable question after would be ... did you mean to clear just the terminal or the whole env? In the first case, it's easy and cheap/fast, in the latter one, you need to await the bootstrap of a whole new pyodide or micropython interpreter, if that's what you're after, which is not 100% clear from your request. (edited)terminal.clear()











ModuleNotFoundError: The module 'numpy' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("numpy") in Python, or
await pyodide.loadPackage("numpy") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
Actually none of the suggestions work.
import micropip; await micropip.install("numpy") This one fails for await being outside of a function (this actually works in the pyodide console)
adding a script tag with module type and calling
await pyodide.loadPackage("numpy") fails for pyodide being undefined
why is pyodide undefined, Is there another place to add this line?

ModuleNotFoundError: The module 'numpy' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("numpy") in Python, or
await pyodide.loadPackage("numpy") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
Actually none of the suggestions work.
import micropip; await micropip.install("numpy") This one fails for await being outside of a function (this actually works in the pyodide console)
adding a script tag with module type and calling
await pyodide.loadPackage("numpy") fails for pyodide being undefined
why is pyodide undefined, Is there another place to add this line? <py-config>
packages = [โnumpy`]
</py-config>
We should maybe consider catching that error from Pyodide and subsituting a pyscript specific one



<py-config>
packages = [โnumpy`]
</py-config>
We should maybe consider catching that error from Pyodide and subsituting a pyscript specific one 










demo.py? Might be easier testing with pyscript.display instead of print.

demo.py? Might be easier testing with pyscript.display instead of print. 

var textreceive ="" //variable javascript
<script type="py" terminal worker target="#terminal">
from pyscript import document
term = document.querySelector('script[terminal]').terminal
term.resize(40, 25)
import code
code.interact(local=globals())
</script>
Thank you (edited)

var textreceive ="" //variable javascript
<script type="py" terminal worker target="#terminal">
from pyscript import document
term = document.querySelector('script[terminal]').terminal
term.resize(40, 25)
import code
code.interact(local=globals())
</script>
Thank you (edited)window element of the pyscript module, thatโs a proxy for the JS global namespace
# if I pass in the options dict, I will get this error
# Error: ownKeys not implemented
# fireworks = Fireworks.new(container, {"opacity": True})
# It would be nice to get the sound working
# https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L91-L102
Thanks. (edited)

# if I pass in the options dict, I will get this error
# Error: ownKeys not implemented
# fireworks = Fireworks.new(container, {"opacity": True})
# It would be nice to get the sound working
# https://github.com/crashmax-dev/fireworks-js/blob/eedee4020e9c458fde83b60dfac6f2502d4593bb/packages/fireworks-js/src/options.ts#L91-L102
Thanks. (edited)to_js conversion functionality:
<canvas id="fw" style="background-color: black;"></canvas>
<py-config>
[js_modules.main]
"https://cdn.jsdelivr.net/npm/fireworks-js@2.10.7/+esm" = "Fireworks_Module"
</py-config>
<script type="py">
from pyscript import document, window
from pyscript.js_modules import Fireworks_Module
from pyodide.ffi import to_js
from js import Object
# This line converts the Python dict to a JS object
options = to_js({"decay": {"min": 0.005, "max": 0.020}}, dict_converter = Object.fromEntries)
container = document.querySelector('#fw')
fireworks = Fireworks_Module.Fireworks.new(container, options)
fireworks.start()
</script>options = to_js({"sound": {"enabled": True, "volume" : {"min": 4, "max": 8}, "files" : ["https://raw.githubcontent.com/crashmax-dev/fireworks-js/website/public/sounds/explosion0.mp3"]}}, dict_converter = Object.fromEntries) (edited)

options = to_js({"sound": {"enabled": True, "volume" : {"min": 4, "max": 8}, "files" : ["https://raw.githubcontent.com/crashmax-dev/fireworks-js/website/public/sounds/explosion0.mp3"]}}, dict_converter = Object.fromEntries) (edited)





# hash, there's no way, Web standards speaking, that ID should ever return more than a single element.

"#... selector. The thing that sucks is that there are other cases when you "know" there's only one element, without specifying the id...
An idea that I've been king of entertaining is to have an alias for "the first element" (something like _, first or something like that) so btn1 = pydom["#btn1"].first in the example above would point to the Element (I like _ better but I realize it isn't the most user friendly.. (edited)
first idea, for what it matters, it reflects the intent without making the returned node list 'hybrid"










dict_view has no len is only something Iโve seen with micropython

out element I think, you'd want to do out.innerHTML += "<h1>Your Text Here</h1>"













out element I think, you'd want to do out.innerHTML += "<h1>Your Text Here</h1>" for i in range(5):
out.innerHTML=f"<h1>This is count {i}</h1>
The output will be This is count 4(the last statement cause innerHTML will keep overwriting previous entries), that's it

dict_view has no len is only something Iโve seen with micropython 



useEffect(() => {
if (!wrapperRef.current) return;
const scriptElement = document.createElement("script");
scriptElement.type = "py";
(scriptElement as any).config = `{
"packages": ["protobuf"],
}`;
scriptElement.src = `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`;
wrapperRef.current.appendChild(scriptElement);
return () => {};
}, []);
But, the package protobuf does not seem to be installed. I get this error (attached img).
Do i have to install it in the py file's init function or something? I am also not sure of the micropip command given in the error message - since I'm using the Pyodide interpreter (i think?).
Super new to pyscript so please let me know if I've done some mistakes in the setup or if you need any additional info. Thanks! (edited)
__future__ should be on the top of the file when i tried to run the nanopb python file (linked), removing that line fixes it.. are future imports not supported in pyodide ?

useEffect(() => {
if (!wrapperRef.current) return;
const scriptElement = document.createElement("script");
scriptElement.type = "py";
(scriptElement as any).config = `{
"packages": ["protobuf"],
}`;
scriptElement.src = `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`;
wrapperRef.current.appendChild(scriptElement);
return () => {};
}, []);
But, the package protobuf does not seem to be installed. I get this error (attached img).
Do i have to install it in the py file's init function or something? I am also not sure of the micropip command given in the error message - since I'm using the Pyodide interpreter (i think?).
Super new to pyscript so please let me know if I've done some mistakes in the setup or if you need any additional info. Thanks! (edited)useEffect(() => {
if (!wrapperRef.current) return;
const pyScript = Object.assign(document.createElement("script"), {
type: "py",
src: `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`;
});
pyScript.setAttribute("config", JSON.stringify({
packages: ["protobuf"]
}));
wrapperRef.current.append(pyScript);
return () => {};
}, []); (edited)config attribute is not an accessor like type, src, async are ... Web speaking, so both config or worker attributes must be set explicitly.


pyScript not scriptElement ... that should work now


__future__ should be on the top of the file when i tried to run the nanopb python file (linked), removing that line fixes it.. are future imports not supported in pyodide ? 

useEffect(() => {
if (!wrapperRef.current) return;
const pyScript = Object.assign(document.createElement("script"), {
type: "py",
src: `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`;
});
pyScript.setAttribute("config", JSON.stringify({
packages: ["protobuf"]
}));
wrapperRef.current.append(pyScript);
return () => {};
}, []); (edited)pyScript.setAttribute("config", '{"packages": ["protobuf"]}');
But this also escapes the quotes and generates the same script tag.
I also tried this using a toml file for the config but that doesn't work either, gives the same error:
useEffect(() => {
if (!wrapperRef.current) return;
const pyScript = Object.assign(document.createElement("script"), {
type: "py",
src: `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`
});
pyScript.setAttribute(
"config",
`${process.env.PUBLIC_URL}/nanopb_generator/config.toml`
);
wrapperRef.current.append(pyScript);
return () => {};
}, []);
The config.toml file is present at this path: public/nanopb_generator/config.toml
with this content:
packages = ["protobuf" ]

pyScript.setAttribute("config", '{"packages": ["protobuf"]}');
But this also escapes the quotes and generates the same script tag.
I also tried this using a toml file for the config but that doesn't work either, gives the same error:
useEffect(() => {
if (!wrapperRef.current) return;
const pyScript = Object.assign(document.createElement("script"), {
type: "py",
src: `${process.env.PUBLIC_URL}/nanopb_generator/nanopb_generator_script.py`
});
pyScript.setAttribute(
"config",
`${process.env.PUBLIC_URL}/nanopb_generator/config.toml`
);
wrapperRef.current.append(pyScript);
return () => {};
}, []);
The config.toml file is present at this path: public/nanopb_generator/config.toml
with this content:
packages = ["protobuf" ] protobuf is not provided by Pyodide micropip registry

const script = document.createElement("script");
script.setAttribute("config", JSON.stringify({packages: ["protobuf"]}));
script.outerHTML;
// <script config="{"packages":["protobuf"]}"></script>
// but ...
script.getAttribute("config");
// '{"packages":["protobuf"]}'
JSON.parse(script.getAttribute("config"));
// {packages: ["protobuf"]}


<py-config> on the page already, such as:
<body>
<py-config>
packages = ["protobuf"]
</py-config>
</body>
setAttribute("config", ...) on the script tag).
I'll try it once with a worker as well since we might be using pyscript at various places on our platform with different package dependencies and having a global py-config would be bad right?


setAttribute("config", ...) on the script tag).
I'll try it once with a worker as well since we might be using pyscript at various places on our platform with different package dependencies and having a global py-config would be bad right? <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="module" src="https://cdn.jsdelivr.net/npm/@pyscript/core"></script>
<script type="module">
const pyScript = Object.assign(document.createElement("script"), {
type: "py",
textContent: `
print("Hello World")
`,
});
pyScript.toggleAttribute("worker");
pyScript.setAttribute("config", "./config.toml");
document.body.appendChild(pyScript);
</script>
</head>
</html>

setAttribute("config", ...) on the script tag).
I'll try it once with a worker as well since we might be using pyscript at various places on our platform with different package dependencies and having a global py-config would be bad right? micropip and use it to import extra stuff only when it's needed but within your own script, basically ignoring completely the need for a config. This would work best on main, imho. With Workers, you bootstrap pyodide every single time because it runs within ... well ... each worker. It's then a matter of tradeoffs











@when decorator with elements that are created by a JavaScript library. The elements are added to the DOM after the Python script runs, so @when seems to miss them. Does anyone have suggestions for adding event handlers dynamically?

@when decorator with elements that are created by a JavaScript library. The elements are added to the DOM after the Python script runs, so @when seems to miss them. Does anyone have suggestions for adding event handlers dynamically? py-click or py-mouseover etc. are handled by PyScript degardless of when in the page lifecycle they are created, even after PyScript runs.

@when decorator with elements that are created by a JavaScript library. The elements are added to the DOM after the Python script runs, so @when seems to miss them. Does anyone have suggestions for adding event handlers dynamically? @when inevitably happens when the interpreter is ready but, at the same time, py-x events can happen only once that interpreter is ready ... or event.preventDefault() and other synchronous things cannot happen. With workers, there is a specialized way to add event listeners, and yet these can't be known upfront so due event loop requiring synchrous tasks, we might, or might not, be able to solve the issue as a whole. (edited)waitUntil standard event primitive, but while I am happy that proposal hasn't been closed yet, I am not holding my breath that will ever work as we need, or be implemented in general: https://github.com/whatwg/html/issues/9540
@whenever operator could be useful as well, i.e. a Python function which hooks up functions to a Mutaton Observer that matches on event names. Not that it's mutually exclusive with somehow enabling py-*event from workers, just thinking out loud (edited)


@whenever operator could be useful as well, i.e. a Python function which hooks up functions to a Mutaton Observer that matches on event names. Not that it's mutually exclusive with somehow enabling py-*event from workers, just thinking out loud (edited)@whenever is needed in general, but unfortunately can't solve Python listeners added before the runtime/interpreter has a reason to understand these. (edited)

@whenever is needed in general, but unfortunately can't solve Python listeners added before the runtime/interpreter has a reason to understand these. (edited)

preventDefalut() or stopPropagation() (or mainly stopImmediatePropagation()) and there's no way around it (main reason for the push-back to my waitUntil() proposal). (edited)document.documentElement.onclick = ... in a sync script on top, so that any click to any post would be re-triggered once the React stuff is fully working. This is a single event though, and one can patch all of them (with perf degradation) ... but surely that's a way to fix the issue. As a module though, not as an owner of the site, it's super hard to implement the same at distance (i.e. lazy loaded PyScript would still fail at polluting the HTML element with listeners that can intercept reactions as that click event might have happened already). (edited)


x=document.getElementById("x")
x.classList.remove("is-hidden")

x=document.getElementById("x")
x.classList.remove("is-hidden") 
pydom["#x"] then remove_class("is-hidden") might do the trick.





remove_class I guessed you were hoping for PyDom to help .. but then again, you need a PyDom thing to be returned, not explicit JS primitives









pydom is right for you or it's missing something (or maybe you really need something different). If anything, I'd love to hear about what it's missing (from your point of view) and what is good about it, so we can know more about what the community needs....
ltk is really nice indeed! If you are looking for a UI toolkit it might be a good option. It has different goals than Pydom though. While Pydom focus on DOM access and manipulation, ltk focuses on UI generation.





display() takes an optional Boolean argument called append which defaults to True. If you pass append=False, the target location is cleared of old content before the new content is displayed

display() takes an optional Boolean argument called append which defaults to True. If you pass append=False, the target location is cleared of old content before the new content is displayed 


















2024.1.1 to start





terminal attribute of the script tag itself. See here for info and examples: https://jeff.glass/post/whats-new-pyscript-2024-1-1/#xterm




io.stderr or normalize it for both main and worker but an example code, instead of a screenshot, might help way more ... the filed issue has a screenshot I can't even access (for some reason) so I can't read how to reproduce the issue. If by chance you can help out with the most basic thing that fails to you, I'd be more than happy to fix it ASAP so next release will have your back covered. (edited)
interpreter.writeFile i believe

interpreter.writeFile i believe with open('myfile.txt', 'w+') as f:
f.write("Hello world")
You can later open that file in the same program and read from it... but as soon as the page refreshes or is reloaded, that file will be lost. Similarly, that file system has no relation to what's on your hard-drive.
You as the developer can pre-load files of any kind which are reachable at a URL into the virtual filesystem, using the files key in <py-config>:https://pyscript.github.io/docs/2024.1.1/user-guide/configuration/#files.
If you want your users to be able to upload/download files, see the upload and download recipes here: https://pyscript.recipes/2024.1.1/basic/file-upload/

localStorage - you can kind of think of it like "cookies" in your browser, but for bits of data. It's not really meant for storing whole documents, but it could be used that way. The key ideas are setItem() and getItem():
<textarea rows="4" cols="60" name="Textbox" id="text"></textarea>
<button py-click="store">Store Doc</button>
<script type="py">
from pyscript import window, document, display
ls = window.localStorage
def store(evt):
text = document.getElementById("text").value
ls.setItem("doc", text)
refresh_display()
def refresh_display():
if doc:= ls.getItem("doc"):
display(f'The stored document contents is: "{doc}"')
else:
display("No document stored")
refresh_display()
</script>localStorage is here: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage






from pyscript import display and change your call to print to display(โฆ) (edited)










2024.1.1, does anything change? Thatโs the most recent open source release - the default version on PyScript.com tends to lag by a few weeks






<script type=โpyโ> or <py-script> tag to the DOM it should evaluate

py:ready event does not fire in mpy. It does in pyodide. What is the correct solution ?
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>

py:ready event does not fire in mpy. It does in pyodide. What is the correct solution ?
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script> 


py:ready event does not fire in mpy. It does in pyodide. What is the correct solution ?
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script> 

Head section before the pyscript tags:
<style>
#loading { outline: none; border: none; background: transparent }
</style>
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>
Then in the Body put this at the top
<dialog id="loading">
<h1>Building Blah blah blah.</h1>
<h3>Assembling bits and pieces...</h3>
<h3>Almost there...</h3>
</dialog>
Just before your <script type="py" src=...
I think it could do with a little bit of endless progress bar as well but that's more guff. Maybe use animation css woudl be nice.




head
<style>
.loading-animation {
border: 8px solid #068770;
border-top: 8px solid #f0f0f0;
border-radius: 50%;
width: 50px;
height: 50px;
margin: auto;
animation: spin 1s linear infinite;
}
#loading {
justify-content: center;
background-color: #304050;
border-radius: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>
body
<dialog id="loading">
<div class="loading-animation"></div>
<h1>Building Blah blah blah.</h1>
<h3>Assembling bits and pieces...</h3>
<h3>Almost there...</h3>
</dialog>
Thanks again!
**small edit (edited)

head
<style>
.loading-animation {
border: 8px solid #068770;
border-top: 8px solid #f0f0f0;
border-radius: 50%;
width: 50px;
height: 50px;
margin: auto;
animation: spin 1s linear infinite;
}
#loading {
justify-content: center;
background-color: #304050;
border-radius: 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>
body
<dialog id="loading">
<div class="loading-animation"></div>
<h1>Building Blah blah blah.</h1>
<h3>Assembling bits and pieces...</h3>
<h3>Almost there...</h3>
</dialog>
Thanks again!
**small edit (edited).loadslide {animation: slide 9s ease-in; }
@keyframes slide {
from { transform: translateX(0%); }
to { transform: translateX(40%); } }
and added the class to:
<h3 class="loadslide">Almost there...</h3>

.loadslide {animation: slide 9s ease-in; }
@keyframes slide {
from { transform: translateX(0%); }
to { transform: translateX(40%); } }
and added the class to:
<h3 class="loadslide">Almost there...</h3> 
build: Fetch the contents of the engine and frontend, and put them together in the /dist folder, ready for upload to web server, or live serving
live: Run a live server and rebuild project on changes


pip install mygame and mygame-build, that deploys to dist and starts a live server.
I think by default this uses html that loads pysrcript's core.js over the network. I guess it users ask for it, we can add an option mygame-build vendor that streamlines the vedor code into dist.
pip install . && pytest
This will install the packages into the environment, and let me access them from from the tests package. I think I will need a little extra code to do E2E tests with the HTML, but I think selenium has me coveredbuild to a dist folder? (edited)live-serve the index.html, main.py, and my engine package, right there from the src directory!
Heck yeah!
pyscript.toml into the src directory, since that's pretty closely related to index.html etc





latest/, pyscript.toml, and main.py. The browser does not cache those files, as they change constantly on the server while you edit them. In contrast, when I load LTK Kitchensink, https://laffra.github.io/ltk/, hosted at github.io, you can see the artifacts are returned by the GitHub web server with caching instructions. This makes them fast to load, as they all come out of the browser's disk cache or memory cache now. Try hosting your code on a production server somewhere to find the actual performance characteristics. With an empty browser cache, LTK takes around 1.4s to load from Amsterdam. Warm cache loads take around 0.3s with Devtools open. With Devtools closed, warm load times go to <0.2s for the entire app to show. When you load https://laffra.github.io/ltk/, what numbers do you see for the first load time and successive load times for refresh of the page?














console.log not a terminal window in the DOM.

console.log not a terminal window in the DOM. 

console.log not a terminal window in the DOM. 





sync works dual way ... you expose a xworker.sync.method = () => {}; in main and you can call sync.method() in workers and vice-versa.sync.method = () => {} in workers and in main, you can call that as xworker.sync.method() which will be inevitably async. From the worker though, all callbacks via sync are ... well, ... syncxworker reference on main query the DOM to find your pyscript element and it's attached in there.






terminal in the TOML.
terminal in PyScript is a <script type="py" terminal> away and it gets super powers with <script type="py" terminal worker> as in there you can also import code and then code.interact() to have a whole, non-blocking, REPL (edited)









Uncaught PythonError: Traceback (most recent call last):
File "<exec>", line 60, in test
File "/home/pyodide/UITracker.py", line 47, in loadData
s.savedData[widgetClass.__name__]))
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable






https://pyscript.net/releases/2024.1.1/core.js



















<script type="py"> tag. Hence that discussion. It's a much-wanted feature and something that was present in Classic when we were main-thread-only, but things have gotten more complicated now that workers are in the mix

document.getElementById. If i have import pandas as pd in my python code, then pyscript.document.getElementById stops working.
https://sai1494.pyscriptapps.com/getelementbyid-error-with-pandas/
I am able to reproduce this on pyscript.com
In worker.py file, comment out the import pandas as pd line and the code works.

document.getElementById. If i have import pandas as pd in my python code, then pyscript.document.getElementById stops working.
https://sai1494.pyscriptapps.com/getelementbyid-error-with-pandas/
I am able to reproduce this on pyscript.com
In worker.py file, comment out the import pandas as pd line and the code works. 




pyscript.document.getElementById becomes None
async only (no worker, so main) = works
worker only (no async) = works
no attributes = works
So only time it fails is with both async and worker attributes. (edited)

document.getElementById. If i have import pandas as pd in my python code, then pyscript.document.getElementById stops working.
https://sai1494.pyscriptapps.com/getelementbyid-error-with-pandas/
I am able to reproduce this on pyscript.com
In worker.py file, comment out the import pandas as pd line and the code works. js.document somehow internally before we manage to normalize that within our code or pandas changes something to document.getElementById ... as the issue happens only when you import pandas, here some extra check I would perform:
import micropip pandas within your code, not through the config ... see if in async + worker that works (you have top level await with async so you shouldn't change much your program)getElementById before you import pandas ... getElementById = pyscript.document.getElementById.bind(pyscript.document) ... then use getElementById(...) directly instead

js.document somehow internally before we manage to normalize that within our code or pandas changes something to document.getElementById ... as the issue happens only when you import pandas, here some extra check I would perform:
import micropip pandas within your code, not through the config ... see if in async + worker that works (you have top level await with async so you shouldn't change much your program)getElementById before you import pandas ... getElementById = pyscript.document.getElementById.bind(pyscript.document) ... then use getElementById(...) directly instead

js.document reference before resolving packages ... I'll try to look at that so that async or not, we're good in workers.

pandas before importying pyscript ? I believe we might have a chicken/egg issue there if pyscript is not the top-most imported script ... although in theory our standard lib should be there before anything else so I am curious to better understand the details of your issue, thanks!

pandas before importying pyscript ? I believe we might have a chicken/egg issue there if pyscript is not the top-most imported script ... although in theory our standard lib should be there before anything else so I am curious to better understand the details of your issue, thanks! print("Hello from worker!")
import pyscript
import pandas as pd
print(f"Type of getElementById is: {type(pyscript.document.getElementById)}")
try:
el = pyscript.document.getElementById("py-script-output")
el.innerHTML = "test"
except Exception as e:
print(e)
I had made some changes to the files to test out your suggestions.Type of getElementById is: <class 'NoneType'> (edited)

Type of getElementById is: <class 'pyodide.ffi.JsProxy'>

print("Hello from worker!")
import pyscript
print(f"Type of getElementById is: {type(pyscript.document.getElementById)}")
import pandas as pd
try:
el = pyscript.document.getElementById("py-script-output")
el.innerHTML = "test"
except Exception as e:
print(e)
document instead out of the box... maybe this is some lazy import thing that is not working as expected on async scenariosfrom pyscript import document everything should work in your code
from pyscript import document and then accessing getElementById after pandas doesn't work
print("Hello from worker!")
from pyscript import document
import pandas as pd
print(f"Type of getElementById is: {type(document.getElementById)}")
...
This has the same issue. Print statement gives NoneType


print("Hello from worker!")
import pyscript
# just access it before pandas kicks in
pyscript.document.getElementById
import pandas as pd
print(f"Type of getElementById is: {type(pyscript.document.getElementById)}") (edited)
document, it's fairly unpredictable ... it might be a matter of cache or I don't know, but if I change the code next time I might have that working, on refresh, it doesn't ... if I remove pandas from packages, it's always there and working and never missing ... I wouldn't know where to even file an issue with pandas like this so if anyone knows please share! /cc @hoodjs.document at the global level to actuall improve packages compatibilities, pandas might or might not mess up getElementById (while the document is always the expected one).
<script worker async type="py" config='{"packages":["pandas"]}'>
import pyscript
# import pandas
print(f"Type of getElementById is: {type(pyscript.document.getElementById)}")
try:
el = pyscript.document.getElementById("py-script-output")
el.innerHTML = "test"
except Exception as e:
print(e)
</script>
<div id="py-script-output"></div>pyodide.runAsync is used, in combination with a worker. Sorry I don't have an answer to the why, but this looks pretty bad and I can't find pandas pyodide related code out there, or the specific pyodide version.

pyodide.runAsync is used, in combination with a worker. Sorry I don't have an answer to the why, but this looks pretty bad and I can't find pandas pyodide related code out there, or the specific pyodide version. document.getElementById? And that happens randomly and in a non predicable and reproducible way? Is my statement correct? and ss that true for the whole document or just document.getElementById?




document methods and the working one is pyodide.runAsync used instead of pyodide.run and in both cases the result is awaited before completion of the engine bootstrap.

document.getElementById? And that happens randomly and in a non predicable and reproducible way? Is my statement correct? and ss that true for the whole document or just document.getElementById? document is always defined which is the odd part ... that's patched upfront witohut issues but its methods become sometimes not reachable ... I haven't found a way to guarantee that's not the case when pandas is part of the packages, even less when pandas is imported in the code, no matter where that happens (before or after, but when it's after, chances methods are broken are higher).


from polyscript import currentScript
try:
from polyscript.xworker.window import document
except:
from js import document
import pandas
print(f"In {currentScript.getAttribute('env')} the type of getElementById is: {type(document.getElementById)}")
try:
el = document.getElementById("py-script-output")
el.innerHTML = "test"
except Exception as e:
print(e)
This is the related HTML layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="module" src="https://cdn.jsdelivr.net/npm/polyscript"></script>
</head>
<body>
<!-- always work -->
<script env="main" type="pyodide" config='{"packages":["pandas"]}' src="./pandas.py"></script>
<script env="async" async type="pyodide" config='{"packages":["pandas"]}' src="./pandas.py"></script>
<script env="worker" worker type="pyodide" config='{"packages":["pandas"]}' src="./pandas.py"></script>
<!-- most time doesn't work -->
<script env="async-worker" async worker type="pyodide" config='{"packages":["pandas"]}' src="./pandas.py"></script>
<div id="py-script-output"></div>
</body>
</html>
And finally this is the outcome:
In main the type of getElementById is: <class 'pyodide.ffi.JsProxy'>
In async the type of getElementById is: <class 'pyodide.ffi.JsProxy'>
In worker the type of getElementById is: <class 'pyodide.ffi.JsProxy'>
In async-worker the type of getElementById is: <class 'NoneType'>
'NoneType' object is not callable (edited)runAsync has, internally, blocking calls to the main so that something locking the script execution might not be fully trusted or it might fail behind "conditions" ... thanks!
getElementById but use querySelector instead !!! /cc @hood @Fabio ... so document but the getElementById is busted there ... with this code I don't have any issue anymore:
from polyscript import currentScript
try:
from polyscript.xworker.window import document
except:
from js import document
import pandas
print(f"In {currentScript.getAttribute('env')} the type of querySelector is: {type(document.querySelector)}")
try:
el = document.querySelector("#py-script-output")
el.innerHTML = "test"
except Exception as e:
print(e) (edited)
getElementById in pandas source code and I wonder if the pyodide version has anything different at all ... this issue is so odd!












py-config or an mpy-config to declare imports you want available ... otherwise you can import micropip and do whatever you like there.





npx command available, is to npx static-handler --coi . where the last . is the root folder you'd like to test and keep in mind if such folder doesn't contain an index.html in it, you'll see nothing and you need to reach the exact path insteadnpx static-handler --coi . is basically the same as runnign npm start server to host your file from the root of the projectnpm run build before testing anything elsenpm run dev instead and in a different shell/console/tab run npm run server./dist/core.js and ./dist/core.css from relative URLs you have in your pipeNO_MIN=true npm run build before tests, you'll have non minified files to dig into source code out of a fork ... that's basically the same, just a tad slower, than npm run dev but after latest command you also need to still run npm run build if you want prod usable artifacts

npx command available, is to npx static-handler --coi . where the last . is the root folder you'd like to test and keep in mind if such folder doesn't contain an index.html in it, you'll see nothing and you need to reach the exact path insteadnpx static-handler --coi . is basically the same as runnign npm start server to host your file from the root of the projectnpm run build before testing anything elsenpm run dev instead and in a different shell/console/tab run npm run server./dist/core.js and ./dist/core.css from relative URLs you have in your pipeNO_MIN=true npm run build before tests, you'll have non minified files to dig into source code out of a fork ... that's basically the same, just a tad slower, than npm run dev but after latest command you also need to still run npm run build if you want prod usable artifacts


hooks from @pyscript/core and then change the io field on ready
ImportError: cannot import name 'JsArray' from 'pyodide.ffi' (/lib/python3.10/site-packages/pyodide/ffi/__init__.py)







ffi.to_js(listOrTuple) which might be doing just about the same.

ImportError: cannot import name 'JsArray' from 'pyodide.ffi' (/lib/python3.10/site-packages/pyodide/ffi/__init__.py) 


ffi.to_js(listOrTuple) which might be doing just about the same. 






py-config or an mpy-config to declare imports you want available ... otherwise you can import micropip and do whatever you like there. 


os._exit() produc ethe same?
exit() etc... doesn't really make sense in PyScript. Exit is how to terminate a Python program, but what should be terminated... the browser tab..? Etc etc etc - feels like a "don't do that" bug 



exit() etc... doesn't really make sense in PyScript. Exit is how to terminate a Python program, but what should be terminated... the browser tab..? Etc etc etc - feels like a "don't do that" bug 




















import asyncio
async def _test():
#await asyncio.sleep(1)
return 1
def test():
loop = asyncio.get_event_loop()
future = asyncio.Future()
# Run the async function in the background using run_coroutine_threadsafe
async_task = asyncio.ensure_future(_test(), loop=loop)
async_task.add_done_callback(lambda f: future.set_result(f.result()))
return_value = loop.run_until_complete(future)
return return_value
test()
print(test())
Running locally it returns me 1 but on pyscript it returns me a <Future pending>, any pointers as to why and how to make it run the right thing? 

import asyncio
async def _test():
#await asyncio.sleep(1)
return 1
def test():
loop = asyncio.get_event_loop()
future = asyncio.Future()
# Run the async function in the background using run_coroutine_threadsafe
async_task = asyncio.ensure_future(_test(), loop=loop)
async_task.add_done_callback(lambda f: future.set_result(f.result()))
return_value = loop.run_until_complete(future)
return return_value
test()
print(test())
Running locally it returns me 1 but on pyscript it returns me a <Future pending>, any pointers as to why and how to make it run the right thing? async ?

src attribute or an entry in the py-config that points at that file so you can import it

import asyncio
async def _test():
#await asyncio.sleep(1)
return 1
def test():
loop = asyncio.get_event_loop()
future = asyncio.Future()
# Run the async function in the background using run_coroutine_threadsafe
async_task = asyncio.ensure_future(_test(), loop=loop)
async_task.add_done_callback(lambda f: future.set_result(f.result()))
return_value = loop.run_until_complete(future)
return return_value
test()
print(test())
Running locally it returns me 1 but on pyscript it returns me a <Future pending>, any pointers as to why and how to make it run the right thing? <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
<script type="py" async>
import asyncio
async def _test():
#await asyncio.sleep(1)
return 1
def test():
loop = asyncio.get_event_loop()
future = asyncio.Future()
# Run the async function in the background using run_coroutine_threadsafe
async_task = asyncio.ensure_future(_test(), loop=loop)
async_task.add_done_callback(lambda f: future.set_result(f.result()))
return_value = loop.run_until_complete(future)
return return_value
print(await test())
</script>
</head>
</html>run_until_complete you still can't block the code from dealing with just a promise ... if you return that test() within a runAsync in pyodide interpreter though, that will eventually give you the 1 you are after, but if you print that without await in place, I am not sure how that could ever possibly work.
test is sync and is doing some async magic under the hood, so I shouldn't need to use the async attribute right? The goal is to use said test function in a sync context but is wrapping some code that could blood, so running that code will make sure that the main thread doesn't block, for example this code will not block the main thread.
import asyncio
from time import sleep
async def _test():
print("sleeping...")
sleep(2)
print("another sleep")
sleep(4)
def test():
loop = asyncio.get_event_loop()
future = asyncio.Future()
# Run the async function in the background using run_coroutine_threadsafe
async_task = asyncio.ensure_future(_test(), loop=loop)
async_task.add_done_callback(lambda f: future.set_result(f.result()))
return_value = loop.run_until_complete(future)
return return_value
print("Test block...")
test()
print("done!")
It will print:
Test block...
done!
sleeping...
another sleep
The surprising thing on this code is that in pyscript/pyodide I can't get a return value, but locally I can
pyscript.sync.sleep instead
test() prints if that's the case?
async attribute, you usually don't ever even need asyncio in general.sleep(4) blocks for 4 seconds the UI ... put a button aroud and see you unable to click it for 4 secondsasync attribute with top-level await capability, so you can just drop asyncio there and do the same<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
<script type="py" async worker>
from pyscript import sync
async def test():
print("sleep 1 sec")
sync.sleep(1)
print("slept 1 sec")
return 1
print(await test())
</script>
</head>
</html>

src attribute or an entry in the py-config that points at that file so you can import it 







async attribute with top-level await capability, so you can just drop asyncio there and do the same 

asyncio you should have an async attribute in the script instead and remove every code that uses asyncio as that won't be needed anymore thanks to async and top-level await

asyncio module, because indeed the conversation was like "what does it do or how and is it needed with runAsync ability?"


async and await when needed, no asyncio is needed to me ... if it is, gotta await the final call/result as the Web can't block promises even on workers.


await API calls to me ... although, there is no other way around (that I know) if not by blocking with synchronous XHR which is already deprecated on main so it's a slippery slope and and a short term harakiri to me. Sorry for not providing the answers you were looking for.

await API calls to me ... although, there is no other way around (that I know) if not by blocking with synchronous XHR which is already deprecated on main so it's a slippery slope and and a short term harakiri to me. Sorry for not providing the answers you were looking for. 

<!DOCTYPE html>
<html lang="en">
<head>
<title>Random Number Generator</title>
<!-- Recommended meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- PyScript CSS -->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css">
<!-- This script tag bootstraps PyScript -->
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
</head>
<body>
<p id="today"><p>
<script type="py" src="./main.py" config="./pyscript.toml" terminal></script>
</body>
</html>
python:
import datetime as dt
def get_rand_num():
Element("today").write(str(dt.date.today()))
get_rand_num()

<!DOCTYPE html>
<html lang="en">
<head>
<title>Random Number Generator</title>
<!-- Recommended meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<!-- PyScript CSS -->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css">
<!-- This script tag bootstraps PyScript -->
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
</head>
<body>
<p id="today"><p>
<script type="py" src="./main.py" config="./pyscript.toml" terminal></script>
</body>
</html>
python:
import datetime as dt
def get_rand_num():
Element("today").write(str(dt.date.today()))
get_rand_num() Element globally anymore, you need to import it from pydom then if it still doesn't work try with a proper CSS selector such as #today.
pyodide.ffi.JsException: Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callable.
For more information about the cause of this error, use 'pyodide.setDebug(true)' errors. If I import pyodide and pyodide.setDebug(true) it tells me no such function. How do I debug which thing is being destroyed and properly proxy it.

pyodide.ffi.JsException: Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callable.
For more information about the cause of this error, use 'pyodide.setDebug(true)' errors. If I import pyodide and pyodide.setDebug(true) it tells me no such function. How do I debug which thing is being destroyed and properly proxy it. experimental_create_proxy = "auto" in your TOML and see if that error goes away.from pyodide.ffi import create_proxy and wrap the listener there ... if it's a one-off listener there is the create_callable_once utility but this is pyodide internals https://pyodide.org/en/stable/usage/type-conversions.html#calling-javascript-functions-from-python




Element globally anymore, you need to import it from pydom then if it still doesn't work try with a proper CSS selector such as #today. 



packages key, which you can think of as roughly the equivalent of pip installโฆ
packages = ["selenium"]
python:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# URL of the website
url = "https://finance.yahoo.com/losers/"
# XPath of the map sliders
element_xpath = '//*[@id="scr-res-table"]/div[1]/table/tbody/tr[1]/td[3]/fin-streamer'
# Setting up the WebDriver
driver = webdriver.Chrome()
try:
# Open the website
driver.get(url)
driver.maximize_window()
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, element_xpath)))
# Get the text value of the element
value = element.text
print(value)
finally:
# Close the browser
pass
# XPATH to the list of containers: //*[@id="scr-res-table"]/div[1]/table/tbody/tr[1] -- Change the index on ending


packages = ["selenium"]
python:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# URL of the website
url = "https://finance.yahoo.com/losers/"
# XPath of the map sliders
element_xpath = '//*[@id="scr-res-table"]/div[1]/table/tbody/tr[1]/td[3]/fin-streamer'
# Setting up the WebDriver
driver = webdriver.Chrome()
try:
# Open the website
driver.get(url)
driver.maximize_window()
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, element_xpath)))
# Get the text value of the element
value = element.text
print(value)
finally:
# Close the browser
pass
# XPATH to the list of containers: //*[@id="scr-res-table"]/div[1]/table/tbody/tr[1] -- Change the index on ending 
















.exe file, any of them, via browser ... PyScript runs in a browser through WASM targeting interpreters, Pyodide and MicroPython. None of these are Windows machines, Windows OS, or able to run Windows executable ... I hope this clarifies.






interpreter.FS in worker python code to read files and write them to worker threads file system.
So first is this is the correct way to move files from main FS to worker FS?
I am able to do this for csv files by reading them as text, but i can't do that for pdfs because that is binary data and will probably get corrupted with utf8 encoding.
interpreter.FS.readFile gives me a Uint8Array object (probably a proxy because i am running this in python), how can i use python write function to write this Uint8Array to a file?
I tried the approach on pyscript.recipes, but it doesn't work. I get an AttributeError for arrayBuffer.
Edit: The interpreter.FS is the micropython interpreter which i capture using the hook. (edited)

interpreter.FS in worker python code to read files and write them to worker threads file system.
So first is this is the correct way to move files from main FS to worker FS?
I am able to do this for csv files by reading them as text, but i can't do that for pdfs because that is binary data and will probably get corrupted with utf8 encoding.
interpreter.FS.readFile gives me a Uint8Array object (probably a proxy because i am running this in python), how can i use python write function to write this Uint8Array to a file?
I tried the approach on pyscript.recipes, but it doesn't work. I get an AttributeError for arrayBuffer.
Edit: The interpreter.FS is the micropython interpreter which i capture using the hook. (edited)

interpreter.FS in worker python code to read files and write them to worker threads file system.
So first is this is the correct way to move files from main FS to worker FS?
I am able to do this for csv files by reading them as text, but i can't do that for pdfs because that is binary data and will probably get corrupted with utf8 encoding.
interpreter.FS.readFile gives me a Uint8Array object (probably a proxy because i am running this in python), how can i use python write function to write this Uint8Array to a file?
I tried the approach on pyscript.recipes, but it doesn't work. I get an AttributeError for arrayBuffer.
Edit: The interpreter.FS is the micropython interpreter which i capture using the hook. (edited)














time.sleep(0.5) in there and why that's not from pyscript import sync and then a sync.sleep(0.5) instead? 

time.sleep(0.5) in there and why that's not from pyscript import sync and then a sync.sleep(0.5) instead? time native module, we do offer a sync.sleep out of the box though ... but in general, from a worker, I don't think you ever want to sleep(X) for the sake of it, it's not necessary.

time native module, we do offer a sync.sleep out of the box though ... but in general, from a worker, I don't think you ever want to sleep(X) for the sake of it, it's not necessary. while loop and I am not sure I understand why that's needed .

time.sleep(0.5) in there and why that's not from pyscript import sync and then a sync.sleep(0.5) instead? 



time = sync.time and import that sync from the pyscript module. A try on top of the program should make it portable. # If the game loop has ended and the win variable is True
if win:
# Calculates the total number of guesses by adding the lengths of the guessed_letters and guessed_words lists
# Subtracts 1 from this to allow the first guess to be without penalty
total_guesses = len(guessed_letters) + len(guessed_words) - 1
score = 26 - total_guesses
print(f"\nYou win! The answer is {selected_word}")
time.sleep(0.75)
print(f"You lost {total_guesses} points based on the number of guesses")
print(f"Score for this game: {score}")
else:
print(f"\nYou lose. The correct answer is {selected_word}")



<py-config>
[[interpreters]]
src = "/runtime/pyodide.js"
name = "pyodide-0.25.0"
lang = "python"
</py-config>
<link rel="stylesheet" href="popup.css" />
<link rel="stylesheet" href="/runtime/pyscript.css" />
<script src="/runtime/pyscript.js"></script>
</head>
<body>
<button id="hi" class="btn">Hello!</button>
<button id="bye" class="btn">Goodbye!</button>
<py-script src="./scripts/main.py"></py-script>
</body>
</html>from pyscript import window, when
@when('click', '.btn')
def handler(evt):
id = evt.target.getAttribute("id")
window.alert(id)
I think the problem I'm running into has something to do with the fact that I have to install everything locally because of chromes Content Security Policy
Maybe someone with more knowledge in this kind of thing could help me figure this out (edited)

<py-config>
[[interpreters]]
src = "/runtime/pyodide.js"
name = "pyodide-0.25.0"
lang = "python"
</py-config>
<link rel="stylesheet" href="popup.css" />
<link rel="stylesheet" href="/runtime/pyscript.css" />
<script src="/runtime/pyscript.js"></script>
</head>
<body>
<button id="hi" class="btn">Hello!</button>
<button id="bye" class="btn">Goodbye!</button>
<py-script src="./scripts/main.py"></py-script>
</body>
</html>from pyscript import window, when
@when('click', '.btn')
def handler(evt):
id = evt.target.getAttribute("id")
window.alert(id)
I think the problem I'm running into has something to do with the fact that I have to install everything locally because of chromes Content Security Policy
Maybe someone with more knowledge in this kind of thing could help me figure this out (edited)interpreter = "/runtime/pyodide.js" eventually but it should rather point to .mjs ... be sure you are on latest PyScript though

interpreter = "/runtime/pyodide.js" eventually but it should rather point to .mjs ... be sure you are on latest PyScript though type="module"

interpreter = "/runtime/pyodide.js" eventually but it should rather point to .mjs ... be sure you are on latest PyScript though cannot import name 'document' from 'pyscript'



wget https://pyscript.net/latest/pyscript.js -o pyscript.js
wget https://pyscript.net/latest/pyscript.css -o pyscript.css








<div py-onload="other_func" id="other_text"></div>
this is the function
def other_func(event):
other_text = document.querySelector("#other_text")
other_text.innerText = "Hello World"
but the text is not appearing. what am i doing wrong?

<div py-onload="other_func" id="other_text"></div>
this is the function
def other_func(event):
other_text = document.querySelector("#other_text")
other_text.innerText = "Hello World"
but the text is not appearing. what am i doing wrong? 


onload event is usually a window thing, not a per-element one. If you want to do anything with PyScript once the interpreter is ready you have py:ready event on the main or py:done once the code has been executed, so that this should actually work:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
</head>
<body>
<div id="other_text"></div>
<script type="py">
from pyscript import window, document
# Pyodide specific thing
from pyodide.ffi import create_once_callable, to_js
def other_func(event):
other_text = document.querySelector("#other_text")
other_text.innerText = "Hello World"
window.addEventListener(
'py:done',
create_once_callable(other_func),
to_js({"once": True})
)
</script>
</body>
</html>

onload event is usually a window thing, not a per-element one. If you want to do anything with PyScript once the interpreter is ready you have py:ready event on the main or py:done once the code has been executed, so that this should actually work:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
</head>
<body>
<div id="other_text"></div>
<script type="py">
from pyscript import window, document
# Pyodide specific thing
from pyodide.ffi import create_once_callable, to_js
def other_func(event):
other_text = document.querySelector("#other_text")
other_text.innerText = "Hello World"
window.addEventListener(
'py:done',
create_once_callable(other_func),
to_js({"once": True})
)
</script>
</body>
</html> <script type="py" worker>
from pyscript import window, document
def other_func(event):
other_text = document.querySelector("#other_text")
other_text.innerText = "Hello World"
window.addEventListener('py:done', other_func, {"once": True})
</script>
This would do the same and it will work eventually out of the box in MicroPython too (we're waiting for a release).





<py-config>
packages = ["js"]
interpreter = "./pyodide/pyodide.mjs"
</py-config> from pyscript import when
import js
from pyodide.ffi import to_js
@when('click', '.copyText')
def copyText(evt):
element = evt.target
js.navigator.clipboard.writeText(element.value)ImportError: can't import name to_js
from pyscript import when
import js
#copies an elements text to clipboard
@when('click', '.copyText')
def copyText(evt):
element = evt.target.innerHTML
js.navigator.clipboard.writeText(f"{element}") (edited)

pyscript.document and do Web stuff.

from pyscript import when
import js
#copies an elements text to clipboard
@when('click', '.copyText')
def copyText(evt):
element = evt.target.innerHTML
js.navigator.clipboard.writeText(f"{element}") (edited)from pyscript import window, when is the way, then window.navigator ... on the main page is the same js namespace, on workers it brigde main synchronously even if things are async in there.
import matplotlib.pyplot as plt
import seaborn
import csv
import pyscript
def generate_graph(event):
with open(r".\assets\parsed_dataset.csv") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
# Parses the data in the dataset csv file to obtain a list of raw data
heart_rates = []
for i in csv_reader:
heart_rates.append(i[1])
del heart_rates[0]
# Converts the data from string to float
for i in range(0, len(heart_rates)):
heart_rates[i] = float(heart_rates[i])
# Compiles a graph from the data
seaborn.set(rc={"figure.figsize": (8, 4)})
plt.ylabel("Frequency")
graph = seaborn.distplot(heart_rates)
# Outputs the graph
pyscript.display(graph)

import matplotlib.pyplot as plt
import seaborn
import csv
import pyscript
def generate_graph(event):
with open(r".\assets\parsed_dataset.csv") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
# Parses the data in the dataset csv file to obtain a list of raw data
heart_rates = []
for i in csv_reader:
heart_rates.append(i[1])
del heart_rates[0]
# Converts the data from string to float
for i in range(0, len(heart_rates)):
heart_rates[i] = float(heart_rates[i])
# Compiles a graph from the data
seaborn.set(rc={"figure.figsize": (8, 4)})
plt.ylabel("Frequency")
graph = seaborn.distplot(heart_rates)
# Outputs the graph
pyscript.display(graph) 

from pyscript import window, when is the way, then window.navigator ... on the main page is the same js namespace, on workers it brigde main synchronously even if things are async in there. 
preventDefault on an event like in JS? I have this:@when("submit", "#poster")
async def on_submit(event: JsProxy):
passpreventDefault is not a method of JsProxy (edited)
console.log? I used print but nothing appears in the JavaScript console, and display meanwhile appends to the actual HTML (edited)

console.log? I used print but nothing appears in the JavaScript console, and display meanwhile appends to the actual HTML (edited)

print does appear in console

pyfetch just fine, but need to pass a body that is FormData. So how do I construct this FormData on the python side?
from js import FormData
@when("click", "#poster")
async def on_submit(_):
data = FormData.new()
[input_el] = pydom["#files"]
for file in input_el._js.files:
data.append(file.name, file)
await pyfetch(f"{API_HOST}/record", method="post", body=data)from js import, need to do FormData.new() instead of FormData(), and need to access "private" _jspydom is without requiring exposure to the JS


import matplotlib.pyplot as plt
import seaborn
import csv
import pyscript
def generate_graph(event):
with open(r".\assets\parsed_dataset.csv") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
# Parses the data in the dataset csv file to obtain a list of raw data
heart_rates = []
for i in csv_reader:
heart_rates.append(i[1])
del heart_rates[0]
# Converts the data from string to float
for i in range(0, len(heart_rates)):
heart_rates[i] = float(heart_rates[i])
# Compiles a graph from the data
seaborn.set(rc={"figure.figsize": (8, 4)})
plt.ylabel("Frequency")
graph = seaborn.distplot(heart_rates)
# Outputs the graph
pyscript.display(graph) 




import matplotlib.pyplot as plt
import seaborn
import csv
import pyscript
def generate_graph(event):
with open(r".\assets\parsed_dataset.csv") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
# Parses the data in the dataset csv file to obtain a list of raw data
heart_rates = []
for i in csv_reader:
heart_rates.append(i[1])
del heart_rates[0]
# Converts the data from string to float
for i in range(0, len(heart_rates)):
heart_rates[i] = float(heart_rates[i])
# Compiles a graph from the data
seaborn.set(rc={"figure.figsize": (8, 4)})
plt.ylabel("Frequency")
graph = seaborn.distplot(heart_rates)
# Outputs the graph
pyscript.display(graph) 











py-config tag or a config JSON/TOML file ... namely: packages = ["pandas"] as example. Also please use window from pyscript instead of importing stuff from js unless you really need the current worker global context there.

py-config tag or a config JSON/TOML file ... namely: packages = ["pandas"] as example. Also please use window from pyscript instead of importing stuff from js unless you really need the current worker global context there. 




plugins = ["!error"] and see errors only in console but the error would likely be the same.

plugins = ["!error"] and see errors only in console but the error would likely be the same. 

<input type="file" id="file-upload"> such that the user can select the table from his local machine. What I want to do is to read and display the head. Then I want the user to make some selection via drop down. Once the user clicks a second button I want to continue to read the file. I haven't done any web development before, so I am not really sure how to tackle this. What I had done so far is converting the file to bytes and then using BytesIO to get the data. my_bytes: bytes = await get_bytes_from_file(first_item) As far as I understand, I am reading in the whole file here. Which can be very inefficient with regards to the browsers memory (?) especially with regards to large files. Is there any way to read a file line by line without causing any browser security issues? (edited)

<input type="file" id="file-upload"> such that the user can select the table from his local machine. What I want to do is to read and display the head. Then I want the user to make some selection via drop down. Once the user clicks a second button I want to continue to read the file. I haven't done any web development before, so I am not really sure how to tackle this. What I had done so far is converting the file to bytes and then using BytesIO to get the data. my_bytes: bytes = await get_bytes_from_file(first_item) As far as I understand, I am reading in the whole file here. Which can be very inefficient with regards to the browsers memory (?) especially with regards to large files. Is there any way to read a file line by line without causing any browser security issues? (edited)


FileReader via JS and add that progress listener and eventually abort the reading once you read enough data but ... you also need to parse yourself the binary data as it comes, because buffers are buffers without any knowledge about CSV or PNG or JPG or whatever file you are reading so it's entirely on you to parse every chunk of data, stop where you want, eventually keep reading from that point later on but like I've said, the next time you'll need to re-instrument the whole thing from the scratch, 'cause the API is not meant to resume binary reads so we're kinda incapable of providing all this out of the box and, most importantly, from a worker it'd be a mess because the File API will exists only on main but worker listeners are inevitably async (if meaning to work on main) so ... don't hold your breath yet, as I am afraid we need more primitives on the Web to offer that. (edited)












FileReader via JS and add that progress listener and eventually abort the reading once you read enough data but ... you also need to parse yourself the binary data as it comes, because buffers are buffers without any knowledge about CSV or PNG or JPG or whatever file you are reading so it's entirely on you to parse every chunk of data, stop where you want, eventually keep reading from that point later on but like I've said, the next time you'll need to re-instrument the whole thing from the scratch, 'cause the API is not meant to resume binary reads so we're kinda incapable of providing all this out of the box and, most importantly, from a worker it'd be a mess because the File API will exists only on main but worker listeners are inevitably async (if meaning to work on main) so ... don't hold your breath yet, as I am afraid we need more primitives on the Web to offer that. (edited)

js_modules.main library ... basically just copy over the code as Python, it should be doable.

COEP=require-corp and CORP=cross-origin headers set on my server. 

COEP=require-corp and CORP=cross-origin headers set on my server. unpkg.com doesn't work with PyScript and workers neither.

COEP=require-corp and CORP=cross-origin headers set on my server. allow="cross-origin-isolated" as iframe attribute might solve that, please share if it does, thank you!
crossorign="anonymous" to each script and img inside the frame and that does the trick for this case.


pyscript.document and do Web stuff. 


ltk.Button("Copy text", ltk.proxy(lambda event: copy_iso_text(event))).addClass("copybtn")
and
def copy_iso_text(event):
"""
select the iso text input and copy
- for user to paste elsewhere
"""
ltk.jQuery("#isolabel").select()
ltk.window.document.execCommand("copy")

ltk.Button("Copy text", ltk.proxy(lambda event: copy_iso_text(event))).addClass("copybtn")
and
def copy_iso_text(event):
"""
select the iso text input and copy
- for user to paste elsewhere
"""
ltk.jQuery("#isolabel").select()
ltk.window.document.execCommand("copy") 



js_modules.main library ... basically just copy over the code as Python, it should be doable. js_modules.main library and I've managed to translate most of the code to python. But I haven't found a way to change the main part to python which is lines 53 to 63. How to change step : function(row){ ... such that python knows to trigger the function when step is called? Also this part looks a bit like a dict. So I tried that, but dict keys can't be called like attributes, which is what papaparse seems to be doing internally. (edited)

js_modules.main library and I've managed to translate most of the code to python. But I haven't found a way to change the main part to python which is lines 53 to 63. How to change step : function(row){ ... such that python knows to trigger the function when step is called? Also this part looks a bit like a dict. So I tried that, but dict keys can't be called like attributes, which is what papaparse seems to be doing internally. (edited)pyodide,ffi,create_prosy to wrap it, for Python to JS object literals use pyodide.ffi.to_js and pass js.Object.fromEntries as dict_converter option. We're actively trying to make this as smooth as posible as we speak!
print("Hello")
a = input()
print("You entered", a)
But on the terminal, it prints "Hello" twice on two lines and then wait for another input. My question is: Why is one print statement printing stuff twice?
Note: This only happens when I use input() after print().
Example link - https://pyscript.com/@justani/weathered-lab/latest

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
</head>
<body>
<script type="mpy" worker>
from pyscript import window
print("Hello")
a = window.prompt()
print("You entered", a)
</script>
</body>
</html> (edited)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyTerminal Main</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
<style>.xterm { padding: .5rem; }</style>
</head>
<body>
<script type="py" worker terminal>
import code
code.interact()
</script>
<script type="py" worker terminal>
import code
code.interact()
</script>
</body>
</html>test = input("> "); print("Hello, World!"); print(test); and either provide a line or not, it will work as expected
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyTerminal Main</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
<style>.xterm { padding: .5rem; }</style>
</head>
<body>
<script type="py" worker terminal>
print("Hello")
a = input()
print("You entered", a)
</script>
</body>
</html>
input().
Something like this doesn't print "hello" twice:
print("hello")
a = int(input('type a number'))
print(a)
input("") won't stop nor ask for user input, it just keeps going which is undesired. AFAIK and IIRC we don't change that behavior at all so maybe this could be even readline module to blame, which is why I think we need a deeper investigation. Put any content in the input("...") like even an invisible zero-width space char and everything is fine. This works to me indeed:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyTerminal Main</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.3/core.css">
<script type="module" src="https://pyscript.net/releases/2024.1.3/core.js"></script>
<style>.xterm { padding: .5rem; }</style>
</head>
<body>
<script type="py" worker terminal>
print("Hello")
a = input("โ")
print("You entered", a)
</script>
</body>
</html> (edited)input 








<script>
function myfunc(val) {
console.log("You said", val);
}
</script>
<script type="py">
from pyscript import window
window.myfunc("Hi from PyScript")
</script>var instead of let or const

window) - you can use the js_modules feature in your configuration to import that module directly via PyScript, which replaces the need to include that module via a script tag
https://pyscript.github.io/docs/2024.2.1/user-guide/configuration/#javascript-modules

<!-- Index.html -->
<py-config>
[js_modules.main]
"./mymod.js" = "mymod"
</py-config>
<script type="py">
from pyscript.js_modules import mymod
print(f"Hello {mymod.name}, my favorite number is {mymod.number}")
</script>
//mymod.js
export const name = 'ric';
export const number = 42;











zipfile in the standard library to unpack it

[files] - if we automatically unpack zip files, how do we handle the case where a use wants to include a zip-file as-is?

unpack:folder could be already a folder ... rather than a prefix then, I'd consider a suffix ... "/url/folder.zip" = "./folder/*" to define where to extract content ... it's true that theoreticlaly a file or folder could also be named ./folder/* but I suspet that's an extremely edge case and it looks for troubles out of any path convention. (edited)./folder/* - edit it was me forgetting the ` around ... 
/ or /* makes sense
/*.
Currently we get a file called "*" which can be opened and unzipped from python.
https://pyscript.com/@szabolcsdombi/zip-test/latest
i don't think it would disrupt anyone's existing code if the archive would have been unpacked instead.
i now like the /* ending more. (edited)
"source.txt" = "./folder/" simplifies the result as ./folder/source.txt so just the trailing / is not enough, it was this Discrod incapable of dealing with my Markdown input, I always meant ./folder/* as special meaning for .zip source files only and nothing else ... we can then consider .tar.gz and stuff but let's move one step per time here ... if it works with .zip it might work with others but the more formats we handle, the least MicroPython is likely able to catch up ... @Jeff Glass do you know if mp can handl zip from its package remote repo? 

"source.txt" = "./folder/" simplifies the result as ./folder/source.txt so just the trailing / is not enough, it was this Discrod incapable of dealing with my Markdown input, I always meant ./folder/* as special meaning for .zip source files only and nothing else ... we can then consider .tar.gz and stuff but let's move one step per time here ... if it works with .zip it might work with others but the more formats we handle, the least MicroPython is likely able to catch up ... @Jeff Glass do you know if mp can handl zip from its package remote repo? uzlib is as close as it comes, which can do zlib and gzip but not generic zip

uzlib is as close as it comes, which can do zlib and gzip but not generic zip .tar.gz or .zip with structure .. I have successfully implemented packages extractor on pyodide though, and tested it works as expected ... not sure we should move forward but maybe that's welcome for more complex scenario, big zips and MicroPython likely don't like each other anyway ... thoughts? /cc @ntoll.tar.gz entries ... not sure though, the fact it has no updates since 2016 looks sketchy to me https://pypi.org/project/micropython-utarfile/

.tar.gz entries ... not sure though, the fact it has no updates since 2016 looks sketchy to me https://pypi.org/project/micropython-utarfile/ 

unpack:folder could be already a folder ... rather than a prefix then, I'd consider a suffix ... "/url/folder.zip" = "./folder/*" to define where to extract content ... it's true that theoreticlaly a file or folder could also be named ./folder/* but I suspet that's an extremely edge case and it looks for troubles out of any path convention. (edited)/** would be more explicit, or even /**/* ... although the /* looks fine to me. (edited)





















.tar.gz or .zip with structure .. I have successfully implemented packages extractor on pyodide though, and tested it works as expected ... not sure we should move forward but maybe that's welcome for more complex scenario, big zips and MicroPython likely don't like each other anyway ... thoughts? /cc @ntoll 

















Uncaught SyntaxError: Unexpected token 'export' You can see these things for yourself. Do you know Chrome browser or firefox has a debugger. Once again - out of the scope of this discord chat server to explain how to use the Browser. I think you need to do quite a bit more research. I wish you luck. I still strongly suggest you follow the approach I have outlined.





















pyodide,ffi,create_prosy to wrap it, for Python to JS object literals use pyodide.ffi.to_js and pass js.Object.fromEntries as dict_converter option. We're actively trying to make this as smooth as posible as we speak! index.html I created var config within script tags as shown before, but leaving step undefined. I edit this in pyscript using window.config.step = create_proxy(step_function) the step_function has two arguments row, which is the same as in JS and parserwhich seems to be implicit in JS. step_function is a python function, which is what I wanted. What didn't work for me was to pause or abort the parser even though I was on the main thread 

Main function Error: input() doesn't work when PyScript runs in the main thread.
For pyscript the best approach would be adding an input box and then using the @when decorator to invoke the function, this section of the docs might help https://pyscript.github.io/docs/2024.2.1/user-guide/builtins/#pyscriptwhen

.zip too (and only zip). (edited)


















import micropip
micropip.install(
'https://files.pythonhosted.org/packages/eb/f5/3ea71e974dd0117b95a54ab2c79d781b4376d257d91e4c2249605f4a54ae/pyhfst-1.2.0-py2.py3-none-any.whl'
)
#import hfst
import regex
import pyhfst
# ... the rest of the code
edit you should try removing pyhfst from your config too (edited)

import micropip
micropip.install(
'https://files.pythonhosted.org/packages/eb/f5/3ea71e974dd0117b95a54ab2c79d781b4376d257d91e4c2249605f4a54ae/pyhfst-1.2.0-py2.py3-none-any.whl'
)
#import hfst
import regex
import pyhfst
# ... the rest of the code
edit you should try removing pyhfst from your config too (edited)micropip to install packages, we don't interfere with that part in particular https://github.com/pyscript/polyscript/blob/main/esm/interpreter/pyodide.js#L98 (edited)




async flagged: see here: https://pyscript.github.io/docs/2024.2.1/user-guide/first-steps/











js.fetch instead? 

js.fetch instead? 

js.fetch instead? 

def fetch(url, method="GET"):
from js import XMLHttpRequest
xhr = XMLHttpRequest.new(method, url, False)
xhr.send(None)
return xhr.responseText # or response





display not working? (edited)

display not working? (edited)

def fetch(url, method="GET"):
from js import XMLHttpRequest
xhr = XMLHttpRequest.new(method, url, False)
xhr.send(None)
return xhr.responseText # or response 

display not working? (edited)
<script>
import * as Plot
function plotter() {
const plot = Plot.rectY({length: 10000}, Plot.binX({y: "count"}, {x: Math.random})).plot();
const div = document.querySelector("#myplot");
div.append(plot);
}
</script>
<script type="py">
from pyscript import window, document
class Plotter:
def __init__(self):
self.plot = None
# Accessing JavaScript Plot object
def graph(self):
window.plotter()
plot_ths = Plotter()
plot_ths.graph()
</script> (edited)




<script>
import * as Plot
function plotter() {
const plot = Plot.rectY({length: 10000}, Plot.binX({y: "count"}, {x: Math.random})).plot();
const div = document.querySelector("#myplot");
div.append(plot);
}
</script>
<script type="py">
from pyscript import window, document
class Plotter:
def __init__(self):
self.plot = None
# Accessing JavaScript Plot object
def graph(self):
window.plotter()
plot_ths = Plotter()
plot_ths.graph()
</script> (edited)






<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>






<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script> 







Access-Control-Allow-Origin localhost header
I've attached both my page and the config which was successfully loading and using the wheel, with the exact same url as is giving an error from micropip.
the question: is there anything I should be doing differently to get micropip to work the same as through packages in config? am I loading it wrong? is there another solution? is this a question I should be asking piodide instead?




pyttsx4 etc...)

Access-Control-Allow-Origin localhost header
I've attached both my page and the config which was successfully loading and using the wheel, with the exact same url as is giving an error from micropip.
the question: is there anything I should be doing differently to get micropip to work the same as through packages in config? am I loading it wrong? is there another solution? is this a question I should be asking piodide instead? 

pyttsx4 etc...) 










pytest in https://pyscript.com was merely a question of calling pytest.main() which I found at https://docs.pytest.org/en/stable/how-to/usage.html#calling-pytest-from-python-code
To run the pytests background worker connected to a terminal do:
<script type="py" config="./pyscript.toml" terminal worker>
import pytest
pytest.main()
</script>
All the file naming for pytest discover, plus the __init__.py files, plus the [files] section of pyscript.toml are required but it work for me!
Also see: https://pyscript.com/@antocuni/pytest-in-pyterminal (edited)

@pages.get("/", response_class=HTMLResponse)
async def index(
) -> HTMLResponse:
"""Base Route for redirect"""
html = (
"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- ================================================================================== -->
<link defer rel="stylesheet" href="/static/index.css" />
<script defer type="module" src="/packages/pyscript/core.js"></script>
<!-- ================================================================================== -->
<title>redact</title>
</head>
<body>
<!-- ==================================================== -->
<py-terminal id="py-out"></py-terminal>"""
f"<script type='py' src='/web/app.py' config='/web/config/config.toml'></script>"
f"</body>"
f"</html>"
)
return HTMLResponse(html, media_type="text/html", status_code=200)

FUN pyscript I demonstrated an app where I have dozens of images that I want to be clickable.
Normally one would use @pyscript.when decorator to statically add an on_click() function. Is there a recommended way to dynamically add/remove an on_click() function to dozens of objects at runtime?
https://pyscript.github.io/docs/2024.3.1/user-guide/builtins/#pyscriptwhen
import pyscript on "py-editor"?
click) and the selector (e.g. #my_id). The docs (https://pyscript.github.io/docs/2024.3.1/user-guide/builtins/#pyscriptwhen) explain that the selector can be any valid CSS selector. So, if you have a collection of objects that have the same CSS class, you can just use .myclass as the selector. The story around removing such event handling is a tad more complicated (the @when is convenient usually because folks only want to add).
Under the hood, if you're using Pyodide as the runtime, Pyodide's add_event_listener wrapper around the JS addEventListener function is used to hook things together (see: https://pyodide.org/en/stable/usage/api/python-api/ffi.html#pyodide.ffi.wrappers.add_event_listener). There is a corresponding remove_event_listener wrapper function in Pyodide too: https://pyodide.org/en/stable/usage/api/python-api/ffi.html#pyodide.ffi.wrappers.remove_event_listener.
If you're using MicroPython we use the standard JS addEventListener under the hood. There is, of course, the removeEventListener function too (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener) but you'll need a reference to the handling function in order to remove it from the desired element/event context.
Does this help..?

import pyscript on "py-editor"? type="py" or type="mpy" and indeed the py-editor is the cleanest interpreter you can get right now and it shares nothing with the surrounding scripts ... it should be possible to use the main thread to reference modules in there with or without the editor (it's an environment a part, always) so maybe that could work? what in particular do you need there, if I might ask?
response = call_api()
raw_response = json.dumps(response)
return f"""
<script type="py-editor" env="env" setup>
import json
raw = r"""{raw_response}"""
response = json.loads(raw)
</script>
<script type="py-editor" env="env">
</script>
"""
Still hacky, but maybe less hacky, and it works 

response = call_api()
raw_response = json.dumps(response)
return f"""
<script type="py-editor" env="env" setup>
import json
raw = r"""{raw_response}"""
response = json.loads(raw)
</script>
<script type="py-editor" env="env">
</script>
"""
Still hacky, but maybe less hacky, and it works setup feature unlocked you /cc @ntoll but I still think expecting pyscript module in a py-editor might be asked more and more as feature ... there's quite some work to do but it will be on the radar / pipeline







from pyscript import document, window
from js import consolefrom js import... always grabs from the current global namespace, whether worker or main thread. But if you import window or document from the pyscript package, you always get a reference to the main thread's window or document, whether you're running in a worker or not










npx mini-coi ./ to bootstrap a server that allows that target folder to server the right headers. npx is provided by npm package, I think you might be able to install it if that's not in there already. (edited)


mini-coi.js in your project folder and include it directly with a script tag https://github.com/WebReflection/mini-coi


<script type='py'>....



npx mini-coi ./ to bootstrap a server that allows that target folder to server the right headers. npx is provided by npm package, I think you might be able to install it if that's not in there already. (edited)









worker to the script tag (to make interactive terminal work) it doesn't even attempt to load the wheel






1

files section to copy it from a URL to a location on the filesystem)

files - which works - and then install it with micropip but that seems to not be able to handle emfs:// (also there's no guarantee it would attempt that only after the file is available, I suspect).
so then I tried requesting the file with files and then installing it with packages pointing at the package with emfs, and that raised a cors error. or rather a "an error occured which could be cors", to paraphrase.
oh I also tried manually starting a worker to initiate the terminal after importing the package but I couldn't get that to work either.
anyhow I'm gonna try mini-coi now
<script type="py" config='{"packages":["./dist/floofbytes-2024.0.2-py3-none-any.whl"]}' terminal >
from pyscript import document, display
term = document.querySelector('script[terminal]').terminal
term.resize(90, 32)
display("resized")
from floofbytes.core import Game, examine
me = Game().get_player()
display(examine(me))
import code
code.interact()
</script>
I get output from my package displayed, and as expected I get Exception: input() doesn't work when PyScript runs in the main thread.
if I add worker to the script tag I get no errors (even in the browser console) and no output at all in the console and my .whl file was never requested according to the network monitor.
this is with mini-coi.js added (it's loading fine from localhost). adding it didn't change the behaviour at all.
I think I'll have to load all my python files individually for now. not that I actually have more than one but this is just proof of concept for a potential project structure.
floofbytes - that had me giggling like a 2yo. 

floofbytes - that had me giggling like a 2yo. 

<script type="py" config='{"packages":["./dist/floofbytes-2024.0.2-py3-none-any.whl"]}' terminal >
from pyscript import document, display
term = document.querySelector('script[terminal]').terminal
term.resize(90, 32)
display("resized")
from floofbytes.core import Game, examine
me = Game().get_player()
display(examine(me))
import code
code.interact()
</script>
I get output from my package displayed, and as expected I get Exception: input() doesn't work when PyScript runs in the main thread.
if I add worker to the script tag I get no errors (even in the browser console) and no output at all in the console and my .whl file was never requested according to the network monitor.
this is with mini-coi.js added (it's loading fine from localhost). adding it didn't change the behaviour at all.
I think I'll have to load all my python files individually for now. not that I actually have more than one but this is just proof of concept for a potential project structure. 


npx mini-coi . to bootstrap a NodeJS server with the right headers then reach that localhost and see if you have any better result would be my first advice.


http://localhost:PORT/dist/wheel/thingy.whl





Access-Control-Allow-Origin localhost header
I've attached both my page and the config which was successfully loading and using the wheel, with the exact same url as is giving an error from micropip.
the question: is there anything I should be doing differently to get micropip to work the same as through packages in config? am I loading it wrong? is there another solution? is this a question I should be asking piodide instead? 

* in our case




<py-script> as custom element is basically deprecated because it suffers DOM parsing which is full of unexpected surprises so you better use <script type="py"> or <script type="mpy"> and be always safe from undesired errors in code you put in there, as there's no DOM parsing involved ever by standard contract.








<py-script> as custom element is basically deprecated because it suffers DOM parsing which is full of unexpected surprises so you better use <script type="py"> or <script type="mpy"> and be always safe from undesired errors in code you put in there, as there's no DOM parsing involved ever by standard contract. 




http://localhost:PORT/dist/wheel/thingy.whl <script type="py" config='{"packages":["http://localhost:80/dist/floofbytes-2024.0.2-py3-none-any.whl"]}' worker terminal >
this loads the package AND shows the terminal!
first time i've seen both work together. doesn't bind it to a hostname in the way CORS wants


. doesn't bind it to a hostname in the way CORS wants * (all) so that even the relative path might work ... however, there is a special config flag to specify your base url for things, including packages, and with the inline conifg it defaults to the current URL but if you move that config elsewhere (as external .json or .toml file) you should see also relative paths working even from a worker. (edited)

* (all) so that even the relative path might work ... however, there is a special config flag to specify your base url for things, including packages, and with the inline conifg it defaults to the current URL but if you move that config elsewhere (as external .json or .toml file) you should see also relative paths working even from a worker. (edited)* as shown to me above, however I couldn't get it to change.
Thanks for the info on the config flag. I do usually use an external config, I just moved it inline to it was simpler to show.
config providing fully qualified URL accordingly with your location.href ... this is an ugly way to do it, but there are more elegant one.
<!doctype html>
<html>
<head><!-- your head things --></head>
<body>
<script>document.write(`<py-config>{"packages":["${location.protocol}//${location.host}/dist/floofbytes-2024.0.2-py3-none-any.whl"]}</py-config>`)</script>
<!-- the rest of your body -->
<script type="py" worker terminal>
import that-wheel # or your code in here
</script>
</body>
</html> (edited)
[js_modules.main]
"https://unpkg.com/react@18/umd/react.development.js" = "react"
"https://unpkg.com/react-dom@18/umd/react-dom.development.js" = "react_dom"
but importing React, ReactDOM and accessing create_root did not work :/
from pyscript.js_modules import react, react_dom
# react is a jsobj, and not usable
# I would also have to access
# import { createRoot } from 'react-dom/client';
# no clue how that could work :/
# goal:
from pyscript import document
# TODO somehow import create_root from creat-dom/client
# TODO somehow import React and ReactDOM
document.body.innerHTML = '<div id="app"></div>';
root = createRoot(document.getElementById('app'));
root.render(<h1>Hello, world</h1>); (edited)


pyscript package in a py-editor?
<script src="mini-coi.js"></script>
<script type="module" src="https://pyscript.net/releases/2024.3.2/core.js"></script>
<script type="py-editor" env="one">
import pyscript
</script>
ModuleNotFoundError: No module named 'pyscript'import os
os.listdir(".")
[]

pyscript package in a py-editor?
<script src="mini-coi.js"></script>
<script type="module" src="https://pyscript.net/releases/2024.3.2/core.js"></script>
<script type="py-editor" env="one">
import pyscript
</script>
ModuleNotFoundError: No module named 'pyscript' 

import pyscript I haven't seen any concrete use case ... even the document is complicated in there to be honest because they might mess up the editor, but also editors are always in workers, which adds complexity.

setup py-editors, thereโs some setup I would find useful to use the pyscript module for. Will leave details over in GitHub


mpy-editor and py-editor https://github.com/pyscript/pyscript/pull/2010


















code.interact() works there but I think there should be a way to have what you are asking for ... it is indeed simulating a tty but I need to learn a bit more about what you are after, thank you!
[[fetch]]
files = ["./worker1.py"]





<script type="module" src="https://pyscript.net/releases/2024.3.2/core.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.3.2/core.css">
<py-config>
packages=['matplotlib', 'numpy']
</py-config>
<script type="py">
import matplotlib.pyplot as plt
import numpy as np
from pyscript import display
x = np.linspace(0, 2 * np.pi, 100)
plt.plot(x, np.sin(x))
display(plt)
</script> (edited)

py-env became py-config and gained some new features/syntaxdisplay()<py-script>, but we recommend <script type="py"> to avoid a nasty class of parsing errors the browser can trip on



onmessage and postMessage available in worker api. Is this for making Web Workers ? Is the sync() designed for Service Workers? Is sync doing this kind of thing: addEventListener('sync', function (event) {}) ?
Any guidance docs you can point us at. I am guessing the new fetch are designed to enable Service workers to do Background syncs ? What's the plan ? Thanks. (edited)
sync but how do I send information from main to the worker for it to work on ?
from pyscript import display, document
from pyscript.ffi import create_proxy
class App:
def __init__(self):
"""Wire up your event listeners in here..."""
self.when("click", "#click-me", self.when_click_me_clicked)
def when(self, event_type, selector, method):
"""
Listen for "event_type" events on all elements that match the
specified css selector.
"""
for element in document.querySelectorAll(selector):
element.addEventListener(event_type, create_proxy(method))
def when_click_me_clicked(self, event):
"""Called when the click-me button is pressed."""
display("Clicked!", self)
app = App() (edited)



add_event_listener() can I specify arguments for the python function I call inside it? I currently have a monolithic function that manages a file upload and carries out operations on the file, but I would like to break it into pieces so that there is a function that handles the file upload, and then with subsequent button clicks, the user decides which operations to apply.
This feeds into a more general (and much lower priority...feel free to ignore it) confusion about how arguments and variables are used in the pyscript/pyodide examples I have seen. For the functions that do a lot of the work between the 'website side' javascript and the 'developer side' python, the function definitions often include arguments that are not referenced in the body of the function ... while variables that I would want to set up as arguments are just referred to in the function body, all while the function itself does not return a value that would enable you to chain functions together . For instance, here (from https://pyscript.recipes/2024.1.1/basic/file-download/), there is never a reference to any *args ... while the variable 'data' is defined outside of it, and directly referenced in the function body:
data = "Hello world, this is some text."
def downloadFile(*args):
encoded_data = data.encode('utf-8')
my_stream = io.BytesIO(encoded_data)
js_array = Uint8Array.new(len(encoded_data))
js_array.assign(my_stream.getbuffer())
file = File.new([js_array], "unused_file_name.txt", {type: "text/plain"})
url = URL.createObjectURL(file)
hidden_link = document.createElement("a")
hidden_link.setAttribute("download", "my_other_file_name.txt")
hidden_link.setAttribute("href", url)
hidden_link.click()
add_event_listener(document.getElementById("download"), "click", downloadFile) (edited)







worker.sync.hello = hello again. I have got it working several times. so the `worker.sync.function_name calls the function in the worker




<!-- index.html -->
<script type="module" src="https://pyscript.net/releases/2024.3.2/core.js"></script>
<label for="seed">Seed</label>
<input type="text" name="seed" id="seed">
<br><label for="iterations">Iterations</label>
<input type="text" name="iterations" id="iterations">
<br><button id="btn">Calculate</button>
<div id="result"></div>
<script type="module">
import { PyWorker } from 'https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.11/+esm';
const { sync } = await PyWorker(
'./worker.py',
{ config: { sync_main_only: true }}
);
document.getElementById('btn').addEventListener('click', async () => {
const seed = parseInt(document.getElementById("seed").value)
const iters = parseInt(document.getElementById("iterations").value)
const result = await sync.pseudorandom(seed, iters)
document.getElementById("result").innerText += result + "\n"
})
</script>
#worker.py
from pyscript import sync
def pseudorandom(seed: int, iters: int):
"""Linear congruential generator. Parameters borrowed from POSIX and are probably bad"""
modulus = 2**48
a = 25214903917
increment = 11
for _ in range(iters):
seed = (a * seed + increment) % modulus
return seed % (2 ** 47)
sync.pseudorandom = pseudorandom





PyWorker in the PyScript package...
worker.sync.draw_floats = draw_floats and adding some args


sync_main_only parameter though, to ideally be able to spawn PyWorkers from PyScript without SharedArrayBuffer access<py-config>
sync_main_only = true
</py-config>
<script type="py">
from pyscript import PyWorker
from pyscript.ffi import to_js
options = to_js({"type": "pyodide"}) # Should _this_ have sync_main_only config'd?
p = PyWorker('./foo.py', options)
</script> (edited)



sync_main_only parameter though, to ideally be able to spawn PyWorkers from PyScript without SharedArrayBuffer access worker_options = ffi.to_js({"type": "pyodide", "config": {"sync_main_only": True}}) (edited)

worker_options = ffi.to_js({"type": "pyodide", "config": {"sync_main_only": True}}) (edited)

worker_options = ffi.to_js({"type": "pyodide", "config": {"sync_main_only": True}}) (edited)

onmessage and postMessage available in worker api. Is this for making Web Workers ? Is the sync() designed for Service Workers? Is sync doing this kind of thing: addEventListener('sync', function (event) {}) ?
Any guidance docs you can point us at. I am guessing the new fetch are designed to enable Service workers to do Background syncs ? What's the plan ? Thanks. (edited)sync is a namespace where you expose utilities, as functions, from either the worker world or he main one, and you can then invoke these utilities from the outer world either synchronously (from worker) or awaiting results (from main). There's no sync event as you can expose hundreds utilities and that would make little sense + the onmessage is thever because you effectively deal with a worker instance, it's just augmented with the sync utility but it is already a Worker 100%. Service Worker is nowhere used in the project except for mini-coi but it's completely unrelated and used only to enable/allow headers needed for the SharedArrayBuffer primitive.


__terminal__ attribute is a reference to the xtermjs terminal itself. You can use resize() to change the rows/columns at runtime. Example here: https://jeff.glass/post/whats-new-pyscript-2024-q1/#terminal-attribute

__terminal__ attribute is a reference to the xtermjs terminal itself. You can use resize() to change the rows/columns at runtime. Example here: https://jeff.glass/post/whats-new-pyscript-2024-q1/#terminal-attribute 





<!-- Short JS script to extract "year" query arg, if given -->
<script>
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
var urlYear = urlParams.get("year")
</script>
<script type="py">
from operator import attrgetter
from pyscript import display, HTML
import pyscript
from pyodide.http import open_url
import matplotlib.pyplot as plt
import littletable as lt
# use littletable to import data from remote CSV URL;
# transforms convert data for those attributes, all others are loaded as strs
url = "https://raw.githubusercontent.com/datasets/s-and-p-500/master/data/data.csv"
stock_data = lt.csv_import(
open_url(url),
transforms={
"Date": lt.Table.parse_date("%Y-%m-%d"),
"SP500": float,
}
)
# add a computed field to summarize or fetch by year
get_year = attrgetter("Date.year")
stock_data.add_field("Year", get_year)
# extract Javascript variable if a query arg `year=####` was part of the URL;
# if given, filter the retrieved data for just this particular year
year = pyscript.window.urlYear
if year is not None:
stock_data = stock_data.where(Year=int(year))
Or have I just reinvented something that is already in the Pyscript library? (I'm also trying to see if using my littletable package instead of pandas does any good.)
<script type="py">
# ... Some lines omitted
# add a computed field to summarize or fetch by year
get_year = attrgetter("Date.year")
stock_data.add_field("Year", get_year)
# vvvv Get the Querys within PyScript vvvvv
# if given, filter the retrieved data for just this particular year
def getQueryYear() -> str | None:
queryString = pyscript.window.location.search;
urlParams = pyscript.window.URLSearchParams.new(queryString);
return urlParams.get("year")
year = getQueryYear()
if year is not None:
stock_data = stock_data.where(Year=int(year))
print(f"Got data for year {year}")
else:
print("No query parameter found")
</script>

<!-- Short JS script to extract "year" query arg, if given -->
<script>
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
var urlYear = urlParams.get("year")
</script>
<script type="py">
from operator import attrgetter
from pyscript import display, HTML
import pyscript
from pyodide.http import open_url
import matplotlib.pyplot as plt
import littletable as lt
# use littletable to import data from remote CSV URL;
# transforms convert data for those attributes, all others are loaded as strs
url = "https://raw.githubusercontent.com/datasets/s-and-p-500/master/data/data.csv"
stock_data = lt.csv_import(
open_url(url),
transforms={
"Date": lt.Table.parse_date("%Y-%m-%d"),
"SP500": float,
}
)
# add a computed field to summarize or fetch by year
get_year = attrgetter("Date.year")
stock_data.add_field("Year", get_year)
# extract Javascript variable if a query arg `year=####` was part of the URL;
# if given, filter the retrieved data for just this particular year
year = pyscript.window.urlYear
if year is not None:
stock_data = stock_data.where(Year=int(year))
Or have I just reinvented something that is already in the Pyscript library? (I'm also trying to see if using my littletable package instead of pandas does any good.) urllib from the Python standard library, if you wanted to:
def getQueryYear() -> str | None:
import urllib.parse as parse
queryString = str(pyscript.window.location)
urlQuery = parse.urlparse(queryString).query
queryDict = parse.parse_qs(urlQuery)
return queryDict['year'][0] if 'year' in queryDict else None (edited)





<py-script> or <script type='py'> is a separate HTML tag that executes Python


<script type="py">
from pyscript import window, document
def get_room_types():
room_types = ["Computers", "Labs", "Computers"]
print (room_types)
return room_types
selectElement = document.getElementById('room-type-select')
for roomType in get_room_types():
option = document.createElement('option')
option.value = roomType
option.textContent = roomType
selectElement.appendChild(option)
</script>pyscript.window is a proxy to the JavaScript global namespace; pyscript.document is a proxy to the DOM document

myapp.py, you can do <script type="py" src="myapp.py"></script>



py-[event] syntax - any HTML tag that has an attribute like py-click or py-mouseover will be hooked up to the function with the value of that attribute:
<button py-click="foo">Click Me!</button>
<script type="py">
from pyscript import display
def foo(evt):
display("Hey you clicked the button!")
</script>

@when decorator, which takes an event type and a css selector:
<button>One</button>
<button>Two</button>
<script type="py">
from pyscript import display, when
@when("click", "button")
def foo(evt):
display(f"Hey you clicked the button with text '{evt.target.innerText}'")
</script>



myapp.py file directly in your browser, does it show/download that file?

fetch()myapp.py file isn't actually being served

python3 -m http.server in the folder in questionlocalhost:8000)



python -m http.server 1234 --bind 127.0.0.1









packages = ["banglanltk"] and in main.py
import banglanltk as bn
from pyscript import document
everything was well and good. But then, when I changed it to packages = ["banglanltk", "collections"] and
import banglanltk as bn
from pyscript import document
from collections import defaultdict, Counter
all the buttons in the html page has gone inactive suddenly.
Any suggestions regarding how to deal with this? Thanks in advance. (edited)

packages = ["banglanltk"] and in main.py
import banglanltk as bn
from pyscript import document
everything was well and good. But then, when I changed it to packages = ["banglanltk", "collections"] and
import banglanltk as bn
from pyscript import document
from collections import defaultdict, Counter
all the buttons in the html page has gone inactive suddenly.
Any suggestions regarding how to deal with this? Thanks in advance. (edited)collections in your packages key - since collections in the standard library, it's installed by default and can just be imported


collections in your packages key - since collections in the standard library, it's installed by default and can just be imported 









npm i @ericblade/quagga2. There are 17 other projects in the npm registry using @ericblade/quagga2.










"BarcodeDetector" in globalThis is false in both Chrome and MSEdge

"BarcodeDetector" in globalThis is false in both Chrome and MSEdge 












evil.com really necessary as example? <a href="..."> instead although I am not sure how XTerm.js would handle that, but maybe it's worth an investigation.{x} in there 


<py-config>
[js_modules.main]
"https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0.11.0/+esm" = "weblinks"
</py-config>
<script type="py" terminal>
from pyscript import js_modules
addon = js_modules.weblinks.WebLinksAddon.new()
__terminal__.loadAddon(addon)
print("Check out https://google.com")
</script>

echo works the same) maybe we could have this in too? as @Jeff Glass showed it's pretty trivial to bring in your addon though, so maybe not ... thoughts? /cc @ntoll





<h1> Database creation and insert</h1>
<button py-click="create_database"> Create Database </button>
<div id="creation_ok"></div>
<button py-click="insert_person"> Insert Person </button>
<div id="insert_ok"></div>
<button py-click="query_person"> Query Person </button>
<div id="query_ok"></div>
<script type="py" src="{{ url_for('pyscriptapp.static', filename='db_service.py') }}" config="{{ url_for('pyscriptapp.static', filename='database.json') }}"></script>
<a href="{{ url_for('pyscriptapp.pyscript_second') }}">Back</a>
and it returns the inserted record
however when i route to pyscript_second.html(basicly a copy of the first) and just try to query the person, it cant find a table named Person
So my question is, how could i either keep the database persistent over a route or should i/do i need to keep everything on one page and do what i want to do all locally until i am finished with the database?

<h1> Database creation and insert</h1>
<button py-click="create_database"> Create Database </button>
<div id="creation_ok"></div>
<button py-click="insert_person"> Insert Person </button>
<div id="insert_ok"></div>
<button py-click="query_person"> Query Person </button>
<div id="query_ok"></div>
<script type="py" src="{{ url_for('pyscriptapp.static', filename='db_service.py') }}" config="{{ url_for('pyscriptapp.static', filename='database.json') }}"></script>
<a href="{{ url_for('pyscriptapp.pyscript_second') }}">Back</a>
and it returns the inserted record
however when i route to pyscript_second.html(basicly a copy of the first) and just try to query the person, it cant find a table named Person
So my question is, how could i either keep the database persistent over a route or should i/do i need to keep everything on one page and do what i want to do all locally until i am finished with the database? 


















Listener added for a synchronous 'DOMSubtreeModified' DOM Mutation Event. This event type is deprecated (https://w3c.github.io/uievents/#legacy-event-types) and work is underway to remove it from this browser.
fontname = 'Siyam Rupali' , it's being done, but not sure how to do this in PyScript.

fontname = 'Siyam Rupali' , it's being done, but not sure how to do this in PyScript. 











evil.com really necessary as example? <a href="..."> instead although I am not sure how XTerm.js would handle that, but maybe it's worth an investigation. 


<py-config>
[js_modules.main]
"https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0.11.0/+esm" = "weblinks"
</py-config>
<script type="py" terminal>
from pyscript import js_modules
addon = js_modules.weblinks.WebLinksAddon.new()
__terminal__.loadAddon(addon)
print("Check out https://google.com")
</script> 

Listener added for a synchronous 'DOMSubtreeModified' DOM Mutation Event. This event type is deprecated (https://w3c.github.io/uievents/#legacy-event-types) and work is underway to remove it from this browser. DOMSubtreeModified string anywhere in my projects ... it's either some 3rd party script or your extensions doing something weird, imho.





fontname = 'Siyam Rupali' , it's being done, but not sure how to do this in PyScript. 









ModuleNotFoundError: The module 'networkx' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("networkx") in Python, or
await pyodide.loadPackage("networkx") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
I already have networkx installed on my system. I modified pyscript.toml to have networkx in packages, and restarted the python http.server but still getting the same error
And in python, import micropip gives ModuleNotFoundError. How can I get this to work

ModuleNotFoundError: The module 'networkx' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("networkx") in Python, or
await pyodide.loadPackage("networkx") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
I already have networkx installed on my system. I modified pyscript.toml to have networkx in packages, and restarted the python http.server but still getting the same error
And in python, import micropip gives ModuleNotFoundError. How can I get this to work 



























<script type="py" terminal async>
import asyncio
print("Clearing the screen in:")
for i in range(5, 0, -1):
print(i)
await asyncio.sleep(1)
print('\033[2J') # clear terminal
print('\033[H', end = "") # move to home position, don't print a newline
print("You should only see this")
</script>

<style>
.xterm .xterm-viewport {
background: #00F !important;
}
</style>
<script type="py" terminal>
print("Hello, world!")
</script>

<script type="py" terminal async>
import asyncio
print("Clearing the screen in:")
for i in range(5, 0, -1):
print(i)
await asyncio.sleep(1)
print('\033[2J') # clear terminal
print('\033[H', end = "") # move to home position, don't print a newline
print("You should only see this")
</script> __terminal__.clear():
<script type="py" terminal async>
import asyncio
print("Clearing the screen in:")
for i in range(5, 0, -1):
print(i)
await asyncio.sleep(1)
__terminal__.clear()
print("You should only see this")
</script>
That's not something PyScript added btw - the __terminal__ global is a direct reference to the underlying xtermjs Terminal object

__terminal__.clear():
<script type="py" terminal async>
import asyncio
print("Clearing the screen in:")
for i in range(5, 0, -1):
print(i)
await asyncio.sleep(1)
__terminal__.clear()
print("You should only see this")
</script>
That's not something PyScript added btw - the __terminal__ global is a direct reference to the underlying xtermjs Terminal object <script type="py" terminal>
print("hello, world")
</script>
<script type="py">
from pyscript import document
def clearTerm(evt):
terminal_element = document.querySelector("script[type='py'][terminal]")
terminal_element.terminal.clear()
</script>
<button py-click="clearTerm">Click to Clear</button>


<script type="py" terminal>
print("hello, world")
</script>
<script type="py">
from pyscript import document
def clearTerm(evt):
terminal_element = document.querySelector("script[type='py'][terminal]")
terminal_element.terminal.clear()
</script>
<button py-click="clearTerm">Click to Clear</button> 
?py to use pyodide instead https://webreflection.github.io/coincident/test/pyterminal/?py (the default is ?mpy)


The FetchEvent for "https://cdn.plot.ly/plotly-2.31.1.min.js" resulted in a network error response: Cross-Origin-Resource-Policy prevented from serving the response to the client.
Has anyone experienced this? Any ideas on how to solve it? Idk if it has any effect, but I'm using mini coi, which I expected to take care of all cross-origin related stuff

The FetchEvent for "https://cdn.plot.ly/plotly-2.31.1.min.js" resulted in a network error response: Cross-Origin-Resource-Policy prevented from serving the response to the client.
Has anyone experienced this? Any ideas on how to solve it? Idk if it has any effect, but I'm using mini coi, which I expected to take care of all cross-origin related stuff https://esm.run/plotly instead of home made CDNs with missing headers to be usable

https://esm.run/plotly instead of home made CDNs with missing headers to be usable 


<style>
.xterm .xterm-viewport {
background: #00F !important;
}
</style>
<script type="py" terminal>
print("Hello, world!")
</script> 


.xterm .xterm-viewport .terminal{
font-family: "gohu";
}
@font-face {
font-family: "gohu";
src: url("/assets/gohu.woff") format('woff');
}


.xterm .xterm-viewport .terminal{
font-family: "gohu";
}
@font-face {
font-family: "gohu";
src: url("/assets/gohu.woff") format('woff');
} __terminal__.option = ... to change the font family:
<style>
@font-face {
font-family: "gohu";
src: url("ResotE-Rose-89c1.woff") format('woff');
}
</style>
<script type="mpy" terminal>
from pyscript.ffi import to_js
__terminal__.options = to_js({"fontFamily": 'gohu'})
print("Hello, world!")
</script> .xterm-rows {
font-family: "gohu" !important;
}
to your stylesterminal.__options__



import pandas as pd
from io import BytesIO
# Assuming `df` is your DataFrame
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
data = {
'Column1': ['Value1', 'Value2'],
'Column2': ['Value3', 'Value4']
}
df = pd.DataFrame(data)
df.to_excel(writer, sheet_name='Sheet1')
writer.save() (edited)







HTML import has ben recently changed (like ... today) to not break on MicroPython, apologies for any inconvenience, it was not documented at all and you are the first user noticying it https://github.com/pyscript/pyscript/pull/2033

HTML import has ben recently changed (like ... today) to not break on MicroPython, apologies for any inconvenience, it was not documented at all and you are the first user noticying it https://github.com/pyscript/pyscript/pull/2033 



import pandas as pd
from io import BytesIO
# Assuming `df` is your DataFrame
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
data = {
'Column1': ['Value1', 'Value2'],
'Column2': ['Value3', 'Value4']
}
df = pd.DataFrame(data)
df.to_excel(writer, sheet_name='Sheet1')
writer.save() (edited)from js import Uint8Array, File, URL
from pyscript import document
import pandas as pd
filename = "myfile.xlsx"
def downloadFile(*args):
# Assuming `df` is your DataFrame
writer = pd.ExcelWriter(filename, engine='xlsxwriter')
data = {
'Column1': ['Value1', 'Value2'],
'Column2': ['Value3', 'Value4']
}
df = pd.DataFrame(data)
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
with open(filename, 'rb') as data:
my_stream = data.read()
js_array = Uint8Array.new(len(my_stream))
js_array.assign(my_stream)
file = File.new([js_array], "unused_file_name.xlsx", {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})
url = URL.createObjectURL(file)
hidden_link = document.createElement("a")
hidden_link.setAttribute("download", "my_other_file_name.xlsx")
hidden_link.setAttribute("href", url)
hidden_link.click()rb modeBufferedRandom, but I couldn't figure it out



BufferedRandom, but I couldn't figure it out 


display has an append=False option ... have you tried that?
click event..? (Rather than trying to manipulate the onclick attribute - which is generally frowned upon these days because "reasons").



click event..? (Rather than trying to manipulate the onclick attribute - which is generally frowned upon these days because "reasons"). 
my_element.addEventListener("click", create_proxy(my_function))
(Off the top of my head, please check)

create_proxy you can always do my_element.onclick = my_function as that binds the reference to a foreign Proxy and both interpreters are smart enough to never kill it from the runtime GC

ffi scene: https://github.com/pyscript/docs/pull/93 (edited)


py-repl class was deprecated / removed back in 2023.11.1

py-repl class was deprecated / removed back in 2023.11.1 





<py-script> tags, even if we encourage the usage of <script> instead because that's a code block, the former isn't and it easily leads to DOM parsing related issues.

from pyscript import document, window
canvas = document.getElementById("GameCanvas")
canvas.width = 320
canvas.height = 240
ctx = canvas.getContext("2d")
square = {
"x": 0,
"y": 32,
"w": 16,
"h": 16,
"color": "#FFAA00"
}
def update(timestamp=0):
ctx.fillStyle = "#000000"
ctx.fillRect(0, 0, 320, 240)
ctx.fillStyle = square["color"]
ctx.fillRect(square["x"], square["y"], square["w"], square["h"])
if square["x"] < 160:
square["x"] += 1
window.requestAnimationFrame(update)
window.requestAnimationFrame(update)



from pyscript import document, window
canvas = document.getElementById("GameCanvas")
canvas.width = 320
canvas.height = 240
ctx = canvas.getContext("2d")
square = {
"x": 0,
"y": 32,
"w": 16,
"h": 16,
"color": "#FFAA00"
}
def update(timestamp=0):
ctx.fillStyle = "#000000"
ctx.fillRect(0, 0, 320, 240)
ctx.fillStyle = square["color"]
ctx.fillRect(square["x"], square["y"], square["w"], square["h"])
if square["x"] < 160:
square["x"] += 1
window.requestAnimationFrame(update)
window.requestAnimationFrame(update) Uncaught Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callablefrom pyscript.ffi import create_proxy
# ...
@create_proxy
def update(timestamp=0):
ctx.fillStyle = "#000000"
ctx.fillRect(0, 0, 320, 240)
# ... (edited)

from pyscript import document, window
from pyscript.ffi import create_proxy
canvas = document.getElementById("GameCanvas")
canvas.width = 320
canvas.height = 240
ctx = canvas.getContext("2d")
square = {
"x": 0,
"y": 32,
"w": 16,
"h": 16,
"color": "#FFAA00"
}
@create_proxy
def update(timestamp=0):
ctx.fillStyle = "#000000"
ctx.fillRect(0, 0, 320, 240)
ctx.fillStyle = square["color"]
ctx.fillRect(square["x"], square["y"], square["w"], square["h"])
if square["x"] < 160:
square["x"] += 1
window.requestAnimationFrame(update)
window.requestAnimationFrame(update)
<link rel="stylesheet" href="https://pyscript.net/releases/2024.4.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.4.1/core.js"></script>
<canvas id="GameCanvas"></canvas>
<script type="py">
from pyscript import document, window
from pyscript.ffi import create_proxy
canvas = document.getElementById("GameCanvas")
canvas.width = 320
canvas.height = 240
ctx = canvas.getContext("2d")
square = {
"x": 0,
"y": 32,
"w": 16,
"h": 16,
"color": "#FFAA00"
}
@create_proxy
def update(timestamp=0):
ctx.fillStyle = "#000000"
ctx.fillRect(0, 0, 320, 240)
ctx.fillStyle = square["color"]
ctx.fillRect(square["x"], square["y"], square["w"], square["h"])
if square["x"] < 160:
square["x"] += 1
window.requestAnimationFrame(update)
window.requestAnimationFrame(update)
</script>2024.4.2 but either works
<!DOCTYPE html>
<html lang="fr">
<head>
<title>PyScript Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="./css/main.css">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css" />
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
</head>
<body>
<canvas id="GameCanvas"></canvas>
<script type="py" src="./main.py" config="./pyscript.toml"></script>
</body>
</html>
I changed with your code it works fine now 

this.viewerContent = this.sanitizer.bypassSecurityTrustHtml(`
${this.pythonREPLContent}
`);
console.log('sanitized latest code commit');
this.viewerContentSubject.next(this.viewerContent);
<div
*ngIf="viewerContent$ | ngrxPush as pythonCode"
[innerHTML]="pythonCode" ></div>
but when using <script type='py-editor'>, the code editor loads and renders the green go button but when the go button is pushed the below message is emitted in the chrome logs
MessageEvent {type: 'error', error: Error: Unable to use SharedArrayBuffer due insecure environment.
Please read requirements in MDN: hโฆ}
polyfills.js:1 Error: Unable to use SharedArrayBuffer due insecure environment.
Please read requirements in MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements
at 719ef878-2ecc-4b5c-9โฆdfe81dcde4a:2:28017
any ideas? (on how to circumvent this evident angular security thing) (edited)

this.viewerContent = this.sanitizer.bypassSecurityTrustHtml(`
${this.pythonREPLContent}
`);
console.log('sanitized latest code commit');
this.viewerContentSubject.next(this.viewerContent);
<div
*ngIf="viewerContent$ | ngrxPush as pythonCode"
[innerHTML]="pythonCode" ></div>
but when using <script type='py-editor'>, the code editor loads and renders the green go button but when the go button is pushed the below message is emitted in the chrome logs
MessageEvent {type: 'error', error: Error: Unable to use SharedArrayBuffer due insecure environment.
Please read requirements in MDN: hโฆ}
polyfills.js:1 Error: Unable to use SharedArrayBuffer due insecure environment.
Please read requirements in MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements
at 719ef878-2ecc-4b5c-9โฆdfe81dcde4a:2:28017
any ideas? (on how to circumvent this evident angular security thing) (edited)npx mini-coi . to bootstrap a server that enables worker attribute, or see the docs about it: https://docs.pyscript.net/2024.4.1/user-guide/workers/#http-headers

npx mini-coi . to bootstrap a server that enables worker attribute, or see the docs about it: https://docs.pyscript.net/2024.4.1/user-guide/workers/#http-headers 
app.UseCors(
options => options
.WithOrigins(allowedCORSOrigins.ToArray())
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.SetIsOriginAllowed(hostname => true)
);
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Cross-Origin-Opener-Policy", "same-origin");
context.Response.Headers.Add("Cross-Origin-Embedder-Policy", "credentialless");
context.Response.Headers.Add("Cross-Origin-Resource-Policy", "cross-origin");
await next();
});
if you get this wrong your spa components will load partially when they try to load assets from syncfusion and so forth
thanks (edited)
tileInput.addEventListener("scroll", create_proxy(tileScroll)) (edited)



window is actually scroll


mini-coi as example via npx or bun x ... example: npx mini-coi . starts a local server that enables SharedArrayBuffer. (edited)

mini-coi as example via npx or bun x ... example: npx mini-coi . starts a local server that enables SharedArrayBuffer. (edited)
<script type="mpy"> , python code get executed offline with no problem using the local interpreter defined in <mpy-config>. But if i use <script type="mpy-editor"> then the page will request blob/interpreter from internet, not the one told to use inside <mpy-config>.
How to force the browser to use local interpreter when using type="mpy-editor"? (edited)

<script type="mpy"> , python code get executed offline with no problem using the local interpreter defined in <mpy-config>. But if i use <script type="mpy-editor"> then the page will request blob/interpreter from internet, not the one told to use inside <mpy-config>.
How to force the browser to use local interpreter when using type="mpy-editor"? (edited)setup attribute and a config attribute pointing to the config in a file
setup attribute helps you provide a config ... that should do the trick as behind the scene it's all the same 



interpreter is ignored in there so here it is: https://github.com/pyscript/pyscript/pull/2043https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.26/dist/core.js for the JS script and https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.26/dist/core.css for the CSS link

https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.26/dist/core.js for the JS script and https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.26/dist/core.css for the CSS link 

code.interact() AFAIK but you can always drop that terminal, actually also invoking terminate() on the associated worker, and create a new one on demand when new code needs to be added. You probably need to keep track of the global references if you manage to pass these around but that's one way to try and see how far you could go. (edited)


fetch (as REST) that result and deal with it as JSON would be my answer ... all through pyscript.fetch, of course.


{
"interpreter": "http://localhost:8000/micropython/micropython.mjs"
}
If i use relative path it will not work:
{
"interpreter": "/micropython/micropython.mjs"
}
and the console will show an error: (edited)





{
"interpreter": "http://localhost:8000/micropython/micropython.mjs"
}
If i use relative path it will not work:
{
"interpreter": "/micropython/micropython.mjs"
}
and the console will show an error: (edited)



npx static-handler --coi ./public/ to start the server?

0.4.30 it solves already your case ... JS link https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.30/dist/core.js with CSS https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.30/dist/core.css (edited)




npx static-handler --coi ./public/ to start the server? 

0.4.30 it solves already your case ... JS link https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.30/dist/core.js with CSS https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.30/dist/core.css (edited)






<script type="py">
class Foo():
def __init__(self, name):
self.name = name
def click(self, evt):
print(f"{self.name} got a {evt.type} event!")
f = Foo('Jeff')
</script>
<button py-click="f.click">Click Me</button>

<script type="py">
class Foo():
def __init__(self, name):
self.name = name
def click(self, evt):
print(f"{self.name} got a {evt.type} event!")
f = Foo('Jeff')
</script>
<button py-click="f.click">Click Me</button> def sent_represent(event):
input_text = document.querySelector("#represent_sent")
text = input_text.value
...
output_div = document.querySelector("#output_represent")
output_div.innerText = min_key (edited)document.querySelector("#represent_sent") through the method ... as an event? Or like object_text = *Class*(document.querySelector("#represent_sent"))
and then py-click = "object_text.sent_represent" in HTML? (edited)

document.querySelector("#represent_sent") through the method ... as an event? Or like object_text = *Class*(document.querySelector("#represent_sent"))
and then py-click = "object_text.sent_represent" in HTML? (edited)object_text.addEventListener("click", create_proxy(object_text.method)) ?


object_text.addEventListener("click", create_proxy(object_text.method)) ? 










<script type="py" terminal>
print("hello, world")
</script>
<script type="py">
from pyscript import document
def clearTerm(evt):
terminal_element = document.querySelector("script[type='py'][terminal]")
terminal_element.terminal.clear()
</script>
<button py-click="clearTerm">Click to Clear</button> 



pyscript.net/releases? I'm having problem when I try loading PyScript using this domain






pyscript.net/releases? I'm having problem when I try loading PyScript using this domain 
id="py-w0" and increases to py-w2 and so on. (edited)



def genx():
yield 'a'
yield 'b'
yield 'c'
worker = PyWorker("./worker.py", worker_options)
worker.sync.genx = genx
and then in worker.py, I do
for x in sync.genx():
but this blows up with an error TypeError: 'pyodide.ffi.JsProxy' object is not iterable

def genx():
yield 'a'
yield 'b'
yield 'c'
worker = PyWorker("./worker.py", worker_options)
worker.sync.genx = genx
and then in worker.py, I do
for x in sync.genx():
but this blows up with an error TypeError: 'pyodide.ffi.JsProxy' object is not iterable 




from pyscript import ffi and then worker.sync.genx = ffi.create_proxy(genx) ? I wonder if that would be smart enough to instrument the returned callback to deal with genreators ... otherwise it seems like a pyodide proxy limitation hard for us to bypass or solve.

from pyscript import ffi and then worker.sync.genx = ffi.create_proxy(genx) ? I wonder if that would be smart enough to instrument the returned callback to deal with genreators ... otherwise it seems like a pyodide proxy limitation hard for us to bypass or solve. 

from pyscript import ffi and then worker.sync.genx = ffi.create_proxy(genx) ? I wonder if that would be smart enough to instrument the returned callback to deal with genreators ... otherwise it seems like a pyodide proxy limitation hard for us to bypass or solve. 









.html file out of the box, you need a localhost. Try with npx mini-coi . in that folder and reach the localhost url. If you name the file index.html you will see everything working, as I just did:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.5.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.5.2/core.js"></script>
</head>
<body>
<script type="py-editor">
import sys
print(sys.version)
</script>
<script type="mpy-editor">
import sys
print(sys.version)
a = 42
print(a)
</script>
</body>
</html> (edited)
ModuleNotFound Error.
The main python file being run is being picked up and I'm trying to access timeutils.py from schedule.py and I'm trying the following import:
from assets.pyfiles.utils.timeutils import (
get_utc_time,
get_local_time,
get_next_update_time,
get_time_until_next_update,
format_time_string,
) (edited)

ModuleNotFound Error.
The main python file being run is being picked up and I'm trying to access timeutils.py from schedule.py and I'm trying the following import:
from assets.pyfiles.utils.timeutils import (
get_utc_time,
get_local_time,
get_next_update_time,
get_time_until_next_update,
format_time_string,
) (edited)




.html file out of the box, you need a localhost. Try with npx mini-coi . in that folder and reach the localhost url. If you name the file index.html you will see everything working, as I just did:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.5.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.5.2/core.js"></script>
</head>
<body>
<script type="py-editor">
import sys
print(sys.version)
</script>
<script type="mpy-editor">
import sys
print(sys.version)
a = 42
print(a)
</script>
</body>
</html> (edited)








<table class="table table-hover table-striped" data-filter-control="true" id="rctable">
<thead>
<tr>
<th scope="col">Frage</th>
<th scope="col">Anzahl</th>
<th scope="col">รbermittlung</th>
</tr>
</thead>
<tbody>
{% for item in json_data.query%}
<tr>
<td>{{ item.Field_Label }}</td>
<td>{{ item.Con_Result}}</td>
<td> {% if item.transfer ==True %}
<input type="checkbox" id="transfer" value=" True " checked>
{% else %}
<input type="checkbox" id="transfer" value=" false" unchecked>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
add a datatable plugin at the end:
html
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script>$(document).ready(function(){
$('#rctable').DataTable();
});
</script>
`
But now i am on the clients side and i am wondering how best to proceed.
1. Would it be possible to load the jinja2 template engine into the pyscript environment and make it usable there? Is it even a reasonable idea, or unjustified effort given the existing possibilites of pyscript?
2. Should i simply try to do this with the dom-manipulation tools provided by pyscript?
3. Save the effort and create a REST API to send the data to the server and proceed from there as usual?

<table class="table table-hover table-striped" data-filter-control="true" id="rctable">
<thead>
<tr>
<th scope="col">Frage</th>
<th scope="col">Anzahl</th>
<th scope="col">รbermittlung</th>
</tr>
</thead>
<tbody>
{% for item in json_data.query%}
<tr>
<td>{{ item.Field_Label }}</td>
<td>{{ item.Con_Result}}</td>
<td> {% if item.transfer ==True %}
<input type="checkbox" id="transfer" value=" True " checked>
{% else %}
<input type="checkbox" id="transfer" value=" false" unchecked>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
add a datatable plugin at the end:
html
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script>$(document).ready(function(){
$('#rctable').DataTable();
});
</script>
`
But now i am on the clients side and i am wondering how best to proceed.
1. Would it be possible to load the jinja2 template engine into the pyscript environment and make it usable there? Is it even a reasonable idea, or unjustified effort given the existing possibilites of pyscript?
2. Should i simply try to do this with the dom-manipulation tools provided by pyscript?
3. Save the effort and create a REST API to send the data to the server and proceed from there as usual? 
TypeError: Can't create an SSLContext object without an ssl module https://pyscript.com/@cheaton/2024-eclipse/latest Any ideas? (edited)

TypeError: Can't create an SSLContext object without an ssl module https://pyscript.com/@cheaton/2024-eclipse/latest Any ideas? (edited)2024.5.2 ?
requests.get() with either website:
/lib/python3.11/site-packages/urllib3/connectionpool.py:1101: InsecureRequestWarning: Unverified HTTPS request is being made to host 'aviationweather.gov'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
warnings.warn(Error occurred: ('Connection aborted.', HTTPException("Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://aviationweather.gov/api/data/metar?ids=KSLC&format=json'."))
Here is the method where the error occurs:
def make_request(self, url, tries=1):
response = None
try:
response = requests.get(url, timeout=self.wait, verify=True)
response.raise_for_status()
except requests.exceptions.RequestException as err:
print(f"Error occurred: {err}")
except Exception as err:
print(f"An unexpected error occurred: {err}")
if tries > 0:
time.sleep(self.wait)
self.make_request(url, tries-1)
else:
print("Requests failed after 5 attempts, giving up...")
return response
Has anyone seen an error like this before? I assume it has to do with my implementation of requests, unless there's something in the html I'm supposed to do (edited)
<script id="my_script" type="mpy" terminal worker>
import code
code.interact()
</script>
and further down
<script>
const myterm = document.querySelector("#my_script");
await myterm.process('print("Hello world!")');
</script>
But i get the following errors:
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules (at terminal:122:5)
and the
Error: Unable to use SharedArrayBuffer due insecure environment error, when i use the suggested solution with the mini-coi.js file and properly reference its file:
{% block header_start %}
<script src={{ url_for('PyScriptDB.static', filename='mini-coi.js') }} scope="./static/"></script>
{% endblock %}
the page tries endlessly to load and reload, without throwing an error. What is the issue here?

2024.5.2 ? 













worker attribute to your PyScript tag, to load the interpreter in a worker thread and prevent blocking the pageโs main thread. There are a couple of considerations around headers there - see the docs for more info







<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script>$(document).ready(function(){
$('#rctable').DataTable();
});
</script>
it is no problem to insert this code into the html, but that doesn't mean the browser will apply the code. How do i load this dynamically into my page and make the browser execute the code?


userElement = js.document.getElementById('brief')
OPENAI_API_KEY = userElement.value.strip()
client = OpenAI(api_key=OPENAI_API_KEY, timeout=60.0, max_retries=3)
# Convert similar_items to string format
global similar_items
similar_items_str = ""
for index, row in similar_items.iterrows():
similar_items_str += f"Title: {row['Title']} Summary: {row['Summary']} Note: {row['Note']}"
payload = f"Using "Please generate a 500 word narrative summary of the following information: '''{similar_items_str}'''"
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": payload }
],
model="gpt-4o",
)
# Log the request data for debugging
console.log(f"Data: {messages}")
# Display the response in the summarybrief div
Element('summarybrief').element.innerHTML = chat_completion




.zip one



[files]
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.js" = "ltk/ltk.js"
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.css" = "ltk/ltk.css"

[files]
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.js" = "ltk/ltk.js"
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.css" = "ltk/ltk.css" .zip it'd be "https://raw.githubusercontent.com/pyscript/ltk/main/ltk.zip" = "./*" instead, where the zip contains the ltk folder with anything else you like in it



[files]
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.js" = "ltk/ltk.js"
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.css" = "ltk/ltk.css" 




# this is mandatory to display svg properly
if tag == "svg":
node.setAttribute("xmlns", _svg_ns)



# this is mandatory to display svg properly
if tag == "svg":
node.setAttribute("xmlns", _svg_ns) 




<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script id="activate_datatable" type="text/javascript">
function activate_datatable(){
$('#results_table').DataTable();
}
</script>
and this my function in pyscript:
def activate_datatable(event):
output_div = document.querySelector('#datatable_ok')
script_content = document.getElementById('activate_datatable').text
output_div.innerText = script_content
window.eval(script_content)
the script content gets shown, but window.eval doesnt seem to do anything, no error prompts either?

<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script id="activate_datatable" type="text/javascript">
function activate_datatable(){
$('#results_table').DataTable();
}
</script>
and this my function in pyscript:
def activate_datatable(event):
output_div = document.querySelector('#datatable_ok')
script_content = document.getElementById('activate_datatable').text
output_div.innerText = script_content
window.eval(script_content)
the script content gets shown, but window.eval doesnt seem to do anything, no error prompts either? from pyscript import window and then window.activate_datatable()







from pyscript import window and then window.activate_datatable() 




pyscript and pyweb modules. Imho, we should add them.

pyscript module has docs: https://docs.pyscript.net/2024.5.2/user-guide/builtins/pydom and pyweb docs, these should probably move from the user guide and be put into a top level "API" section of the docs.






Traceback (most recent call last):
File "/lib/python3.10/_pyodide/_base.py", line 460, in eval_code
.run(globals, locals)
File "/lib/python3.10/_pyodide/_base.py", line 306, in run
coroutine = eval(self.code, globals, locals)
File "<exec>", line 3, in <module>
ModuleNotFoundError: No module named 'discord'
I'm getting this error trying to import discord. In the TOML file, there is packages = ["discord.py"] (also tried with packages = ["discord"] but same issue). So does it not support Discord bots? I want the user to click a button to send a message to my Discord account with a Bot
ImportError: cannot import name 'fetch' from 'pyscript' (/home/pyodide/pyscript/__init__.py)
<script> tags in your head of the HTML file... latest version is 2024.5.2 although we expect to cut a new release sometime mid-week). (edited)
<button class="guildenter" py-click="join()">Unisciti alla Gilda</button>
My main.py file:
from pyscript import fetch
async def join():
payload = {
"content": "THE_MESSAGE"
}
headers = {
"Authorization": "MY_BOT'S_TOKEN"
}
await fetch(
"MY_URL",
method="POST",
headers=headers,
body="Utente registrato"
)
When I click the button, which appears, nothing happens<link rel="stylesheet" href="https://pyscript.net/releases/2024.5.2/pyscript.css" />
<link rel="stylesheet" href="elements.css">
<script defer src="https://pyscript.net/releases/2024.5.2/pyscript.js"></script>
<button py-click="find()">Fetch</button> in HTML
def find():
print("found")
in main.py
Now the button seems perma-clicked and can't be clickedfind, find(), main.find, main.find(), nothing at all works

py-click="find"

def find(event): (or something like it).

terminalprint in the browser console.



payload = {
"content": "Utente registrato"
}
headers = {
"Authorization": "MY TOKEN"
}
res = await fetch(
"LINK TO THE DISCORD CHANNEL",
method="POST",
headers=headers,
payload=payload
)
print(res)
requests. So all the browser CORS sandboxing and isolation limitations come into play (they're not there when using requests). (edited)


requests in normal Python..?

requests in normal Python..? 




discord from where?
import discord, and in the TOML file, packages = ["discord.py"]
discord.py..?
















for file in os.listdir():
print(file)
jsonfile = f"/db.json"
print(jsonfile)
with open(jsonfile, "r") as f:
db = json.load(f)
db["partecipanti"].append("Master di <Servant_class>")
with open(jsonfile, "w") as f:
json.dump(db, f)

for file in os.listdir():
print(file)
jsonfile = f"/db.json"
print(jsonfile)
with open(jsonfile, "r") as f:
db = json.load(f)
db["partecipanti"].append("Master di <Servant_class>")
with open(jsonfile, "w") as f:
json.dump(db, f) "./db.json?"


db.json, ./db.json, /db,json








db.json or literally /db.json?
pyscript.toml:[files]
"db.json" = "db.json"[files] key does. https://docs.pyscript.net/2024.5.2/user-guide/configuration/#files










import js and then await js.import_("module.js") but AFAIK micropython doesn't have the same convention for reserved words ... edit ... actually that doesn't work anymore in pyodide neither (edited)<script>const dynamicImport = name => import(name)</script> on the page and then:
from pyscript import window
module = await window.dynamicImport("module.js")

import and from are reserved words in Python so Array.from_ (IIRC) is what Pyodide came up as solution (imho a bit ugly but it works) but there's no import_ counterpart on the global context.

worker attribute all JS modules are loaded lazily, only when you import these, so you can have thousand of modules in your config and, as long as that's a worker PyScript executing it, you won't see any difference. On the main though, we can't make it lazy so on main (no worker attribute) you need that workaround

import utility ... as long as you don't use import in Python everything is fine.

from pyscript import window # if you want modules always on main
js_import = window.Function('return name => import(name)')()
await window.js_import("module.js").then(window.console.log) (edited)
js.eval()?
eval too ... eval is contextual so I always try not to use it

eval, but pyodide.code.run_js is a wrapper around eval that works from Python (edited)
js_import = window.Function('return name => import(name)')() (edited)

pyscript.js_import too that won't need eval or Function from our users ... @ntoll thoughts?pyscript.py_import(one, or_more, module) and pyscript.js_import(one, or_more, module) that both resolve asynchronously as modules tuple
./whatever.js in the context of JavaScript's runtime, it imports it relative to wherever PyScript was served from, not relative to your psuedo filesystem.

.whl files in python, the JS import can't be in the vFS as that vFS is not reachable through JS (edited)
{ "import_config": "my_project.json" }
Then in my_project.json, I could specify js_modules.files section to be able to use the project -- not that important, just a nicety.

files section to be able to use the project -- not that important, just a nicety. 


import code
code.interact()
Finally, we're making a new release of PyScript later today (this evening Euro-time). It'll have a major update to the MicroPython REPL, along with more docs (once released). All feedback most welcome. 
code.interact(). Just tried it w/ 2024.5.2 and it works like a charm. Thanks!




print() so it's not interacting w/ the UI. For now it's not actually using anything loaded from the config file, to remove that as a possible source of issues. It works fine when:
1. Using MicroPython not in a worker (with no config)
2. Using Pyodide not in a worker, with the config
3. Using Pyodide in a worker but not providing the config option
But whenever I combine MicroPython or a Pyodide worker with a config option, I get this error in the console: (edited)

(apparently its next build) (edited)




git clone -q https://github.com/pyscript/pyscript.git tmp-pyscript && \
cp -r tmp-pyscript/pyscript.core/src/stdlib/pyscript ./pyscript && \
rm -rf tmp-pyscript
from pyscript import document
element = document.getElementById("some_elem")
element.innerHTML = "LOL"
you will not get any type hints on the getElementById function or the element variable itself, for that you'd need a custom .pyi file or something (edited)

<template id="jinja-template">
<div>{{ name }}</div>
</template>
My intention is to extract <div>{{ name }}</div> out of it. Here is my code:
from pyscript import document
template_element = document.getElementById("jinja-template")
template_content = template_element.innerHTML
print(f'jinja_template_str => {template_content}')
but this returns <div></div> (i.e. gets rid of the {{ name }} placeholder)
Does anyone know how i can get the raw value with the placeholder?
Many thanks in advance.

<template id="jinja-template">
<div>{{ name }}</div>
</template>
My intention is to extract <div>{{ name }}</div> out of it. Here is my code:
from pyscript import document
template_element = document.getElementById("jinja-template")
template_content = template_element.innerHTML
print(f'jinja_template_str => {template_content}')
but this returns <div></div> (i.e. gets rid of the {{ name }} placeholder)
Does anyone know how i can get the raw value with the placeholder?
Many thanks in advance. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.6.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.6.1/core.js"></script>
<script type="mpy">
from pyscript import document
template_element = document.getElementById("jinja-template")
template_content = template_element.innerHTML
print(f'jinja_template_str => {template_content}')
</script>
</head>
<body>
<template id="jinja-template">
<div>{{ name }}</div>
</template>
</body>
</html>











fetch API.

{
"packages": [
"Jinja2"
],
"files": {
"{STATIC_FOLDER}": "http://localhost:5000/wizard/pyscript/static/",
"{TEMPLATES}": "templates",
"{STATIC_FOLDER}/jinja.py": "jinja.py",
"{STATIC_FOLDER}{TEMPLATES}/query_results.html": "./{TEMPLATES}/query_results.html",
"{STATIC_FOLDER}{TEMPLATES}/redcap_reroute.html": "./{TEMPLATES}/redcap_reroute.html"
}
}
then in my jinja.py i configure functions to setup the jinja2 environment:
import os
from jinja2 import Environment, FileSystemLoader, select_autoescape
def setup_jinja_env():
root_dir = os.path.dirname(__file__)
template_folder = os.path.join(root_dir, 'templates')
new_env = Environment(
loader=FileSystemLoader(template_folder),
autoescape=select_autoescape(["html", "xml"]),
)
return new_env
def _render_template(template_name_or_list, jinja_env, **context):
template = jinja_env.get_template(template_name_or_list)
return template.render(**context)
and finally use them at the top of my main.py file:
from jinja import setup_jinja_env, _render_template
jinja_env = setup_jinja_env()
def render_template(template_name_or_list, **context):
return _render_template(template_name_or_list, jinja_env, **context)
Now i can use the templates similiar to how i use them in flask. Keep in mind though, that you don't have access to all the flask environment variables you usually can access in the templates like current_user but only the context you have explicitly passed to the template.
Hope that helps (edited)

{
"packages": [
"Jinja2"
],
"files": {
"{STATIC_FOLDER}": "http://localhost:5000/wizard/pyscript/static/",
"{TEMPLATES}": "templates",
"{STATIC_FOLDER}/jinja.py": "jinja.py",
"{STATIC_FOLDER}{TEMPLATES}/query_results.html": "./{TEMPLATES}/query_results.html",
"{STATIC_FOLDER}{TEMPLATES}/redcap_reroute.html": "./{TEMPLATES}/redcap_reroute.html"
}
}
then in my jinja.py i configure functions to setup the jinja2 environment:
import os
from jinja2 import Environment, FileSystemLoader, select_autoescape
def setup_jinja_env():
root_dir = os.path.dirname(__file__)
template_folder = os.path.join(root_dir, 'templates')
new_env = Environment(
loader=FileSystemLoader(template_folder),
autoescape=select_autoescape(["html", "xml"]),
)
return new_env
def _render_template(template_name_or_list, jinja_env, **context):
template = jinja_env.get_template(template_name_or_list)
return template.render(**context)
and finally use them at the top of my main.py file:
from jinja import setup_jinja_env, _render_template
jinja_env = setup_jinja_env()
def render_template(template_name_or_list, **context):
return _render_template(template_name_or_list, jinja_env, **context)
Now i can use the templates similiar to how i use them in flask. Keep in mind though, that you don't have access to all the flask environment variables you usually can access in the templates like current_user but only the context you have explicitly passed to the template.
Hope that helps (edited)
http-server at localhost://8000
I still encounter error, my website doesnt function (edited)

http-server - I'm guessing you mean python -m http.server ..? If so, that's exactly the same setup as me.

http-server at localhost://8000
I still encounter error, my website doesnt function (edited)


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>get json from s3</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.6.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.6.1/core.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.4.1.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.4.1.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.4.1.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.4.1.min.js"></script>
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.4.1.min.js"></script>
</head>
<body>
<p>getting python code and py fetching remote AWS S3 json data...</p>
<div id="chart"></div>
<py-config>packages = ["bokeh"]</py-config>
<script type="py" async>
from bokeh.plotting import figure
from bokeh.embed import json_item
from pyscript import window, fetch, ffi
Bokeh = window.Bokeh
async def get_data():
data = await fetch('https://rickd.s3.us-east-2.amazonaws.com/04.json').json()
xAxis=[i['time'] for i in data] #grab s3 data using loop
yAxis=[i['Quantity'] for i in data] #grab s3 data using loop
p = figure(x_range=(0, 10), y_range=(0, 10), width = 700, height = 600)
p.line(xAxis, yAxis, legend_label="data from S3", line_width=2)
await Bokeh.embed.embed_item(ffi.to_js(json_item(p, "chart")))
await get_data()
</script>
</body>
</html> (edited)
from pyscript import window, fetch, ffi
Bokeh = window.Bokeh
about, it's a way to retrieve Bokeh from the main thread, no matter if you add worker to the <script type="py"> which I also suggest at it bootstraps without ever blocking the main thread (edited as the time seems to be similar in both cases, just measured) (edited)

from pyscript import window, fetch, ffi
Bokeh = window.Bokeh
about, it's a way to retrieve Bokeh from the main thread, no matter if you add worker to the <script type="py"> which I also suggest at it bootstraps without ever blocking the main thread (edited as the time seems to be similar in both cases, just measured) (edited)



<mpy-config> instead of <py-config> as multiple interpreters can run on the same page and should not interfere with each other setupwindow on the main thread is just an indirection for js ... basically import js and from pyscript import window on the main are the same thing but if you use a worker attribute and you land JS code on the page import js will give you the worker global context, not the main thread one, so you won't find any Bokeh in there at all as that's on the main page. from pyscript import window in there will still give you full access to the main thread even from a worker, so it's always the right global main reference to use and it makes code portable between main and workers.

<mpy-config> instead of <py-config> as multiple interpreters can run on the same page and should not interfere with each other setup 



loadPyodide when there's no config around, these do almost the same thing. Classic PyScript itself was 5X if not 10X heaveier on the JS side, if not more, but then again it used an older version of Pyodide so it's oranges to apples comparison. (edited)











renderers was not available, I had to switch to its latest and I suggest you keep the pace with this module's updates too



renderers was not available, I had to switch to its latest and I suggest you keep the pace with this module's updates too 








js_modules instead






packages = [...] that points at those pinned version of the module you expect both on Python and JS sidebokeh@2.4.2

packages = [...] that points at those pinned version of the module you expect both on Python and JS side 















package-lock.json got introduced in the JS world and why Pyodide itself has a package-lock bootstrap feature too so that if you expect certain packages to work, those packages frozen in time will guarantee they will work, with all pros and possible bugs they have, in your project. (edited)









python -m http.server
2. Visit localhost:8000 to view the page.
3. Report what happens.



id in HTML has to be unique.class name instead and document.querySelectorAll('.stats') to then loop over each stat and do the math.




@when you do ... well, the same, you create a listener that invokes two functions. If you want to pass through addEventListener manually though, you just add 2 listeners.

@when you do ... well, the same, you create a listener that invokes two functions. If you want to pass through addEventListener manually though, you just add 2 listeners. 

event cycle so ... use just one function if you really need to do two things within a single click.

event cycle so ... use just one function if you really need to do two things within a single click. 

<p> tag ... you were destroying every PyScript layout with that innerHTML on that element ... why was that?terminal reference where you can clear ittarget which is where stuff happens ... the terminal exposes a detach or desotry (can't remember, that's XTerm API) to remove it ... so unless I understand your initial goal and your final one, I am afraid I cannot help further.




None I am not sure what you think it should display?






runtime.runPython or similar


PyEditor is CodeMirror (https://codemirror.net/). We explain how it all works and fits together here: https://docs.pyscript.net/2024.6.2/user-guide/editor/
If this isn't enough for you, it would be really helpful for us if you could tell us what precisely it is you want to configure. Then, depending on the feasibility of what you're trying to do, we might be able to fix/enable/document things so your request becomes an enhancement! Of course, caveats apply: is it possible, how much effort is involved, is it likely to be a much sought after enhancement etc... But the key thing to do (as you've already started to do) is to engage..! 

PyEditor is CodeMirror (https://codemirror.net/). We explain how it all works and fits together here: https://docs.pyscript.net/2024.6.2/user-guide/editor/
If this isn't enough for you, it would be really helpful for us if you could tell us what precisely it is you want to configure. Then, depending on the feasibility of what you're trying to do, we might be able to fix/enable/document things so your request becomes an enhancement! Of course, caveats apply: is it possible, how much effort is involved, is it likely to be a much sought after enhancement etc... But the key thing to do (as you've already started to do) is to engage..! 
config attribute (see: https://docs.pyscript.net/2024.6.2/user-guide/configuration/#file-or-inline). But to be honest, the currently idiomatic approach is to stick config into a separate file and reference that from config. 

config attribute (see: https://docs.pyscript.net/2024.6.2/user-guide/configuration/#file-or-inline). But to be honest, the currently idiomatic approach is to stick config into a separate file and reference that from config. 

py-config at all ... in your page you have no type="py" and just a type="py-editor" but there is also a py-config which will be ignored ... it's not clear to me what you are trying to do but having a link instead of a screenshot to your pyscript .com attempt (or anything else you are using) might help further.

<script type=py> in <script type=py-editor> creating an editor where user can type the code and see their outputs.
I am sorry if the sreen-shot confused you, this is the link to PyScript .com, https://pyscript.com/@aayush05/run-ltk-in-browser/latest.
I am able to do that when I provide config attribute to the py-editor as separate file but when I do it as an inline json like in the link above I get an ever loading editor.
Once again, thank you for being so patient with the questions. (edited)

<script type=py> in <script type=py-editor> creating an editor where user can type the code and see their outputs.
I am sorry if the sreen-shot confused you, this is the link to PyScript .com, https://pyscript.com/@aayush05/run-ltk-in-browser/latest.
I am able to do that when I provide config attribute to the py-editor as separate file but when I do it as an inline json like in the link above I get an ever loading editor.
Once again, thank you for being so patient with the questions. (edited)

https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.52/dist/core.js (with its .css counterpart, but no changes in there)

https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.52/dist/core.js (with its .css counterpart, but no changes in there) 
ModuleNotFoundError: No module named 'public'
on the call to pickle.load. I've imported pickle at the top of my file and it seems to work fine, no errors about not finding that module. It seems to happen on the call to pickle.load. Am I missing an import or a dependency in my pyodide set up? Any other ideas? This is the first module of things I'd consider part of python that I've run into an issue with. I have no issues using re, typing, collections, etc.





https://cdn.jsdelivr.net/npm/@pyscript/core@0.4.52/dist/core.js (with its .css counterpart, but no changes in there) 





async attribute in your script you also have top-level await (edited)

async attribute in your script you also have top-level await (edited)



store = await storage("my-storage-name")
# now all operations are sync
store["key"] = { "some": "value" }
print(store["key"])
del store["key"]async attribute in your script and you would have no issue.





pyscript.storage feels easy, fast, and natural to use. We keep things in sync behind the scene too but if paranoid about it you can eventually, once in a while, use await store.sync() and be sure that will persist next time you visit that page/project. I hope this clarifies a bit and explain contrains and decisions around it.

runPythonAsync behind the scene might be a welcome feature. I don't know if there's anything ugly, greedier, slower, or problematic behind Pyodide and MicroPython scene but, if that's not the case, I think having even less to explain around async attribute or top level await would be beneficial (big imho here).
async attribute as surpless to requirements, and we should just tacitly make it that way... assuming no performance gotchas).




async attribute as surpless to requirements, and we should just tacitly make it that way... assuming no performance gotchas). 

File "/lib/python3.12/site-packages/botocore/utils.py", line 39, in <module>
import botocore.httpsession
File "/lib/python3.12/site-packages/botocore/httpsession.py", line 22, in <module>
from urllib3.util.ssl_ import (
ImportError: cannot import name 'ssl' from 'urllib3.util.ssl_' (/lib/python3.12/site-packages/urllib3/util/ssl_.py) I know urllib package does not work in pyscript. it seems that urllib is being called from boto3 (edited)


src ...<script id="my_script" src="./plan.py" type="mpy" terminal worker> (edited)



type in there, and everything else I've said ... you also likely never need pyfetch in our current offer

type in there, and everything else I've said ... you also likely never need pyfetch in our current offer 












web3.js.... (https://web3js.readthedocs.io/en/v1.10.0/index.html) - However, I notice that their docs say you may need the MetaMask (MetaMask) plugin for your browser, for this to work.
Details of interacting with JavaScript modules from PyScript can be found here: https://docs.pyscript.net/2024.6.2/user-guide/dom/#working-with-javascript



<script type="py" src="main.py" config="pyscript_pyo.toml" terminal></script>so I can see any print statements when I am editing the code and running it on pyscript.com. This is working.But if the code errors - there is no error message in the terminal(used to be) and there is no error message in the Chrome console(used to be). I am using py not mpy and I have only main - no workers. How do I get error messages to console or terminal ?
input element that gets created from an HTML template. The element has an attribute id = "status_msg". I can access said attribute via pydom['#status_msg'] or document.getElementById('status_msg'). I can change its value using the .value attribute, but not using .content nor .html. Given this little context, can anyone see what I am doing wrong? I tried using 2024.1.1 as well as 2024.6.2. My issue with .value is that it seems to be for text and I would like to store HTML code in the input element. Thanks 
.innerHTML? I think that's how you usually do it, both in Pyscript and JavaScript
.innerHTML as well. It's strange though, I am able to modify the input element itself using .outerHTML... cannot really make sense of it
<input> of type text doesn't store HTML, it only stores plain text. And to get the text written in it, you can read/write the value property (this works the same in JS and Pyscript).innerHTML can be used to modify e.g. a <div>.innerHTML, it should be a <div>, not an input
input element. If I copy and paste it from the clipboard into the input element, it gets shown correctly as a rendered emoji. If I set the emoji (html encoding) via .value, it does not get rendered but shown as the html encoded chars. That's the issue I am trying to solve.







<script type="py" src="main.py" config="pyscript_pyo.toml" terminal></script>so I can see any print statements when I am editing the code and running it on pyscript.com. This is working.But if the code errors - there is no error message in the terminal(used to be) and there is no error message in the Chrome console(used to be). I am using py not mpy and I have only main - no workers. How do I get error messages to console or terminal ? 








<script type="py" src="main.py" config="pyscript_pyo.toml" terminal></script>so I can see any print statements when I am editing the code and running it on pyscript.com. This is working.But if the code errors - there is no error message in the terminal(used to be) and there is no error message in the Chrome console(used to be). I am using py not mpy and I have only main - no workers. How do I get error messages to console or terminal ? 

runtime.runPython or similar 

fetch rather than pyfetch and the async attribute for the script tags (although you can still import asyncio if you need it). You can also still import pyodide namespaces... they're still there, but your code won't be so portable. Hope this makes sense.




pyscript namespace is part of the framework, not a module in your local filesystem.


fetch rather than pyfetch and the async attribute for the script tags (although you can still import asyncio if you need it). You can also still import pyodide namespaces... they're still there, but your code won't be so portable. Hope this makes sense. 


<script type="mpy" terminal worker>, e.g. stop its execution/restart it? To be more precise, I'd like to know if it's possible to stop the executed code (e.g. an infinite loop) from JS?


code.interact(), but i don't know if there is a way to trigger this from main thread
terminate on it..? @Andrea Giammarchi probably has better context to advise on this.
worker = PyWorker('python/worker.py', worker_options) where worker_options looks like this
worker_options = ffi.to_js({ "type" : "pyodide",
"config": {
"files" : {
"./python/decorators/makefilter.py" : "decorators/makefilter.py",
...
When I run this, it loads pyodide.mjs from https://cdn.jsdelivr.net/pyodide/v0.26.1/full/pyodide.mjs. I tried specifying an interpreter like i did in the main toml file as a field in the config, but it seems to ignore it. If I leave off the type, it doesn't work. I need to pass dynamic config because I am also passing additional configuration to my worker. It is possible I could specify the config with a toml file, and then try and load data in the worker thread, but ideally, i'd be able in the config to specify the interpreter just like in my main toml file to get the main thread script running.
/dist/core-Di0g8mUD.js there is an object that maps pyodide to https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs. I was able to modify that code in the dist to point to my local pyodide.mjs and make it work, but it seemed brittle and error prone since I'd want to reference an environmnent variable as to whether i was running on localhost or the actual server endpoint.



worker = PyWorker('python/worker.py', worker_options) where worker_options looks like this
worker_options = ffi.to_js({ "type" : "pyodide",
"config": {
"files" : {
"./python/decorators/makefilter.py" : "decorators/makefilter.py",
...
When I run this, it loads pyodide.mjs from https://cdn.jsdelivr.net/pyodide/v0.26.1/full/pyodide.mjs. I tried specifying an interpreter like i did in the main toml file as a field in the config, but it seems to ignore it. If I leave off the type, it doesn't work. I need to pass dynamic config because I am also passing additional configuration to my worker. It is possible I could specify the config with a toml file, and then try and load data in the worker thread, but ideally, i'd be able in the config to specify the interpreter just like in my main toml file to get the main thread script running. interpreter there?

terminate on it..? @Andrea Giammarchi probably has better context to advise on this. worker.terminate() and kill it ... then you need to bootstrap it again, eventually. This is part of Web Workers API though, nothing really too magic from our side.terminate() it is.









interpreter there? 

version instead for some reason ... please give it a try, and outside the config

version instead for some reason ... please give it a try, and outside the config 

module:(e="0.26.1")=>https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`` to module:(e="0.26.1")=>${globalThis.origin}/pyodide/pyodide.mjs``

module:(e="0.26.1")=>https://cdn.jsdelivr.net/pyodide/v${e}/full/pyodide.mjs`` to module:(e="0.26.1")=>${globalThis.origin}/pyodide/pyodide.mjs`` 

PyWorker instance itself ... from JS module everything looks fine to me.

PyWorker instance itself ... from JS module everything looks fine to me. 

PyWorker instance itself ... from JS module everything looks fine to me. 







head element ... also the logo.png is nowhere in your repo, here a cloned example https://pyscript.com/@agiammarchi/pandas-copy-36373-copy-copy/latest (edited)<head> it moves itself, or its target visual element, to the document.body ... a Web page has a <head> to explain intents but never to show layouts ... the body element is always what you are after for anything layout related. (edited)<!doctype html>
<html>
<instructions />
<view />
</html>
consider those instructions your head element and the view your body tag and you won't have issues whatsoever later on. (edited)definition would've been more appropriate too ... instruction is a bit too generic ... <title> as example makes sense only in <head> elements, putting titles anywhere else makes no sense for the browsers ... maybe it works too, but at the search engine level, it's broken

terminate() it is. .terminate() has no effect: https://pyscript.com/@jbdod/stop-terminal-worker/latest.
What's more, I don't think it's possible to list the workers running on a web page from JS, so I can't use the API directly from JS (Or is there a way to get the reference out of python?).

version parameter. I had tried passing it relative and called interpreter as it is in the config for the main thread.

version parameter. I had tried passing it relative and called interpreter as it is in the config for the main thread. 

.terminate() has no effect: https://pyscript.com/@jbdod/stop-terminal-worker/latest.
What's more, I don't think it's possible to list the workers running on a web page from JS, so I can't use the API directly from JS (Or is there a way to get the reference out of python?). worker.terminate() as that's not awaitable, it's a "kill" switchworkers[name] convention is for utilities, it doesn't give you a reference to the worker itself ... to do so, you need to query that very same script node and access its xworker field to then terminate it. This is all food for thoughts on how we could simplify that terminate dance, but as it's not the main use case for workers, I hope you can deal with my revision of your example.
xworker 

xworker terminate method to the script itself might indeed fade away some complexity ... still we need to be clear that workers[name] give you access to utilities exported by that worker, not the worker itself, as that's a different API





packages = [ "pyscript-ltk>=0.1.2", "emfs://wheels/PyRTF3-0.47.5-py3-none-any.whl"] or as packages = [ "PyRTF3"] the whll never gets past initialisation on pyscript.com. Any hints ?


canvas.toDataURL() https://pyscript.recipes/latest/basic/file-download/






window.addEventListener or window.dispatchEvent there might help.








hide() method.
What I am doing so far:
from pyscript import document
from js import bootstrap
offcanvas_element = document.querySelector('#myOffcanvas')
offcanvas = bootstrap.Offcanvas(offcanvas_element).new()
However, calling new() causes error: pyodide.ffi.JsException: TypeError: Class constructor qn cannot be invoked without 'new'
Any ideas why? (edited)

CustomElementRegistry.define()) using PyScript?





Atomic.wait operations there is no DOM access in workers so ... yes and no: yes because it helps integrating with already used Service Workers (something mini-coi can't do) and no, it can't fix/patch automatically itself because the service worker related file MUST be installed and served via the server.

<script src="mini-coi.js"></script> on top of your <head> ... once you have that, you should have no issues. Feel free to literally copy and paste this content into mini-coi.js then add that script that should NOT be a module and should be there before anything else.


pyscript.web now, if interested, and yes, it's docummented https://docs.pyscript.net/2024.7.1/api/#pyscriptweb






main.py as <script src="..."> is that you get intellisense for Python out of the box. We need a plugin for VSCode/ium to do the same on <script type="py|mpy"> but currently that's not on the pipe ... unless you are referring to our pyscript module namespace, in which case we also would need a plugin for VSCode/ium but that might be even harder to bring in. (edited)


pyscript namespace / module or not ... that pure python wheel would need a lot of assumptions around the worker/non-worker DOM and JS magic in it though, it would be a dummy module in pypi and I am not sure that's a (welcomed) thing in there 







pypi does not want the internet to fetch from other domains or extensions we cannot really fix much ... and if we default to no-cors fetch operations we'll have other issues.

pypi does not want the internet to fetch from other domains or extensions we cannot really fix much ... and if we default to no-cors fetch operations we'll have other issues. <head> element and see if that fixes the issue?
<script>
globalThis.fetch = ($ => (url, options) => $(url, { ...options, mode: 'no-cors' }))(fetch);
</script>
pyodide.setDebug(true)" for calls from the JavaScript side to the Python side (example on the javascript side would be let r = await checkCommSystem();; checkCommSystem is a function on the Python side). On the python side this is how I'm setting up the communication between the two sides:
Near the top:
from pyscript import window as js
At the end:
js.startBootstrapWrapper = startBootstrapWrapper
js.buildTableWrapper = buildTableWrapper
js.calcMeansSDMW = calcMeansSDMW
js.passFileData = passFileData
js.getListData = getListData
js.checkCommSystem = checkCommSystem
Where each one of these items is a async function.
Is this a bug or are we changing how we are supposed to setup the communication between the two sides? My python code is running in a worker. (edited)

pyodide.setDebug(true)" for calls from the JavaScript side to the Python side (example on the javascript side would be let r = await checkCommSystem();; checkCommSystem is a function on the Python side). On the python side this is how I'm setting up the communication between the two sides:
Near the top:
from pyscript import window as js
At the end:
js.startBootstrapWrapper = startBootstrapWrapper
js.buildTableWrapper = buildTableWrapper
js.calcMeansSDMW = calcMeansSDMW
js.passFileData = passFileData
js.getListData = getListData
js.checkCommSystem = checkCommSystem
Where each one of these items is a async function.
Is this a bug or are we changing how we are supposed to setup the communication between the two sides? My python code is running in a worker. (edited)create_proxy when you want callbacks to be kept alive and never be garbage collected ... the only hint I have is that you are using eval somewhere and the engine couldn't know what you are going to evaluate, so that the reference is marked as not needed anymore and removed from the running context. We do take care a lot about memory leaks, so I kinda prefer less leaks and breaking things than having unspotted leaks out there, if that makes sense.

create_proxy when you want callbacks to be kept alive and never be garbage collected ... the only hint I have is that you are using eval somewhere and the engine couldn't know what you are going to evaluate, so that the reference is marked as not needed anymore and removed from the running context. We do take care a lot about memory leaks, so I kinda prefer less leaks and breaking things than having unspotted leaks out there, if that makes sense. 
js.thing = create_proxy(thing) where create_proxy comes from pyodide.ffy or even pyscript.ffi I think your issue should vanish.




<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script src="./onloadCode.js"></script>
<script type="py" src="./startup.py" worker></script>
</body>
</html>onloadCode.js being like thiswindow.addEventListener("py:all-done", async (event) => {
console.log(await checkCommSystem());
});sturtup.py bein like this
from pyscript import window as js
def checkCommSystem():
return True
js.checkCommSystem = checkCommSystemasync def checkCommSystem():
return Truewindow global namespace understands callbacks, although there might be an issue with async callbacks but nothing throws on MicroPython side, it does on Pyodide side (edited)


























packages = ["python-weather"]


<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script>
addEventListener('py:done', async () => {
console.log({ result: await test() });
});
</script>
<script type="py" worker>
from pyscript import window
async def test():
print("test")
return True
# enforce pyodide async resolution when
# the attached method is an async def
def attach_async(fn):
from pyscript import window, RUNNING_IN_WORKER
if not RUNNING_IN_WORKER: return fn
from pyscript.ffi import create_proxy
cb = create_proxy(fn)
def invoker(*args, **kw):
p = window.Promise.withResolvers()
cb(*args, **kw).add_done_callback(lambda _:p.resolve(_.result()))
return p.promise
return invoker
window.test = attach_async(test)
</script>
</body>
</html>then in it so that the callback would've resolved without the actual result. As apparently there's no way to run_until_complete in a blocking way (no matter what I do, no matter if async) and pyodide.ffi.run_sync was breaking too, that dance is needed to ensure that the task runs and once it's done it's result is passed to the returned promise which is understood by the main and awaited. If older PyScript (before current changes) was working it's worth investigating what the hell is going on because I don't know or understand why it was working before (or why it wouldn't now).
At least there is a workaround for this though

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script>
addEventListener('py:done', async () => {
console.log({ result: await test() });
});
</script>
<script type="py" worker>
from pyscript import window
async def test():
print("test")
return True
# enforce pyodide async resolution when
# the attached method is an async def
def attach_async(fn):
from pyscript import window, RUNNING_IN_WORKER
if not RUNNING_IN_WORKER: return fn
from pyscript.ffi import create_proxy
cb = create_proxy(fn)
def invoker(*args, **kw):
p = window.Promise.withResolvers()
cb(*args, **kw).add_done_callback(lambda _:p.resolve(_.result()))
return p.promise
return invoker
window.test = attach_async(test)
</script>
</body>
</html> # enforce micropython async resolution when
# the attached method is an async def
def attach_async(fn):
from pyscript import window, RUNNING_IN_WORKER
if not RUNNING_IN_WORKER: return fn
def invoker(*args, **kw):
async def promise(resolve, _):
resolve(await fn(*args, **kw))
return window.Promise.new(promise)
return invoker






<script type="py" src="/pyscript/c_and_c_client.py" config="/pyscript/c_and_c_client.toml"></script>
Doesn't seem to reload on a Shift F5. Currently the entire content of that file is....
def main():
print("I'm here!")
main()
But when I reload I get this error
ImportError: cannot import name 'console' from 'pyscript'
I was trying to do from pyscript import console
But when that gave me the error above I decided to cut down my code and rebuild slowly so I could track down what I was doing that was wrong.
Also is the above the "correct" way to launch pyscript code?
PythonError: Traceback (most recent call last):
File "/lib/python312.zip/_pyodide/_base.py", line 522, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python312.zip/_pyodide/_base.py", line 356, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 1, in <module>
ImportError: cannot import name 'console' from 'pyscript' (/home/pyodide/pyscript/__init__.py)
why?
<script type="py" src="..." config="..." terminal></script> I believe these days they might recommend using display() instead of print which defaults to adding text to the dom. https://docs.pyscript.net/2024.8.1/user-guide/first-steps/

pytest in https://pyscript.com was merely a question of calling pytest.main() which I found at https://docs.pytest.org/en/stable/how-to/usage.html#calling-pytest-from-python-code
To run the pytests background worker connected to a terminal do:
<script type="py" config="./pyscript.toml" terminal worker>
import pytest
pytest.main()
</script>
All the file naming for pytest discover, plus the __init__.py files, plus the [files] section of pyscript.toml are required but it work for me!
Also see: https://pyscript.com/@antocuni/pytest-in-pyterminal (edited)pytest working in pyscript, as described here.
It would be preferable to have it in color, however it's obvious that this method https://pyscript.com/@antocuni/pytest-in-pyterminal is very much deprecated and I don't know whether there's any current know recipe for a pyscript terminal that supports colour

pytest_runtest_makereport hook (edited)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>๐ฆ Polyglot - Piratical PyScript</title>
<!--
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script type="py" worker>
print("runs")
</script>
</script>
</body>
</html>
when using pyscript 2024.8.1 i get
TypeError: oe.withResolvers is not a function
but only when using the worker, in 2024.7.1 both variants work.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>๐ฆ Polyglot - Piratical PyScript</title>
<!--
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script type="py" worker>
print("runs")
</script>
</script>
</body>
</html>
when using pyscript 2024.8.1 i get
TypeError: oe.withResolvers is not a function
but only when using the worker, in 2024.7.1 both variants work. 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>๐ฆ Polyglot - Piratical PyScript</title>
<!--
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script type="py" worker>
print("runs")
</script>
</script>
</body>
</html>
when using pyscript 2024.8.1 i get
TypeError: oe.withResolvers is not a function
but only when using the worker, in 2024.7.1 both variants work. <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>๐ฆ Polyglot - Piratical PyScript</title>
<!--
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<script type="py" worker>
print("runs")
</script>
</body>
</html>
you need to run a server that enables special headers to use workers at their full potentials.

terminal attribute is missing ... https://developer.chrome.com/docs/devtools/open

PythonError: Traceback (most recent call last):
File "/lib/python312.zip/_pyodide/_base.py", line 522, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python312.zip/_pyodide/_base.py", line 356, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 1, in <module>
ImportError: cannot import name 'console' from 'pyscript' (/home/pyodide/pyscript/__init__.py)
why? console to import from pyscript ... you can import window and then use window.console to use native JS consle otherwise you can just use print





https://cdn.jsdelivr.net/npm/@pyscript/core@0.5.2/dist/core.js (and .css counter-part) ... it'd be great if you could confirm everything works again as expected, thank you. /cc @ntoll ... PR here https://github.com/pyscript/pyscript/pull/2136

https://cdn.jsdelivr.net/npm/@pyscript/core@0.5.2/dist/core.js (and .css counter-part) ... it'd be great if you could confirm everything works again as expected, thank you. /cc @ntoll ... PR here https://github.com/pyscript/pyscript/pull/2136 

await should happen whenever the worker utility is defined, which is in the worker indeed. In short, I am confident the current patch "just works" and it makes sense too. Before? ... I am not super sure why or how that worked but it clearly did, and that's why I wanted to rewrite coincident, to be sure about what happens 

console to import from pyscript ... you can import window and then use window.console to use native JS consle otherwise you can just use print 

terminal attribute is missing ... https://developer.chrome.com/docs/devtools/open 

index.html page https://discord.com/channels/972017612454232116/972020206538997822/1269928297618214943 and you open devtools to read the printed value in console.

await should happen whenever the worker utility is defined, which is in the worker indeed. In short, I am confident the current patch "just works" and it makes sense too. Before? ... I am not super sure why or how that worked but it clearly did, and that's why I wanted to rewrite coincident, to be sure about what happens 





index.html page https://discord.com/channels/972017612454232116/972020206538997822/1269928297618214943 and you open devtools to read the printed value in console. 






prompt in Workers, you can use input though ... but that's unrelated with the devtools not showing logs?window.prompt oneinput there.




asyncio that heavy computation so that the DOM has a chance to "tick" and show changes. I am sure this would help anyone else not using worker out there so the solution is here for history sake: https://github.com/pyscript/pyscript/issues/2135#issuecomment-2271260217




pip /cc @ntoll

py3-none-any wheel


latest a version of PyScript, because we want folks to pin their PyScript version (especially since, given the current growth stage of the project, things are changing fast). Change is hard. I know exactly how this feels, and you have my deepest sympathy when dealing with this... pyscript namespace (see: https://microsoft.github.io/pyright/#/type-stubs)

latest a version of PyScript, because we want folks to pin their PyScript version (especially since, given the current growth stage of the project, things are changing fast). Change is hard. I know exactly how this feels, and you have my deepest sympathy when dealing with this... 

asyncio that heavy computation so that the DOM has a chance to "tick" and show changes. I am sure this would help anyone else not using worker out there so the solution is here for history sake: https://github.com/pyscript/pyscript/issues/2135#issuecomment-2271260217 










import { things } from './assets/pyscript/dist/core.js'; in your project as part of the HTML so that you won't have bundlers on your way.

import { things } from './assets/pyscript/dist/core.js'; in your project as part of the HTML so that you won't have bundlers on your way. https://esm/run/pyscript@core witohut explicit /dist/core.js target is broken because bundlers tend to do "way too smart" things and in our case, like in many other cases out there where things are not just the usual "hello world" but a more complex architecture/hierarchy of dependencies, everything breaks "like a charm" but it's always bundlers fault ... or bundlers not being properly configured to ignore things that are not supposed to be bundled around. (edited)



ValueError: Can't find a pure Python 3 wheel for: 're'
See: https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package
We explain this in our docs here: https://docs.pyscript.net/2024.8.2/faq/#python-packages
python
from sympy.plotting import plot
from sympy.abc import x
# Create a plot
p = plot(x**2, show=False)
# Display the plot
display(p)
this returns only the plot object but not the plot :
<sympy.plotting.plot.Plot object at 0x3242648> (edited)
Plot object probably needs one of these methods: https://github.com/pyscript/pyscript/blob/main/pyscript.core/src/stdlib/pyscript/display.py#L8

greeting = sync.hello("PyScript"). Is the body of the hello() function executed in the worker thread or in the main thread?



























floofbytes - that had me giggling like a 2yo. 



InsecureRequestWarning: Unverified HTTPS request is being made to host 'redcap.med.tu-dresden.de'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
Is there a way to add the certificate verification to my environment, or via the browser or at least disable the warnings?
















./img input/ maybe also consider replacing the space with an underscore - not that you need to - just for clarity and to make your life easier. Looks like you're using opencv or PIL.







sys.excepthook could be a way to approach this? Something like:
import sys
import random
def nudge(exc_type, instance, traceback):
msg = random.choice([
"Whoops! That didn't go so well",
"Ouch! Python didn't like that",
"Hmmmm..., something weird happened",
])
suggest = random.choice([
"Try looking at",
"I think the problem is around",
"Something smells funny around",
])
frame = traceback.tb_frame
lineno = frame.f_lineno
from pathlib import Path
source_file = Path(frame.f_code.co_filename).read_text()
source = source_file.splitlines()[lineno-2:lineno+1]
print(msg)
print(f"{suggest} line {frame.f_lineno}:\n")
print("\n".join(f" {lineno + i - 1}: {line}" for i, line in enumerate(source)))
sys.excepthook = nudge
# do something exceptional
x = 1/0



sys.excepthook could be a way to approach this? Something like:
import sys
import random
def nudge(exc_type, instance, traceback):
msg = random.choice([
"Whoops! That didn't go so well",
"Ouch! Python didn't like that",
"Hmmmm..., something weird happened",
])
suggest = random.choice([
"Try looking at",
"I think the problem is around",
"Something smells funny around",
])
frame = traceback.tb_frame
lineno = frame.f_lineno
from pathlib import Path
source_file = Path(frame.f_code.co_filename).read_text()
source = source_file.splitlines()[lineno-2:lineno+1]
print(msg)
print(f"{suggest} line {frame.f_lineno}:\n")
print("\n".join(f" {lineno + i - 1}: {line}" for i, line in enumerate(source)))
sys.excepthook = nudge
# do something exceptional
x = 1/0 

sys.excepthook could be a way to approach this? Something like:
import sys
import random
def nudge(exc_type, instance, traceback):
msg = random.choice([
"Whoops! That didn't go so well",
"Ouch! Python didn't like that",
"Hmmmm..., something weird happened",
])
suggest = random.choice([
"Try looking at",
"I think the problem is around",
"Something smells funny around",
])
frame = traceback.tb_frame
lineno = frame.f_lineno
from pathlib import Path
source_file = Path(frame.f_code.co_filename).read_text()
source = source_file.splitlines()[lineno-2:lineno+1]
print(msg)
print(f"{suggest} line {frame.f_lineno}:\n")
print("\n".join(f" {lineno + i - 1}: {line}" for i, line in enumerate(source)))
sys.excepthook = nudge
# do something exceptional
x = 1/0 <script type="py-editor">:
import sys
def nudge(exc_type, instance, traceback):
frame = traceback.tb_frame
print(f'File: {frame.f_code.co_filename}')
print(f'Line: {frame.f_lineno}')
sys.excepthook = nudge
x = 1/0
The output div shows:
File: /lib/python312.zip/_pyodide/_base.py
Line: 596
Error
The error is in red. So the line number is not informative, nor is the filename. I'd really like to not show the red error as well. Is there any way to get relevant information from the error and not display "Error"?







<script type="py-editor"> with
editor.process(editor.code)
Would the process function throw an exception if the code had an error?
Separately, I can't get the process function to work. I get the following error in the browser console:
pyodide.asm.js:10 Unable to use `window` or `document` -> https://docs.pyscript.net/latest/faq/#sharedarraybuffer


from pyscript import document
def submit(event):
editor = document.querySelector('#editor')
print(f'code: {editor.code}')
editor.process(editor.code)
The code gets printed to the consoleprocess gives me the above error


exec() instead of process()editor.process(editor.code) broken, or am I missing something?
import mylib
mylib.myfunc()
where mylib.py is in the same directory as the current file. But this doesn't work in PyScript.

<script type="py-editor">:
import sys
def nudge(exc_type, instance, traceback):
frame = traceback.tb_frame
print(f'File: {frame.f_code.co_filename}')
print(f'Line: {frame.f_lineno}')
sys.excepthook = nudge
x = 1/0
The output div shows:
File: /lib/python312.zip/_pyodide/_base.py
Line: 596
Error
The error is in red. So the line number is not informative, nor is the filename. I'd really like to not show the red error as well. Is there any way to get relevant information from the error and not display "Error"? mpy-editor instead with the exact same code you have Line 8 which is where the error happens, then you have:
Error: Traceback (most recent call last):
File "", line 8, in
AttributeError: 'module' object has no attribute 'excepthook'
which is definitively better but then again, it's not us interfering with what the error provides in terms of details. That being said, if you want to disable the red errors you can add this CSS toyour page:
py-editor-output span, mpy-editor-output span {
display: none;
}

import mylib
mylib.myfunc()
where mylib.py is in the same directory as the current file. But this doesn't work in PyScript. 


async functions instead of orchestrating manually coroutines as that gets easily translated on the interpreter side and it's more aligned with JS pattern around async ... also latest PyScript enables top level await out of the box, just in case this detail is interesting or useful. (edited)

import mylib
mylib.myfunc()
where mylib.py is in the same directory as the current file. But this doesn't work in PyScript. [files]
"./mylib.py" = "./"

async functions instead of orchestrating manually coroutines as that gets easily translated on the interpreter side and it's more aligned with JS pattern around async ... also latest PyScript enables top level await out of the box, just in case this detail is interesting or useful. (edited)



worker script you have all sync-like APIs you like, that's how the whole project works already, it's non-blocking from a worker, if you ask for async stuff on the main thread.




[files]
"./mylib.py" = "./" 



<script type="mpy">, <script type="py">, <py-script>, and <mpy-script> tags. But I need students to be able to submit code to be tested by my unit tests, in addition to running their code. For that, I need to be able to programmatically execute the Python code in the editor, either from JavaScript or within Python. Unfortunately, I can't get editor.process(editor.code) (https://docs.pyscript.net/2024.8.2/user-guide/editor/#read-write-execute) to work as mentioned in a post above.
@chris.laffra suggested using exec() instead of process(). The output goes directly to the console and there's no result (what the code returns after the last statement).
Is there a way to get process() working or can I intercept exec() 's output and retrieve the result?

<script type="mpy">, <script type="py">, <py-script>, and <mpy-script> tags. But I need students to be able to submit code to be tested by my unit tests, in addition to running their code. For that, I need to be able to programmatically execute the Python code in the editor, either from JavaScript or within Python. Unfortunately, I can't get editor.process(editor.code) (https://docs.pyscript.net/2024.8.2/user-guide/editor/#read-write-execute) to work as mentioned in a post above.
@chris.laffra suggested using exec() instead of process(). The output goes directly to the console and there's no result (what the code returns after the last statement).
Is there a way to get process() working or can I intercept exec() 's output and retrieve the result? editor.exec works, it looks like editor.process should too ... are you also changing the editor code before asking it to evaluate anything?

editor.exec works, it looks like editor.process should too ... are you also changing the editor code before asking it to evaluate anything? editor.exec in our code ...

editor.exec works, it looks like editor.process should too ... are you also changing the editor code before asking it to evaluate anything? exec, not editor.exec

exec, not editor.exec await editor.process as we switched to async by default so these cases must await the resultawait editor.process(editor.code) ... something we should definitively change in our docs for clarity sake

await editor.process as we switched to async by default so these cases must await the result await editor.process()

exec works, but only outputs to console and doesn't give a return result. editor.process() never works
event.preventDefault() too

print. What's LTK? I also see that editor.process(editor.code) also doesn't work in your example. Is editor.process() simply broken? Or the documentation for PyScript needs to be updated?

print. What's LTK? I also see that editor.process(editor.code) also doesn't work in your example. Is editor.process() simply broken? Or the documentation for PyScript needs to be updated? 







{
"packages": [
"SQLAlchemy",
"Jinja2",
"python_dateutil",
"PyCap"
],
"files": {
"{STATIC_FOLDER}": "http://localhost:5000/wizard/pyscript/static/",
"{TEMPLATES}": "templates",
"{STATIC_FOLDER}/db_config.py": "db_config.py",
"{STATIC_FOLDER}/models.py": "models.py",
"{STATIC_FOLDER}/invoice.py": "invoice.py",
"{STATIC_FOLDER}/invoicequery.py": "invoicequery.py",
"{STATIC_FOLDER}/jinja.py": "jinja.py",
"{STATIC_FOLDER}/pycap_ext.py": "pycap_ext.py",
"{STATIC_FOLDER}{TEMPLATES}/query_results.html": "./{TEMPLATES}/query_results.html",
"{STATIC_FOLDER}{TEMPLATES}/redcap_reroute.html": "./{TEMPLATES}/redcap_reroute.html"
}
}
"interpreter": "3.11"
and it works fine now, i guess the maintainers of the PyCap Package need to update their wheel.



from pyscript import document ??





Unverified HTTPS request is being made. Adding certificate verification is strongly advised.See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
I could probably simply disable the warning:
import requests
from requests.packages.urllib3.exceptions
import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
But prefer to solver the issue, so i thought the certificates are missing so i tried to add them like this:
import certifi
import os
os.environ['REQUESTS_CA_BUNDLE'] = certifi.where()
But this didnt help, so i dug through the libraries and if i understand correctly the requests library already uses urrlib3 and the certifi package for the certification. So the PyScript Environment has the needed certificates. There is also a check if the proxy is verified. Could this be the root of the issue? Any ideas how to proceed? Debugging this is a nightmare. (edited)
pypy.org/simple/pyperclip (a dependency from cmd2), it makes no progress or raises any error on the console.
I see that pyperclip doesn't distribute a wheel, and from its name it must rely on native capabilities to access the clipboard. What options do you recommend to move forward?


































async def main():
response = await fetch("http://localhost:8000/get_uuid")
if response.ok:
data = response.text()
else:
display(response.status, target="myoutput")
display(f"UUID: {data}", target="myoutput", append=False)
Why do I not get anything displayed in my "myoutput" div? I know that the endpoint being called has been called successfully. but it feels like that display call never gets called.
<div id="myoutput">my output</div>
<script type="py" config="/pyscript/c_and_c_client.toml" target="myoutput">
import c_and_c_client
c_and_c_client.main()
</script>
<py-script>
from pyscript import display
display("Hello all you people", target="myoutput", append=False)
</py-script>
That py-script block works as expected.
The console reports:
<PyodideFuture pending>
and I'm unsure what that means. (edited)

'myoutput' and not '#myoutput'?main() function without using await.


import sys
if 'MicroPython' in sys.version:
print('mpy')
else:
print('py')
<link rel="stylesheet" href="https://pyscript.net/releases/2024.9.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.9.1/core.js"></script>
in the same folder, i created a run.py script that imports libraries like this :
import cv2 as cv
from cv2geojson import find_geocontours, export_annotations
import numpy as np
and finally in my html i added the following script element :
<script type="mpy" src="./run.py" config='{"packages":["cv2","cv2geojson","numpy"]}'></script>
now when i open my page, i get a CORS error :
micropython.mjs:1 Access to XMLHttpRequest at 'https://micropython.org/pi/v2/package/py/cv2/latest.json' from origin 'https://super-duper.fr' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm not sure what i'm doing wrong, any help is appreciated. Thanks 


<link rel="stylesheet" href="https://pyscript.net/releases/2024.9.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.9.1/core.js"></script>
in the same folder, i created a run.py script that imports libraries like this :
import cv2 as cv
from cv2geojson import find_geocontours, export_annotations
import numpy as np
and finally in my html i added the following script element :
<script type="mpy" src="./run.py" config='{"packages":["cv2","cv2geojson","numpy"]}'></script>
now when i open my page, i get a CORS error :
micropython.mjs:1 Access to XMLHttpRequest at 'https://micropython.org/pi/v2/package/py/cv2/latest.json' from origin 'https://super-duper.fr' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm not sure what i'm doing wrong, any help is appreciated. Thanks 

def _img2geojson(e):
myFile = e.target.files.item(0)
....
img2geojson = create_proxy(_img2geojson)
document.getElementById("inputFile").addEventListener("change", img2geojson)
the thing i do not understand is how to use a function that requires a file path. For example with opencv library i would open an image with the command imread("/path/img.png"). In my pyscript i only have a file object, i don't have a path to give to imread function. Is there a way to deal with this?


tmp = window.URL.createObjectURL(file)
i imagine this would make my file somehow accessible from the window object, but i'm not sure where this is created or how to use it in a javascript function.
By the way, thanks everyone for your answers, it's very helpfull.


















Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "nanotui/__init__.py", line 2, in <module>
ImportError: no module named '__future__'
https://pyscript.com/@ntoll/chewytui/

main.py ? What browser is this? Try updating if not the latest.

main.py ? What browser is this? Try updating if not the latest. 


Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "nanotui/__init__.py", line 2, in <module>
ImportError: no module named '__future__'
https://pyscript.com/@ntoll/chewytui/ 








https://pyscript.net/releases/2024.5.2/core.js works (edited)



# for Rich color output
os.environ["FORCE_COLOR"] = "1"

# for Rich color output
os.environ["FORCE_COLOR"] = "1" Package not found: https://micropython.org/pi/v2/package/py/picotui/latest.json 2f0c965c-eb37-46cf-a1e9-ffabaaa9e930:2:7273
Package may be partially installed 2f0c965c-eb37-46cf-a1e9-ffabaaa9e930:2:7273
What is the best way to use it? Do I copy all the python files in my project directory ?

Package not found: https://micropython.org/pi/v2/package/py/picotui/latest.json 2f0c965c-eb37-46cf-a1e9-ffabaaa9e930:2:7273
Package may be partially installed 2f0c965c-eb37-46cf-a1e9-ffabaaa9e930:2:7273
What is the best way to use it? Do I copy all the python files in my project directory ? 





result = pw.page.find("#result_div")[0]
try:
res = g.query(query_string)
result.append(res_to_table(res))
except Exception as e:
...

result = pw.page.find("#result_div")[0]
try:
res = g.query(query_string)
result.append(res_to_table(res))
except Exception as e:
... result.replaceChildren() right..?

result.replaceChildren() right..? res_to_table(res)._dom_element to get it to work though. (edited)
replaceChildren() call should be passed through to the underlying ._dom_element automagically. I'll take a look.
<script type="py-editor"> widget? At the moment no matter what I do it always starts out tiny and only gets larger if you type in it

<script type="py-editor"> widget? At the moment no matter what I do it always starts out tiny and only gets larger if you type in it 
@when("click", ".tile")
def click_tile(event):
# need to know which div was clicked here
event.targetevent is a JsProxy object that represents the "standard" JS event object.



ltk.window.document.currentScript.terminal.resize(60, 12) I am not familiar with the py-editor but maybe look for some direct handles

ltk.window.document.currentScript.terminal.resize(60, 12) I am not familiar with the py-editor but maybe look for some direct handles 
















type attribute in this section of the docs: https://docs.pyscript.net/2024.9.2/api/#pyscriptconfigpyscript.config now has a type attribute that returns either "mpy" or "py" to indicate the interpreter in which the code is running. 



pyscript.config now has a type attribute that returns either "mpy" or "py" to indicate the interpreter in which the code is running. 














python --version. So what I would like to have is the version of the PyScript that runs my script. (edited)

python --version. So what I would like to have is the version of the PyScript that runs my script. (edited)



from pyweb import pydom results to an ModuleNotFoundError error. Is this correct and if so where is pydom now? (edited)








from pyscript import to_js and to_js(python_ref)
to_js from pyscript ensures you convert to literals, no Proxies or exotic objects hard to understand from JS APIs.
output = page["#output"][0]
output.html = outputText
shows no output in the browser? output is the id of a div and outputText contains text and a display(output.html) outputs the text. So the html attribute has a value. I am using 2024.9.2.
It looks like the object page["#output][0] returns is a pyscript.web.divobject that has no attributes like html or content. (edited)





latest/pyscript.net, and what is served by releases/2024.10.1/core.js.latest, stdout and stderr are both redirected to the javascript console. However, under 2024.10.1, stdout goes to the javascript console, but errors go to the DOM. I've seen a bunch of references to this being the behavior of an error plugin that is enabled by default, and that adding a plugins=["!error"] declaration to the config can reverse this behavior... but this doesn't appear to do anything for me.This is normal content goes to the javascript console; but This is error content is added as content in red in the DOM.
<script type="mpy">, the content that is printed to the DOM is each individual ASCII value of the text, one line per value (so, "84", "104", "105", "115", "32", ...) (edited)














latest at all because latest does not exist anymore since very long time ago. We never granted feature parity with latest over the last year so while the mpy bug is something to look at and fix, we won't necessarily match latest because we had different goals with modern PyScript. /cc @ntoll
latest isnโt necessarily a goal; but โdonโt write to DOMโ should exist as an option somehow. It looks like it might have been an option in 2024.4.*, but itโs not clear that it is an option any more. (edited)
!error that indeed should indicate no error is print on the DOM. If you can provide a minmal example case in our repo we'll have a look if that's not the case and fix it, same gose for mpy printing out ASCII chars ... we did change mpy behavior "recently" to allow REPL mode and its now handling chars in a different way but that might be terminal dependent, which is why a minimal error case would be ideal. Thanks again for helping us helping you 
!error in the docs appear to have been removed, so if thatโs still an option, thatโs a notable omission.


!error in the docs appear to have been removed, so if thatโs still an option, thatโs a notable omission. 

<script type="py" src="main.py" config="pyscript_pyo.toml" terminal></script> but this is only for py. But will not workfor mpy (micropython interpreter which is faster). OR you can add this to the top of your main.py file and use print (maybe just for quick debugging, its not a useful solution (which is display()) import ltk def print(*args):
ltk.find("body").append(" ".join(str(a) for a in args), "<br>")


<script type="py" src="main.py" config="pyscript_pyo.toml" terminal></script> but this is only for py. But will not workfor mpy (micropython interpreter which is faster). OR you can add this to the top of your main.py file and use print (maybe just for quick debugging, its not a useful solution (which is display()) import ltk def print(*args):
ltk.find("body").append(" ".join(str(a) for a in args), "<br>") 








python3 -m asyncio async repl



onchange or whatever event you want to trigger on, can just pop some function











while stop == False:
user_input = input("Enter a value")
if user_input == "!":
stop = True
else:
print(user_input)
So none of that actually matters from my opinion. If you think of this more like an HTML document that just has some kind of python backend/server you'll get this awaiting by virtue of what it is. I am a huge fan of domain specific languages as doing the things they are good at is super easy and straightforward.
a basic example may look like this
<script>
function doit(value){
console.log(value)
}
</script>
some sample code here
<input type="text" onchange="doit(this.value)">
then in your pyscript you have. ...and I can't remember the exact syntax anymore it may have changed since the last time i looked
from pyscript import js
def pydoit(value):
print(f'pyscript: {value})
js.doit = pydoit # this will override the original js function (which may not be needed in the first place)
Then you just replace functions in various places for whatever you're looking to do (edited)













ltk.Input(measure).on("change", ltk.proxy(lambda event: change_param(event, uniqueid))).attr("id",uniqueid).addClass("measure")


.gone {
display: none;
}
Then you could toggle that class on and off for that dom element. To get the element you can use jquery (especially if you are using the ltk for your UI (as jquery is included) or any kind of dom selector to get the element you wish to toggle.











import helper
import boardbut helper.py and board.py not existing in the root file system but instead read from github.
I've tried to do it in my config TOML with no success...
name = "Name"
description = "..."
packages = ["numpy", "requests"]
[files]
"helper" = "https://raw.githubusercontent.com/path/to/helper.py"
"board" = "https://raw.githubusercontent.com/path/to/board.py" I've tried a bunch of combinations with quotes around helper/board, without, with .py on the end, with ./ at the start... none work. (edited)

import helper
import boardbut helper.py and board.py not existing in the root file system but instead read from github.
I've tried to do it in my config TOML with no success...
name = "Name"
description = "..."
packages = ["numpy", "requests"]
[files]
"helper" = "https://raw.githubusercontent.com/path/to/helper.py"
"board" = "https://raw.githubusercontent.com/path/to/board.py" I've tried a bunch of combinations with quotes around helper/board, without, with .py on the end, with ./ at the start... none work. (edited)micropython and pyodide examples of using the ltk - which comes from a github account like yours. Check the toml files for each example on pyscript,com - https://github.com/pyscript/ltk

micropython and pyodide examples of using the ltk - which comes from a github account like yours. Check the toml files for each example on pyscript,com - https://github.com/pyscript/ltk 


<script type="text/javascript" nonce="71340758f62d4234aed13772c61" src="//local.adguard.org?ts=1730283868492&type=content-script&dmn=pyscript.com&url=https%3A%2F%2Fpyscript.com%2Fapi%2Fcontent%2F1cbafd21-3208-4424-a703-82fae09c0d1e%252Fbb6f3633-2f1d-447e-9321-630ce990a267%252Flatest%252Findex.html&app=opera.exe&css=3&js=1&rel=1&rji=1&sbe=1"></script>
and you need to be using a modern versin of pyscript. Your link is very old and not in use anymore. Try:
<!-- Import PyScript -->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.10.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.10.2/core.js"></script>

<script type="text/javascript" nonce="71340758f62d4234aed13772c61" src="//local.adguard.org?ts=1730283868492&type=content-script&dmn=pyscript.com&url=https%3A%2F%2Fpyscript.com%2Fapi%2Fcontent%2F1cbafd21-3208-4424-a703-82fae09c0d1e%252Fbb6f3633-2f1d-447e-9321-630ce990a267%252Flatest%252Findex.html&app=opera.exe&css=3&js=1&rel=1&rji=1&sbe=1"></script>
and you need to be using a modern versin of pyscript. Your link is very old and not in use anymore. Try:
<!-- Import PyScript -->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.10.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.10.2/core.js"></script> onAfterRun hook that I would like to run a function. How I do this on my plugin? (edited)

onAfterRun hook that I would like to run a function. How I do this on my plugin? (edited)Plugins from there. I do see there is some documentation about plugins here: https://docs.pyscript.net/2024.10.2/user-guide/plugins/ I hope this helps

onAfterRun hook that I would like to run a function. How I do this on my plugin? (edited)







donkey process now exists (starts in JS) which allows you to execute the code without any startup. You copy the user's code entry to the Donkey and then shows the results. This might also be a useful approach ? The donkey is halfway down this page (so #ref sorry) https://docs.pyscript.net/2024.10.2/api/ and here is an example of its use (you can call it to execute user stuff) - https://pyscript.com/@neon22/pyscript-donkey-copy/latest?files=main.py,index.js
Maybe someone who has done this already could chime in ? (edited)







type="mpy" for micropython instead of type="py" .
<script type="mpy" src="main.py"></script> this is from the docs at https://docs.pyscript.net/2024.10.2/user-guide/first-steps/


afterStartup() method https://github.com/pyscript/pyscript/blob/25809660efab80046d75314b14c08ff2c5d6194e/pyscriptjs/src/main.ts#L197 
addEventListener('py:ready', () => loading.close());document.addEventListener('py:ready', function () {

donkey process now exists (starts in JS) which allows you to execute the code without any startup. You copy the user's code entry to the Donkey and then shows the results. This might also be a useful approach ? The donkey is halfway down this page (so #ref sorry) https://docs.pyscript.net/2024.10.2/api/ and here is an example of its use (you can call it to execute user stuff) - https://pyscript.com/@neon22/pyscript-donkey-copy/latest?files=main.py,index.js
Maybe someone who has done this already could chime in ? (edited)

donkey process now exists (starts in JS) which allows you to execute the code without any startup. You copy the user's code entry to the Donkey and then shows the results. This might also be a useful approach ? The donkey is halfway down this page (so #ref sorry) https://docs.pyscript.net/2024.10.2/api/ and here is an example of its use (you can call it to execute user stuff) - https://pyscript.com/@neon22/pyscript-donkey-copy/latest?files=main.py,index.js
Maybe someone who has done this already could chime in ? (edited)



addEventListener('py:ready', () => loading.close()); py:all-done

py:all-done 

<script>
document.addEventListener('DOMContentLoaded', function () {
console.log('DOM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
document.addEventListener('py:all-done', function () {
console.log('PY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
});
});
</script>
js.window.dispatchEvent(js.window.Event.new("python-done")); (edited)







<py-config>
packages = ["pandas"]
</py-config> (edited)



nltk.download("words") no matter if I try it the default way or unzipping the actual words.zip into my project. It can't find it

from pyscript import document, window
from pyscript.ffi import create_proxy
class Canvas:
def __init__(self, id, width=64*9, height=64*9):
self.canvas = document.querySelector(id)
self.ctx = self.canvas.getContext('2d')
self.canvas.height = height
self.canvas.width = width
self.y = 100
self.set_bg_color('black')
self.animation()
def clear(self, color='black', pos=(0,0), size=None):
x,y = pos
if size:
width, height = size
else:
width, height = (self.canvas.width, self.canvas.height)
self.ctx.fillStyle = color
self.ctx.clearRect(x,y,width,height)
def set_bg_color(self, color):
self.ctx.fillStyle = color
self.ctx.fillRect(0, 0, self.canvas.width, self.canvas.height)
def animation(self):
self.ctx.fillStyle = 'red'
self.ctx.fillRect(100, self.y, 100, 100)
self.y += 1
self.clear()
proxy = create_proxy(self.animation)
window.requestAnimationFrame(proxy)
i get this error Uncaught PythonError: TypeError: Canvas.animation() takes 1 positional argument but 2 were given
py-editor? I understand that it uses CodeMirror and I feel like it shouldn't be too hard to use a different code mirror theme, but I don't see a way other than cloning down the pyscript project and changing it there. Surely, I can just override the css somehow, but I am a... back end engineer.
py-editor div and it loaded that theme. (edited)
<script type="mpy-editor" config="pyscript.toml" env="env" src="init.py" setup></script>
<script type="mpy-editor" env="env" target="editor" id="client-script">
is there a way to get the worker the editor is running within the setup stage somehow and call worker.terminate() when needed? (tie it into a button click handler?)
Sorry, I am new, and it seems a bit confusing... (edited)

<script type="mpy-editor" config="pyscript.toml" env="env" src="init.py" setup></script>
<script type="mpy-editor" env="env" target="editor" id="client-script">
is there a way to get the worker the editor is running within the setup stage somehow and call worker.terminate() when needed? (tie it into a button click handler?)
Sorry, I am new, and it seems a bit confusing... (edited)pyscript.window to add a global stop_flag to test for it within script. But I still would like to stop it when it's unresponsive without having to refresh the page...

<script type="mpy-editor" config="pyscript.toml" env="env" src="init.py" setup></script>
<script type="mpy-editor" env="env" target="editor" id="client-script">
is there a way to get the worker the editor is running within the setup stage somehow and call worker.terminate() when needed? (tie it into a button click handler?)
Sorry, I am new, and it seems a bit confusing... (edited)xworker attached where you can invoke terminate() any time you need.
INFO: 127.0.0.1:49266 - "GET /get_uuid HTTP/1.1" 200 OK
Traceback (most recent call last):
File "/lib/python312.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
File "/lib/python312.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 5, in <module>
File "/home/pyodide/c_and_c_client.py", line 14, in get_uuid
response = await fetch("http://localhost:8000/get_uuid")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python312.zip/pyodide/webloop.py", line 108, in callback
r = onrejected_(e)
^^^^^^^^^^^^^^
File "/lib/python312.zip/pyodide/webloop.py", line 102, in onrejected_
raise x
pyodide.ffi.JsException: TypeError: Failed to fetch

import pyscript
from pyodide.http import pyfetch
what_to_use = ["default_file_specified_in_TOML"]
async def custom_load(event):
x = pyscript.document.querySelector("#user_option").value
value_mappings = {"some": "collection", "of": "values", "mapped": "to_urls"}
if x:
nu_file = await pyfetch(value_mappings[x])
what_to_use.append(nu_file)
def do_it(event):
for f in what_to_use:
foo(f, data_specified_by_user) #process the data_specified_by_user using f
My index.html file has buttons with the py-click option for both the do_it() function (to be clicked when the user specifies data) and the custom_load() function (to be clicked when the user customizes options). These functions work as intended. EXCEPT:
what_to_use that was specified outside of custom_load()
Addressing some sideshows: open_url() and fetch() I am happy to use whichever one is best

import pyscript
from pyodide.http import pyfetch
what_to_use = ["default_file_specified_in_TOML"]
async def custom_load(event):
x = pyscript.document.querySelector("#user_option").value
value_mappings = {"some": "collection", "of": "values", "mapped": "to_urls"}
if x:
nu_file = await pyfetch(value_mappings[x])
what_to_use.append(nu_file)
def do_it(event):
for f in what_to_use:
foo(f, data_specified_by_user) #process the data_specified_by_user using f
My index.html file has buttons with the py-click option for both the do_it() function (to be clicked when the user specifies data) and the custom_load() function (to be clicked when the user customizes options). These functions work as intended. EXCEPT:
what_to_use that was specified outside of custom_load()
Addressing some sideshows: open_url() and fetch() I am happy to use whichever one is best

# - to find rawgithub url - append `?raw=true` to url in browser
# and use resolved url which will come from raw.githubusercontent.com
I.e. just navigate to the url you want to use and put that on the end and hit return = rawgithub url (edited)








# - to find rawgithub url - append `?raw=true` to url in browser
# and use resolved url which will come from raw.githubusercontent.com
I.e. just navigate to the url you want to use and put that on the end and hit return = rawgithub url (edited)

py_import() will not work, since these are not .py files.

[files]
"https://raw.githubusercontent.com/Neon22/pyweaving/wif-missing-warp/src/pyweaving/data/pyweaving-logo-1-84sq.png" = "logo-1-84sq.png"
allows me to reference it inside the python code as "./logo-1-84sq.png"
If you are looking to load js/css files then the ltk uses this approach:
[files]
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.js" = "ltk/ltk.js"
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.css" = "ltk/ltk.css"
as well as having this also in the toml file:
packages = [ "pyscript-ltk"]
then you just import ltk in your python file.
But not sure what kind of task you are trying to do.

[files]
"https://raw.githubusercontent.com/Neon22/pyweaving/wif-missing-warp/src/pyweaving/data/pyweaving-logo-1-84sq.png" = "logo-1-84sq.png"
allows me to reference it inside the python code as "./logo-1-84sq.png"
If you are looking to load js/css files then the ltk uses this approach:
[files]
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.js" = "ltk/ltk.js"
"https://raw.githubusercontent.com/pyscript/ltk/main/ltk/ltk.css" = "ltk/ltk.css"
as well as having this also in the toml file:
packages = [ "pyscript-ltk"]
then you just import ltk in your python file.
But not sure what kind of task you are trying to do. 

foo = []
def bar(event):
for o in values_specified_by_users_on_the_html_side: foo.append(o)
def baz(event):
for f in foo: print(f)
I assumed that when a user clicked a button with py-click=bar specified, foo would get updated, and then when they clicked a button with py-click=baz specified, the updated value of foo would be accessed. But it isn't. Only the initial value of foo is used inside baz.
UPDATE: I had been thinking that I was being clever and avoiding having to tangle with async and await (probably inspired by this discussion of just putting user data straight into a python data structure https://github.com/pyscript/pyscript/discussions/1146). Ultimately, could an approach like that work to add the results of three optional upload buttons to a containing python data structure, and then use that data structure? Or do I need to base my approach off of @Jeff Glass's demo here (https://jeff.glass/post/pyscript-image-upload/) ? At this late hour I am having trouble seeing where I should stash the various optional uploaded files before ultimately using them in my main function.
Very many thanks to anyone who looks at this 

foo = []
def bar(event):
for o in values_specified_by_users_on_the_html_side: foo.append(o)
def baz(event):
for f in foo: print(f)
I assumed that when a user clicked a button with py-click=bar specified, foo would get updated, and then when they clicked a button with py-click=baz specified, the updated value of foo would be accessed. But it isn't. Only the initial value of foo is used inside baz.
UPDATE: I had been thinking that I was being clever and avoiding having to tangle with async and await (probably inspired by this discussion of just putting user data straight into a python data structure https://github.com/pyscript/pyscript/discussions/1146). Ultimately, could an approach like that work to add the results of three optional upload buttons to a containing python data structure, and then use that data structure? Or do I need to base my approach off of @Jeff Glass's demo here (https://jeff.glass/post/pyscript-image-upload/) ? At this late hour I am having trouble seeing where I should stash the various optional uploaded files before ultimately using them in my main function.
Very many thanks to anyone who looks at this py- event listeners are deprecated


@when decorator might be a starter https://docs.pyscript.net/2024.10.2/api/#pyscriptwhen

os.walk and it appears they just aren't on the virtual filesystem at all. The content of these files is just text, but the names are not static. It doesn't seem like includes/pkl/* is a legal files entry in config.json, is there another way? (edited)

os.walk and it appears they just aren't on the virtual filesystem at all. The content of these files is just text, but the names are not static. It doesn't seem like includes/pkl/* is a legal files entry in config.json, is there another way? (edited)

ImportError: no module named 'ulab' yet https://pyscript.net/tech-preview/micropython/repl.html lets me import ulab?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Test</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.10.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.10.2/core.js"></script>
</head>
<body>
<script type="mpy">import ulab</script>
</body>
</html>



ImportError: no module named 'ulab' yet https://pyscript.net/tech-preview/micropython/repl.html lets me import ulab?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Test</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.10.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.10.2/core.js"></script>
</head>
<body>
<script type="mpy">import ulab</script>
</body>
</html> 

tech-preview doesn't declare it

tech-preview doesn't declare it 



import ulab then hit enter.
USER_C_MODULES=../../../micropython-ulab/ whereas https://github.com/micropython/micropython/blob/master/ports/webassembly/Makefile does not?



rowspan attribute for some tds, but even though I'm passing the rowspan=... attribute to web.td(..., rowspan=...), the generated HTML doesn't have that attribute
any suggestions on how to solve my issue?

rowspan attribute for some tds, but even though I'm passing the rowspan=... attribute to web.td(..., rowspan=...), the generated HTML doesn't have that attribute
any suggestions on how to solve my issue? document.createElement; that solved the issue and allowed me to set rowspan as needed

type="py" runs fast enough and type="mpy" is slow. I am pre-allocating maxlen even though the algorithm doesn't require it because I read something about micropython and allocations. I replaced the generator expression by an inner loop but that didn't help. What else can it be? Is this just MarkdownContext { Depth = 1 } or worth an issue?



Uncaught TypeError: crypto.randomUUID is not a function
<anonymous> main.js:43
Can someone let me know what's going on?
code here:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<h1>hello world</h1>
<script type="mpy">
print('hello world')
</script>
</body>
</html>

Uncaught TypeError: crypto.randomUUID is not a function
<anonymous> main.js:43
Can someone let me know what's going on?
code here:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<h1>hello world</h1>
<script type="mpy">
print('hello world')
</script>
</body>
</html> 

Uncaught TypeError: crypto.randomUUID is not a function
<anonymous> main.js:43
Can someone let me know what's going on?
code here:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
</head>
<body>
<h1>hello world</h1>
<script type="mpy">
print('hello world')
</script>
</body>
</html> 
http:// without the s) you need to instrument your browser to trust that URL but this is not about PyScript, this is how the entirety of most recent Web APIs work.

http:// without the s) you need to instrument your browser to trust that URL but this is not about PyScript, this is how the entirety of most recent Web APIs work. https:// (with the s) through local network, but I am afraid that also requires you explicitly adding, and taking care of, those home-made certificates, which is slightly out of this project scope/goal to help with.

https:// (with the s) through local network, but I am afraid that also requires you explicitly adding, and taking care of, those home-made certificates, which is slightly out of this project scope/goal to help with. localhost has a special place in browsers' heart ... make it any http://127.0.10.7:8080/ and goodbye secure related features of the Web.http://192.168.27.3:8080 or any similar IP based approachhttps to work at all.



package_name==1.2.3 convention, where 1.2.3 is the exact version and package_name is numpy, matplotlib or any other package you like. That ensures you will use the exact same version in the future. Add the fact we have a micropip cache to guarantee further that, you should be fine?













window.process_data(filteredData); (edited)

index_url as config field landed already, feel free to use it if needed.
class Page(TemplateView):
template_name = "page.html"
def get(self, request):
response = render(request, self.template_name)
response.headers = {"Access-Control-Allow-Origin": "*",
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Resource-Policy": "cross-origin"}
return response
class Script(View):
def get(self, request):
path = request.path.split('/')[-1].replace('..','')
try:
file = open(os.path.join(settings.BASE_DIR, f'goop/{path}'), 'r')
return HttpResponse(file.read(), content_type='text/plain',
headers={"Access-Control-Allow-Origin": "*",
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
"Cross-Origin-Resource-Policy": "cross-origin"})
except Exception as e:
raise e

page.append(div("foo", id="#foo"))
page["#foo"].textContent = "bar"
adds foo successfully but does not change it to bar. document.getElementById("#foo").textContent = "bar" in the console works fine. (edited)






























def update_date_range(self, date_range):
print('Updating date range...')
start_date, end_date = date_range
start_ms = start_date.timestamp() * 1000
end_ms = end_date.timestamp() * 1000
self._date_range.noUiSlider.updateOptions({
'range': {
'min': start_ms,
'max': end_ms
},
'start': [start_ms, end_ms]
}, True)
self._date_range.noUiSlider.set([start_ms, end_ms])
print('Completed!') (edited)
to_js({ ... }) . See https://docs.pyscript.net/2024.3.2/user-guide/builtins/#pyscriptffito_js (edited)

to_js({ ... }) . See https://docs.pyscript.net/2024.3.2/user-guide/builtins/#pyscriptffito_js (edited)from pyscript.ffi import to_js would be my pick as it automatically pass object literals instead of maps, but with latest Pyodide even those maps should work out of the box (in theory, not all APIs are happy about those).

from pyscript.ffi import to_js would be my pick as it automatically pass object literals instead of maps, but with latest Pyodide even those maps should work out of the box (in theory, not all APIs are happy about those). 
to_js now 
from pyodide.ffi import to_js
def update_date_range(self, date_range):
print('Updating date range...')
start_date, end_date = date_range
start_ms = start_date.timestamp() * 1000
end_ms = end_date.timestamp() * 1000
options = {
'range': {
'min': start_ms,
'max': end_ms
},
'start': [start_ms, end_ms]
}
js_options = to_js(options)
self._date_range.noUiSlider.updateOptions(js_options, True)
self._date_range.noUiSlider.set(to_js([start_ms, end_ms]))
print('Completed!') (edited)

to_js({ ... }) . See https://docs.pyscript.net/2024.3.2/user-guide/builtins/#pyscriptffito_js (edited)self._date_range.noUiSlider.updateOptions(to_js({
'range': {
'min': start_ms,
'max': end_ms
}
}), True) (edited)button1.addEventListener('click', function () {
updateSlider.noUiSlider.updateOptions({
range: {
'min': 20,
'max': 50
}
});
});
options = {'range': {'min': 0, 'max': 200}}
js_options = to_js(options, dict_converter=js.Object.fromEntries) (edited)

options = {'range': {'min': 0, 'max': 200}}
js_options = to_js(options, dict_converter=js.Object.fromEntries) (edited)

options = {'range': {'min': 0, 'max': 200}}
js_options = to_js(options, dict_converter=js.Object.fromEntries) (edited)

from pyodide.ffi import to_js
def update_date_range(self, date_range):
print('Updating date range...')
start_date, end_date = date_range
start_ms = start_date.timestamp() * 1000
end_ms = end_date.timestamp() * 1000
options = {
'range': {
'min': start_ms,
'max': end_ms
},
'start': [start_ms, end_ms]
}
js_options = to_js(options)
self._date_range.noUiSlider.updateOptions(js_options, True)
self._date_range.noUiSlider.set(to_js([start_ms, end_ms]))
print('Completed!') (edited)from pyscript.ffi import to_js if you never want surprises (edited)

from pyscript.ffi import to_js if you never want surprises (edited)

from pyscript.ffi import to_js no error, we also have integration tests so I am not sure what kind of error you are seeing or why


pyscript package. However, this code works fine for me in the browser in the context of PyScript (tested also on v2024.11.1).

[pyexec] Python exception:
Traceback (most recent call last):
File "/home/pyodide/pyscript/_internal.py", line 104, in run_pyscript
result = eval_code(code, globals=__main__.__dict__)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 468, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 310, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 5, in <module>
ModuleNotFoundError: No module named 'pyscript.ffi' (edited)

[pyexec] Python exception:
Traceback (most recent call last):
File "/home/pyodide/pyscript/_internal.py", line 104, in run_pyscript
result = eval_code(code, globals=__main__.__dict__)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 468, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 310, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 5, in <module>
ModuleNotFoundError: No module named 'pyscript.ffi' (edited)

[pyexec] Python exception:
Traceback (most recent call last):
File "/home/pyodide/pyscript/_internal.py", line 104, in run_pyscript
result = eval_code(code, globals=__main__.__dict__)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 468, in eval_code
.run(globals, locals)
^^^^^^^^^^^^^^^^^^^^
File "/lib/python311.zip/_pyodide/_base.py", line 310, in run
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 5, in <module>
ModuleNotFoundError: No module named 'pyscript.ffi' (edited)<head> of your HTML). See: https://pyscript.net/releases/2024.11.1/




pyscript.interpreter.globals.
function verificarPyScriptAsync() {
return new Promise(function (resolve) {
function verificar() {
try {
if (!pyscript.interpreter.globals) {
setTimeout(verificar, 500);
} else {
//console.log("Python Liberado:" + new Date());
hideLoadingImage();
resolve(); // Resolvendo a Promise quando a condiรงรฃo รฉ atendida
}
} catch (ex) {
setTimeout(verificar, 500);
}
}
verificar(); // Inicia a verificaรงรฃo
});
}`


pyscript.interpreter.globals.
function verificarPyScriptAsync() {
return new Promise(function (resolve) {
function verificar() {
try {
if (!pyscript.interpreter.globals) {
setTimeout(verificar, 500);
} else {
//console.log("Python Liberado:" + new Date());
hideLoadingImage();
resolve(); // Resolvendo a Promise quando a condiรงรฃo รฉ atendida
}
} catch (ex) {
setTimeout(verificar, 500);
}
}
verificar(); // Inicia a verificaรงรฃo
});
}` pyscript globally, it's been over a year now ... we have py:ready event triggered, if needed to know when PyScript is ready. Use Promise.withResolvers() around to resolve whatever you need so you never need ever again a setTimeout dance. There are also hooks ... in few words, PyScript has been different for a long time, that latest end point only caused troubles for the present and future of the project.



<script type="mpy" terminal worker>import code; code.interact()</script> these days, it's in the docs https://docs.pyscript.net/2024.11.1/user-guide/terminal/ (edited)









pyscript globally, it's been over a year now ... we have py:ready event triggered, if needed to know when PyScript is ready. Use Promise.withResolvers() around to resolve whatever you need so you never need ever again a setTimeout dance. There are also hooks ... in few words, PyScript has been different for a long time, that latest end point only caused troubles for the present and future of the project. pyscript.interpreter.globals.get('gerarElementos')(dicionarioConfigElementos, listaElementos) to call my functions in the Python file.
My functions arenโt triggered by a button, but rather by events happening in the back-end (arrival of new data, visiting a specific location in the view, loading multiple charts simultaneously, etc.). Without interpreter.globals, how should I call a specific function from my Python file?

pyscript.web for working with the DOM. We just proxy the attributes from the underlying JS objects, so innerText, innerHtml, etc... should just work as the docs on W3 schools or MDN say. Anything AI says is likely to be wrong. 

pyscript.web namespace and other upcoming APIs are designed to give you access to web-by stuff but in a Pythonic manner).







fetch https://docs.pyscript.net/2024.11.1/api/#pyscriptfetch or anything really on window

fetch https://docs.pyscript.net/2024.11.1/api/#pyscriptfetch or anything really on window 




start_button.style["display"] = "none" But could I just remove it from the parent element somehow?main.remove(start_button) would be good, but I don't see any option like that

start_button.style["display"] = "none" But could I just remove it from the parent element somehow? 





myimage I would eventually like to insert that SVG into a canvas, but at the moment I will just settle for getting it to display on the page.
I have a div with an id of "foo" I use
mydiv = page.find("#foo") to get the div, and then I try mydiv.append(myimage) However, that results in this error:
File "/lib/python312.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
File "/lib/python312.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 11, in <module>
TypeError: 'list' object is not callable
I'm unsure what I might be doing wrong.

myimage I would eventually like to insert that SVG into a canvas, but at the moment I will just settle for getting it to display on the page.
I have a div with an id of "foo" I use
mydiv = page.find("#foo") to get the div, and then I try mydiv.append(myimage) However, that results in this error:
File "/lib/python312.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
File "/lib/python312.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 11, in <module>
TypeError: 'list' object is not callable
I'm unsure what I might be doing wrong. window.Image.new() and then set its .src to a data URL that represents such SVG then you have an image ... that represents an SVG ... not sure canvas in general understands out of the box SVG elements as image otherwise

window.Image.new() and then set its .src to a data URL that represents such SVG then you have an image ... that represents an SVG ... not sure canvas in general understands out of the box SVG elements as image otherwise 

window.Image.new() and then set its .src to a data URL that represents such SVG then you have an image ... that represents an SVG ... not sure canvas in general understands out of the box SVG elements as image otherwise 





.src with a data-uri that represent that SVG, once .onload happens, you pass that image to the canvas and it'll do the right thing ... passing right away the SVG, AFAIK, and IIRC, would not work.


const svg = `
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6" />
<line x1="8" y1="2" x2="8" y2="18" />
<line x1="16" y1="6" x2="16" y2="22" />
</svg>
`.trim();
const image = new Image;
image.src = `data:image/svg+xml;utf8,${svg}`;
image.onload = () => {
document.body.append(image);
};
you can do that via PyScript directly, the result would be the same.


from pyscript import document, window
svg = '''
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6" />
<line x1="8" y1="2" x2="8" y2="18" />
<line x1="16" y1="6" x2="16" y2="22" />
</svg>
'''.strip()
image = window.Image.new()
image.src = f'data:image/svg+xml;utf8,{svg}'
image.onload = lambda e: document.body.append(image) (edited)


[files] in your config toml to put the module in your virtual FS on bootstrap and it'll be there ready to use.

[files] in your config toml to put the module in your virtual FS on bootstrap and it'll be there ready to use. 


npm i @pyscript/core the version is 0.6.23. Where is the mysterious version 0.6.23 located?


npm i @pyscript/core the version is 0.6.23. Where is the mysterious version 0.6.23 located? npm ... we have canary releases in there, you should use our official stable version instead

npm ... we have canary releases in there, you should use our official stable version instead 

npm i @pyscript/core the version is 0.6.23. Where is the mysterious version 0.6.23 located? npm version is for easy development and for easy reachability, it's not meant to be used for any production purpose, you need to use our official releases for that, currently we are here: https://pyscript.net/releases/2024.11.1/core.jsnpm versions might break, won't likely be documented (part of the release process) and so on ... it's in our docs but of course one must know where to look at in there ... not sure how else we could mention it but maybe having a first paragraph on the npm README might help.






latest out there, for every library or software, it was a bad decision to provide that and we're all paying the consequenceses these days, sorry you are having issues now but I am sure it was never meant, or advertised, to be used for production purposes.


npm versions might break, won't likely be documented (part of the release process) and so on ... it's in our docs but of course one must know where to look at in there ... not sure how else we could mention it but maybe having a first paragraph on the npm README might help. 
















Introduction.html is probably the file to rename to index.html (it is the only one with a python script tag). the main.json file looks like a config.toml file (although unreferenced in the potential index.html). The code.html looks like a 1980's basic program (no disrespect intended) converted to python but I don't understand its purpose. Sorry we can't work out what you're trying to do.

Introduction.html is probably the file to rename to index.html (it is the only one with a python script tag). the main.json file looks like a config.toml file (although unreferenced in the potential index.html). The code.html looks like a 1980's basic program (no disrespect intended) converted to python but I don't understand its purpose. Sorry we can't work out what you're trying to do. 










fetch https://docs.pyscript.net/2024.11.1/api/#pyscriptfetch or anything really on window 



from pyscript import window
def callPythonFooFromJS(event, jsData):
# do something with the jsData
return [3, 2, 1]
window.callPythonFooFromJS = callPythonFooFromJS
then you have a py:all-done event on the main meaning all your scripts have been executed and there you'll have your function



3.12.1 (main, Nov 15 2024, 14:17:00) [Clang 19.0.0git doesn't tell which Pyodide we're using. Pyodide might be based on the same C-Python version and yet have fixed internal Pyodide only bugs while releasing and the same goes for MicroPython. (edited)type field, py or mpy, we don't have pyodide or micropython fields, which could be instrumented to expose the currently used version. That would also work only out of our build steps, but maybe somewhere pyodide, or micropython, expose that detail ... which would make it easier to show that on that very same page too ... I'll check it once back from vacations. (edited)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terminal</title>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.11.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.11.1/core.js"></script>
</head>
<body>
<div>
<button id="btn-run">Run</button>
</div>
<div>
<script id="my_terminal" type="mpy" terminal worker>print("First is OK")</script>
</div>
<script>
const runButton = document.getElementById('btn-run');
runButton.onclick = async () => {
const myterm = document.querySelector("#my_terminal");
await myterm.process('print("This doesnt show")');
};
</script>
</body>
</html> (edited)
option in multiple selects. No big deal, I can always rebuild the list of options, just wondering if there's a way to do it that I'm misisng.





https://pyscript.net/latest/pyscript.js but modern examples show something like https://pyscript.net/releases/2024.10.2/core.css -- I can see that the releases usually align with the tags on pyscript/pyscript but older tags aren't viable. So just wondering if there's a list of versions that the releases exist for, or something like that.

https://pyscript.net/latest/pyscript.js but modern examples show something like https://pyscript.net/releases/2024.10.2/core.css -- I can see that the releases usually align with the tags on pyscript/pyscript but older tags aren't viable. So just wondering if there's a list of versions that the releases exist for, or something like that. latest seemed like a good idea at the time but the continual improvements to a new project like pyscript meant old code would subtly fail. So now deprecated and removed to avoid confusion. Check docs for latest (its in the dropdown at the top). Personally recommend always looking for the newest one and using that. So far every step has been continual improvement 

print() if using pyodide. Can import https://github.com/gruns/icecream if you want an improvement over print.
Can also use something like this if not using terminal (in pyodide and in mpy)
import ltk
def print(*args):
ltk.find("body").append(" ".join(str(a) for a in args), "<br>")
and then you can print to the dom instead of a dedicated terminal (which takes up room).
Or use the logger - ltk has a nic logger.... (edited)

print() if using pyodide. Can import https://github.com/gruns/icecream if you want an improvement over print.
Can also use something like this if not using terminal (in pyodide and in mpy)
import ltk
def print(*args):
ltk.find("body").append(" ".join(str(a) for a in args), "<br>")
and then you can print to the dom instead of a dedicated terminal (which takes up room).
Or use the logger - ltk has a nic logger.... (edited)


pyscript.toml through the CLI, akin to how poetry will udpate your pyproject.toml ?

pyscript.toml through the CLI, akin to how poetry will udpate your pyproject.toml ?packages = []

packages = [] 
docker compose up --build to relaunch with the changes
<script type="py" src="../../scripts/example/example.py" config="../../scripts/pyscript.toml"></script>
<script type="py" src="../../tests/main.py" config="../../tests/pyscript.toml" terminal></script>
And I've noticed that even if the contents of the files is the same, neither of them is even requested. Are configs only loaded if only one config is used on a single page?
upytest question on top of that one; say I have the following html
<input type="text" id="input_number" placeholder="Type number here..." />
<button id="do_a_thing_button" py-click="do_a_thing">Get next value</button>
<div id="output_number"></div>
<script type="py" src="../../scripts/example/example.py" config="../../scripts/pyscript.toml"></script>
<script type="py" src="../../tests/main.py" config="../../scripts/pyscript.toml" terminal></script>
And the py-click="do_a_thing" that is brough in from the src="../../scripts/example/example.py" is
def do_a_thing(event):
input_text = document.querySelector("#input_number")
input_number = input_text.value
output_div = document.querySelector("#output_number")
output_div.innerText = str(1+int(input_number))
And the src="../../tests/main.py" is doing upytest ~
import json
from base import upytest
from pyscript import web
results = await upytest.run("./tests")
output = web.div(json.dumps(results), id="results")
web.page.append(output)import asyncio
from pyscript import document, web, when
async def test_example():
input_container = document.querySelector("#input_number")
input_container.value = "101"
just_a_button = web.page.find("#do_a_thing_button")[0]
call_flag = asyncio.Event()
@when("click", just_a_button)
def on_click(event):
call_flag.set()
# Now let's simulate a click on the button (using the low level JS API)
# so we don't risk dom getting in the way
just_a_button._dom_element.click()
await call_flag.wait()
output_container = document.querySelector("#output_number")
assert output_container.innerHTML == "102", output_container.innerHTML
(trying to learn how to put this together so it looks very similar to how upytest is used in pyscript core) --
My question is -- is there any way that the upytest executing in the second <script> that's discovered the test_example to await the execution of the do_a_thing run from the first <script>? I can see the result is appearing as expected on the page, but there's obviously a race, because the test is failing (but obviously passes if I add the on-click function into the test)
















packages = [] 
invent framework that watches my code directories as I develop, and automagically rebuilds and gzips the assets, so I just have to re-load the browser to run the test suite, test the examples etc... https://github.com/invent-framework/invent/blob/main/utils/serve.py (although I just noticed a speeling mistaik... I should know how to spell "handler"). 





invent framework that watches my code directories as I develop, and automagically rebuilds and gzips the assets, so I just have to re-load the browser to run the test suite, test the examples etc... https://github.com/invent-framework/invent/blob/main/utils/serve.py (although I just noticed a speeling mistaik... I should know how to spell "handler"). 
upytest question above. I am assuming that the intent of upytest is to run a test suite on a page by interacting with the elements and whatnot -- similar browser automation tests e.g. selenium -- but my problem is that I can't just "add" a <script type="py" src="main.py" config="pyscript.toml" terminal></script> sort of script, to test an already present script, because there's a race condition, i.e. the script that I already have on the page AND the upytest invoking script. Having both, the page behaves as expected but obviously the upytest case finishes ahead of when the page actually updates so reports it failed. The only reliable way I can get upytest to assert the result of another script is by including the required scripts in my [files], importing the actual script into the test script and executing the function from within the test case upytest runs -- which feels like a lot of manual decoration as well as being a pretty big gap between "having the thing be the way it is and test it as is" and "have a test pretend to be the actual thing and just test itself not the actual thing" -- so I can't tell if I'm just wildly misunderstanding the intent or how to use upytest.

upytest question above. I am assuming that the intent of upytest is to run a test suite on a page by interacting with the elements and whatnot -- similar browser automation tests e.g. selenium -- but my problem is that I can't just "add" a <script type="py" src="main.py" config="pyscript.toml" terminal></script> sort of script, to test an already present script, because there's a race condition, i.e. the script that I already have on the page AND the upytest invoking script. Having both, the page behaves as expected but obviously the upytest case finishes ahead of when the page actually updates so reports it failed. The only reliable way I can get upytest to assert the result of another script is by including the required scripts in my [files], importing the actual script into the test script and executing the function from within the test case upytest runs -- which feels like a lot of manual decoration as well as being a pretty big gap between "having the thing be the way it is and test it as is" and "have a test pretend to be the actual thing and just test itself not the actual thing" -- so I can't tell if I'm just wildly misunderstanding the intent or how to use upytest. <script type="py"> (with or without terminal attribute) and then avoid race conditions until such script py:ready event is triggered (or other events, all listed in our docs). Maybe this way you can do what you are trying to do with ease?

upytest question above. I am assuming that the intent of upytest is to run a test suite on a page by interacting with the elements and whatnot -- similar browser automation tests e.g. selenium -- but my problem is that I can't just "add" a <script type="py" src="main.py" config="pyscript.toml" terminal></script> sort of script, to test an already present script, because there's a race condition, i.e. the script that I already have on the page AND the upytest invoking script. Having both, the page behaves as expected but obviously the upytest case finishes ahead of when the page actually updates so reports it failed. The only reliable way I can get upytest to assert the result of another script is by including the required scripts in my [files], importing the actual script into the test script and executing the function from within the test case upytest runs -- which feels like a lot of manual decoration as well as being a pretty big gap between "having the thing be the way it is and test it as is" and "have a test pretend to be the actual thing and just test itself not the actual thing" -- so I can't tell if I'm just wildly misunderstanding the intent or how to use upytest. upytest to scratch an itch - just catching up post-holidays). Yes, the intent is for upytest to be a PyTest-ish framework for unit testing in the browser with PyScript (working with both MicroPython and Pyodide).
I think I should probably update the README in the github repository to explain how to "idiomatically" use it. But the tl;dr is that there should be a test page specifically for your test suite... in which you copy over your project, its test suite and reference upytest too. Then you do something like:
import upytest
await upytest.run("./tests")
You can see this pattern in the test suite for the Invent framework here: https://github.com/invent-framework/inventinvent module and the associated tests directory into a foo.tgz file that I simply unzip onto the filesystem. I also copy over the upytest module too. This setup is found here: https://github.com/invent-framework/invent/blob/main/static/settings.json
If you look at index.html in the root of that repository, you'll see where it all comes together.











help> modules pyscript
Here is a list of modules whose name or summary contains 'pyscript'.
If there are any, enter a module name to get more help.
pyscript
pyscript.display
pyscript.event_handling
pyscript.magic_js
pyscript.util

help> modules pyscript
Here is a list of modules whose name or summary contains 'pyscript'.
If there are any, enter a module name to get more help.
pyscript
pyscript.display
pyscript.event_handling
pyscript.magic_js
pyscript.util 



upytest to scratch an itch - just catching up post-holidays). Yes, the intent is for upytest to be a PyTest-ish framework for unit testing in the browser with PyScript (working with both MicroPython and Pyodide).
I think I should probably update the README in the github repository to explain how to "idiomatically" use it. But the tl;dr is that there should be a test page specifically for your test suite... in which you copy over your project, its test suite and reference upytest too. Then you do something like:
import upytest
await upytest.run("./tests")
You can see this pattern in the test suite for the Invent framework here: https://github.com/invent-framework/invent <script type="py" to test the functionality of the other script and whether or not the other script is successfully updating the correct elements on the page or not. So I'd have two <script type="py" on each of several pages, one that is "the regular script to test" and one that is "the upytest invoker" but my problem is that the upytest invoker is unaware of or unable to wait on the timing of the other script completing its action.


?test=true to the URL. E.g. perhaps use something like this..? (This is raw untested code written without trying it out):
from pyscript import window
if window.location.endswith("?test=true"):
# start the tests
This code won't work, but you get the idea.














to_py method in the pyodide ffi module. Not sure if its the right thing.. - https://pyodide.org/en/stable/usage/api/python-api/ffi.html





packages = [""] in the toml config file and import it in your main.py file. Can't speak to how its design would intehrate to being run from inside the browser - as its designed for diff use. YMMV

packages = [""] in the toml config file and import it in your main.py file. Can't speak to how its design would intehrate to being run from inside the browser - as its designed for diff use. YMMV Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/lib/python3.12/site-packages/micropip/_commands/install.py", line 146, in install
raise ValueError(
ValueError: Can't find a pure Python 3 wheel for: 'yattag'
See: https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package
at new_error (pyodide.asm.js:10:9958)
at pyodide.asm.wasm:0x16dd24
at pyodide.asm.wasm:0x1777ca
at _PyEM_TrampolineCall_JS (pyodide.asm.js:10:123144)
at pyodide.asm.wasm:0x1c2f97
at pyodide.asm.wasm:0x2c7d12
at pyodide.asm.wasm:0x20a96c
at pyodide.asm.wasm:0x1c3684
at pyodide.asm.wasm:0x1c3993
at pyodide.asm.wasm:0x1c3a11
at pyodide.asm.wasm:0x29ea60
at pyodide.asm.wasm:0x2a5057
at pyodide.asm.wasm:0x1c3b51
at pyodide.asm.wasm:0x1c37ba
at pyodide.asm.wasm:0x176e2a
at callPyObjectKwargs (pyodide.asm.js:10:62076)
at Module.callPyObjectMaybePromising (pyodide.asm.js:10:63254)
at wrapper (pyodide.asm.js:10:27079)
at onGlobalMessage (pyodide.asm.js:10:99160) (edited)

Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/lib/python3.12/site-packages/micropip/_commands/install.py", line 146, in install
raise ValueError(
ValueError: Can't find a pure Python 3 wheel for: 'yattag'
See: https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package
at new_error (pyodide.asm.js:10:9958)
at pyodide.asm.wasm:0x16dd24
at pyodide.asm.wasm:0x1777ca
at _PyEM_TrampolineCall_JS (pyodide.asm.js:10:123144)
at pyodide.asm.wasm:0x1c2f97
at pyodide.asm.wasm:0x2c7d12
at pyodide.asm.wasm:0x20a96c
at pyodide.asm.wasm:0x1c3684
at pyodide.asm.wasm:0x1c3993
at pyodide.asm.wasm:0x1c3a11
at pyodide.asm.wasm:0x29ea60
at pyodide.asm.wasm:0x2a5057
at pyodide.asm.wasm:0x1c3b51
at pyodide.asm.wasm:0x1c37ba
at pyodide.asm.wasm:0x176e2a
at callPyObjectKwargs (pyodide.asm.js:10:62076)
at Module.callPyObjectMaybePromising (pyodide.asm.js:10:63254)
at wrapper (pyodide.asm.js:10:27079)
at onGlobalMessage (pyodide.asm.js:10:99160) (edited)


files thing in the toml will do that. You only need packages if they are published on pypi.
https://docs.pyscript.net/2024.11.1/user-guide/configuration/ (edited)



image.onload = lambda e: append_image(e.target)

image.onload = lambda e: append_image(e.target) image reference will point at the latest image you assigned in that loop ... with my change all should be fine, the image is referenced by the event.target (or event.currentTarget) (edited)

image reference will point at the latest image you assigned in that loop ... with my change all should be fine, the image is referenced by the event.target (or event.currentTarget) (edited)
append does not understand HTML, it's either plain text (appended as such, hence sanytized) or a DOM element ... if you want to put that <br> in the mix, you need br = lambda: document.createElement('br') and pass br() instead of a string
from pyscript import window
class my_class():
def greet():
return "hello"
window.my_class = my_class
JAVASCRIPT
myClass = window.my_class
const instance = new myClass()
const greet = instance.greet()
console.log(greet) // 'hello' (edited)

from pyscript import window
class my_class():
def greet():
return "hello"
window.my_class = my_class
JAVASCRIPT
myClass = window.my_class
const instance = new myClass()
const greet = instance.greet()
console.log(greet) // 'hello' (edited)




import requests
from bs4 import BeautifulSoup
web = requests.get('https://www.geoguessr.com/world-cup')
does requests just not work on pyscript?

import requests
from bs4 import BeautifulSoup
web = requests.get('https://www.geoguessr.com/world-cup')
does requests just not work on pyscript? 

worker attribute (and the right headers)




worker attribute (and the right headers) 

<script type="py" worker>

self argument
2. Python does not use, or understand, new
check this out: https://pyscript.com/@agiammarchi/dry-water-copy/latest?files=main.py,index.html

self argument
2. Python does not use, or understand, new
check this out: https://pyscript.com/@agiammarchi/dry-water-copy/latest?files=main.py,index.html Arguments to and the results from such calls, when used in a worker, must be serializable, otherwise they won't work.
https://pyscript.com/@mauriel/dry-water/latest?files=index.html (edited)

worker attribute (and the right headers) 



Arguments to and the results from such calls, when used in a worker, must be serializable, otherwise they won't work.
https://pyscript.com/@mauriel/dry-water/latest?files=index.html (edited)import js instead of from pyscript import window and pass js.my_class = my_class then notify js.dispatchEvent(js.Event.new('my_class')) and from the JS side of affairs, the one executed through the worker via import or any other way, you can addEventListener('my_class', callback) and in there use my_class same way you'd do on the main thread.
As summary: JS references are preserved in Python side but not vice-versa when it comes to cross-thread interaction but pyodide preserves both references within the same runtime, being that on main or in a worker (two different worlds/realms).

import js instead of from pyscript import window and pass js.my_class = my_class then notify js.dispatchEvent(js.Event.new('my_class')) and from the JS side of affairs, the one executed through the worker via import or any other way, you can addEventListener('my_class', callback) and in there use my_class same way you'd do on the main thread.
As summary: JS references are preserved in Python side but not vice-versa when it comes to cross-thread interaction but pyodide preserves both references within the same runtime, being that on main or in a worker (two different worlds/realms). async ref.greetings() is not needed if on the same thread, it was my mistake suggesting it, apologies. (edited)

<script type="py" ... worker terminal>, is there any way to declare a sync function to be called on the main thread?

<script type="py" ... worker terminal>, is there any way to declare a sync function to be called on the main thread? <script type="py/mpy" worker> exposes a xworker property with a sync proxy where you can define any callback you like, synchronous or asynchronous, and that callback will be available from pyscript via from pyscript import xworker and then xworker.sync.fromMain(...args) will work synchronously.
To provide some context, the time.sleep() works like that, it's a sync.sleep function exposed through the xworker.sync proxy and used in PyScript when blocking for X milliseconds is desired.
When you have thousand references from the main it's a good thing to keep those in there, or better, crytical UI related path (or rendering path) should happen in the UI so that from the worker you just provide raw data to deal with, not handle all objects from there. Hpefully some of this helps, happy to help further otherwise.sync works both ways ... you can define from a worker callbacks that can be called from main, but that will be asynchronos (inevitably, we can't block the main thread) ... the other way around can be both sync or async.from pyscript import xworker does not work, try from polyscript import xworker as I am sure that's a polyscript thing, not sure we expose it in PyScript too but I think we do, for what I remember
worker terminal


pyscript.web, check out https://docs.pyscript.net/2024.11.1/user-guide/dom/#pyscriptweb 













ltk.window.CodeMirror() You can see the demo running here: https://pyscript.github.io/ltk/?tab=8 If you want to roll your own then the ltk source is in github

create_proxy..? See: https://docs.pyscript.net/2024.11.1/user-guide/ffi/#create_proxy


setTimeout I.e. it's unloadCode not unloadCode().






<!DOCTYPE html>
<html lang="en">
<head>
<!--tagi meta-->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--pyscript css-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css">
<!--css dla przykladu, nie jest potrzebny-->
<link rel="stylesheet" href="./assets/css/examples.css" />
<!--tylko uruchamiacz pyscript-->
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
<!--ekran wczytywania-->
<style>
#loading { outline: none; border: none; background: transparent }
</style>
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>
<title>Document</title>
</head>
<body>
<dialog id="loading">
<h1>Loading...</h1>
</dialog>
<section class="pyscript">
Temperatura i wilgotnoลฤ:
<script type="py">
import time
from adafruit-blinka import board
from adafruit-circuitpython-dht import adafruit_dht
sensor = adafruit_dht.DHT11(board.D2)
while True:
try:
temperature_c = sensor.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = sensor.humidity
print("Temp={0:0.1f}^C, Temp={1:0.1f}^F, Humidity={2:0}")
except RuntimeError as error:
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
sensor.exit()
raise error
time.sleep(3.0)
</script>
</section>
</body>
</html>


<!DOCTYPE html>
<html lang="en">
<head>
<!--tagi meta-->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--pyscript css-->
<link rel="stylesheet" href="https://pyscript.net/releases/2024.1.1/core.css">
<!--css dla przykladu, nie jest potrzebny-->
<link rel="stylesheet" href="./assets/css/examples.css" />
<!--tylko uruchamiacz pyscript-->
<script type="module" src="https://pyscript.net/releases/2024.1.1/core.js"></script>
<!--ekran wczytywania-->
<style>
#loading { outline: none; border: none; background: transparent }
</style>
<script type="module">
const loading = document.getElementById('loading');
addEventListener('py:ready', () => loading.close());
loading.showModal();
</script>
<title>Document</title>
</head>
<body>
<dialog id="loading">
<h1>Loading...</h1>
</dialog>
<section class="pyscript">
Temperatura i wilgotnoลฤ:
<script type="py">
import time
from adafruit-blinka import board
from adafruit-circuitpython-dht import adafruit_dht
sensor = adafruit_dht.DHT11(board.D2)
while True:
try:
temperature_c = sensor.temperature
temperature_f = temperature_c * (9 / 5) + 32
humidity = sensor.humidity
print("Temp={0:0.1f}^C, Temp={1:0.1f}^F, Humidity={2:0}")
except RuntimeError as error:
print(error.args[0])
time.sleep(2.0)
continue
except Exception as error:
sensor.exit()
raise error
time.sleep(3.0)
</script>
</section>
</body>
</html> <py-config>
{
"packages": ["adafruit-blinka", "adafruit_dht", "adafruit-circuitpython-dht"]
}
</py-config>

<py-config>
{
"packages": ["adafruit-blinka", "adafruit_dht", "adafruit-circuitpython-dht"]
}
</py-config> 

packages = ["adafruit-blinka", "adafruit_dht", "adafruit-circuitpython-dht"]
If you create a toml file make sure o update your <script type='py'> with <scrip type='py' config="./pyscript.toml"
hope it helps

packages = ["adafruit-blinka", "adafruit_dht", "adafruit-circuitpython-dht"]
If you create a toml file make sure o update your <script type='py'> with <scrip type='py' config="./pyscript.toml"
hope it helps 

Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/lib/python3.11/site-packages/micropip/_commands/install.py", line 146, in install
raise ValueError(
ValueError: Can't find a pure Python 3 wheel for: 'adafuit-dht'
See: https://pyodide.org/en/stable/usage/faq.html#why-can-t-micropip-find-a-pure-python-wheel-for-a-package
k https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
new_error https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
_PyCFunctionWithKeywords_TrampolineCall https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
callPyObjectKwargs https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
callPyObject https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
wrapper https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.asm.js:9
pyodide.asm.js:9:104344 (edited)

















2024.11.1 rather than older 2024.1.1
You use print so you need a terminal or to print to the dom. You could change your script invocation to be: <script type="py" config="./pyscript.toml" terminal> or you could overwrite print in your script so it appended to the page, or use display() from pyscript instead.
If the terminal is a bit big - you can add __terminal__.resize(60, 20) below your imports.
I don't think you need "setuptools" in your toml packages.
I'm getting this error:
Adafruit-PlatformDetect version 3.77.0 was unable to identify the board and/or
microcontroller running the Emscripten platform. Please be sure you
have the latest packages by running:
'pip3 install --upgrade adafruit-blinka adafruit-platformdetect'
If you are running the latest package, your board may not yet be supported. Please
open a New Issue on GitHub at https://github.com/adafruit/Adafruit_Blinka/issues and
select New Board Request.
I would have expected to see some kind of "connect with the board" code so I don;t know how the AdaFruit code is supposed to find your external device. Is it by wifi ? The errors looks like the code expects the Adadfruit board to be your browser but I expect you have a DHT11 unit plugged into an ADAfruit board of some kind....?

2024.11.1 rather than older 2024.1.1
You use print so you need a terminal or to print to the dom. You could change your script invocation to be: <script type="py" config="./pyscript.toml" terminal> or you could overwrite print in your script so it appended to the page, or use display() from pyscript instead.
If the terminal is a bit big - you can add __terminal__.resize(60, 20) below your imports.
I don't think you need "setuptools" in your toml packages.
I'm getting this error:
Adafruit-PlatformDetect version 3.77.0 was unable to identify the board and/or
microcontroller running the Emscripten platform. Please be sure you
have the latest packages by running:
'pip3 install --upgrade adafruit-blinka adafruit-platformdetect'
If you are running the latest package, your board may not yet be supported. Please
open a New Issue on GitHub at https://github.com/adafruit/Adafruit_Blinka/issues and
select New Board Request.
I would have expected to see some kind of "connect with the board" code so I don;t know how the AdaFruit code is supposed to find your external device. Is it by wifi ? The errors looks like the code expects the Adadfruit board to be your browser but I expect you have a DHT11 unit plugged into an ADAfruit board of some kind....? 
import board where is board defined ?




















type parameter to text 






type parameter to text 



credentialless should fix it https://developer.mozilla.org/en-US/docs/Web/Security/IFrame_credentialless#the_solution_%E2%80%94_iframe_credentialless


donkey functionality within PyScript. This allows you to create a worker that is ready and waiting to recieve, and then execute, Python code 











<script type="py" src="main.py" terminal></script>

<script type="py" src="main.py" terminal></script> 






window object, also because global context pollution is a thing "from the past" and discouraged a lot these days, due name clashing and other issues ... modules are "sandboxed" in scope and functionality, including private variables out of a publicly exported namespace. One can chose, js_modules in config is there to help chosing ESM these days, even for projects such as THREE js (edited)

window object, also because global context pollution is a thing "from the past" and discouraged a lot these days, due name clashing and other issues ... modules are "sandboxed" in scope and functionality, including private variables out of a publicly exported namespace. One can chose, js_modules in config is there to help chosing ESM these days, even for projects such as THREE js (edited)






true to track globals and locals
terminal: '', // optionally set a target terminal container
config: {}, // the worker config (packages, files, etc.)
});
<head> and from where..?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title> Monty Hall problem </title>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.2.2/core.css">
<script type="module" src="https://pyscript.net/releases/2025.2.2/core.js"></script>
</head>
<body>
<h1>Monty Hall problem</h1>
<div id="output"></div>
<script type="py" terminal></script>
<script type="py" src="./main.py" config="./pyscript.json"></script>
</body>
</html>
Hello I'm trying to get a terminal to open and give inputs to the terminal. For some reason the terminal is not opening, though it did with the same code before but I couldn't give any inputs (the input and send in the image was removed, I only want to give inputs inside the terminal) (edited)
<script type="py" terminal></script>
<script type="py" src="./main.py" config="./pyscript.json"></script>
to:
<script type="py" src="./main.py" config="./pyscript.json" terminal></script>
and put all your code in main.py

<script type="py" terminal></script>
<script type="py" src="./main.py" config="./pyscript.json"></script>
to:
<script type="py" src="./main.py" config="./pyscript.json" terminal></script>
and put all your code in main.py 




true to track globals and locals
terminal: '', // optionally set a target terminal container
config: {}, // the worker config (packages, files, etc.)
}); @pyscript/core/js same way we provide @pyscript/core/css and point already to the dist/* folder ... will do soon!

@pyscript/core/js same way we provide @pyscript/core/css and point already to the dist/* folder ... will do soon! @pyscript/core/js as import works in there, that'd be awesome, thank yuo!


.com page to work with ... just giving us code we test and know it works does not really help us in helping you around the issue.

.com page to work with ... just giving us code we test and know it works does not really help us in helping you around the issue. execute(code) is by contract/API that is going to execute some code ... you are invoking it with no code to execute and it's unclear what you are doing ... as summary, the moment you provide a minimal example of your failing attempts is the moment we can help. If you paste code out of an import we use already daily it doesn't help us in helping you so all these threads could be 1. a thread and 2. have a failing example we can work on, thank you!

execute(code) is by contract/API that is going to execute some code ... you are invoking it with no code to execute and it's unclear what you are doing ... as summary, the moment you provide a minimal example of your failing attempts is the moment we can help. If you paste code out of an import we use already daily it doesn't help us in helping you so all these threads could be 1. a thread and 2. have a failing example we can work on, thank you! 

await it? https://pyscript.com/@agiammarchi/calm-queen-copy/latest?files=index.html

await it? https://pyscript.com/@agiammarchi/calm-queen-copy/latest?files=index.html await a donkey ... /cc @ntoll as that's a bug in our documentation!

await donkey right..? 


await in front of ay of your donkey related calls and you should be fine.


execute(code) is by contract/API that is going to execute some code ... you are invoking it with no code to execute and it's unclear what you are doing ... as summary, the moment you provide a minimal example of your failing attempts is the moment we can help. If you paste code out of an import we use already daily it doesn't help us in helping you so all these threads could be 1. a thread and 2. have a failing example we can work on, thank you! 



















index.html (edited)












mini-coi.js and serve it as static JS file as long as it's at the root of every other JS file or the Service Worker won't be able to control/intercept those calls

/js/ that should work










builtins.print and that achieves what I need for the basic testing functionality that I have. (edited)


builtins.print and that achieves what I need for the basic testing functionality that I have. (edited)

skyfield which has all pure python packages except for sgp4. There is a recently made pure python version of sgp4 called sgp4_pure_python. This package has a provides tag that says it provides sgp4.
I am loading that pure python package before skyfield in my toml file but micropip cannot see that the requirement has been met. And it fails in the console with no pure python package for sgp4 can be found.
The problem is documented here (on the skyfield github) - https://github.com/skyfielders/python-skyfield/issues/1040#issuecomment-2675499472
Question:

--no-deps option. Invoked like this: micropip.install("pkg", deps=False)
Is there a way to signal nodeps in the toml file ? That might allow me to load the skyfield package. (edited)

js_modules.main and js_modules.worker accept URLs. But what is the URL to a .js file bundled in a pypi package?imported? To be completely transparent to the consumer?

js_modules.main and js_modules.worker accept URLs. But what is the URL to a .js file bundled in a pypi package?imported? To be completely transparent to the consumer? .js file (it should be a module) in the TOML as js_modules.main (or worker, or both) and import it before importing the package relying on its presence and that should be it?


.js file (it should be a module) in the TOML as js_modules.main (or worker, or both) and import it before importing the package relying on its presence and that should be it? 


window.thatGloballyLeakedNamespace and you can use it from there without needing anything in the TOML file, but it's an awkward indirection, our config doesn't provide a way to trash non-modules on the HTML so far so I am not sure how to do that but, like I've said the module runs when you import it, so you can import that .js file via your TOML, if defined, before importing your PyPy wheel module. That file can do everything you need ... that being said, if there was a minimalistic example of the issue you are trying to solve in ... let's say PyScript .com, I could surely help more with an example.

window.thatGloballyLeakedNamespace and you can use it from there without needing anything in the TOML file, but it's an awkward indirection, our config doesn't provide a way to trash non-modules on the HTML so far so I am not sure how to do that but, like I've said the module runs when you import it, so you can import that .js file via your TOML, if defined, before importing your PyPy wheel module. That file can do everything you need ... that being said, if there was a minimalistic example of the issue you are trying to solve in ... let's say PyScript .com, I could surely help more with an example. To use libfoo in pyscript, you will need to declare the following in your pyscript.toml:
packages = ["libfoo@2.0.1"]
[js.modules]
"https://cdn.pyscript.com/serve-files-from-wheels/pypi/libfoo@2.0.1/subpath/shim.js" = "libfooshim"
What should that URL look like?
Important characteristics:
.js from within the wheel, but wouldn't it be great if that was possible?
Because, in general, that's our goal with libraries:imported
.js code from the virtual filesystem and loading it into the DOM by manually creating a script tag with the content of your .js. That feels very dirty to me though.





To use libfoo in pyscript, you will need to declare the following in your pyscript.toml:
packages = ["libfoo@2.0.1"]
[js.modules]
"https://cdn.pyscript.com/serve-files-from-wheels/pypi/libfoo@2.0.1/subpath/shim.js" = "libfooshim"
What should that URL look like?
Important characteristics:
packages = ["libfoo@2.0.1"]
[js_modules.main]
"https://esm.run/libfoo@2.0.1" = "libfooshim"
and ... that's it? 



pyscript.js_modules.libfooshim so that one could just import libfooshim and call it a day. I welcome that DX and I think we could provide the same to simplify even further Python users' expectations.

pyscript.js_modules.libfooshim so that one could just import libfooshim and call it a day. I welcome that DX and I think we could provide the same to simplify even further Python users' expectations. 

packages = ["libfoo@2.0.1"]
[js_modules.main]
"https://esm.run/libfoo@2.0.1" = "libfooshim"
from pyscript.js_modules import libfooshim
this works well with PyScript projects but it won't scale by any mean elsewhere ... what I have in mind is (instead):
packages = ["libfoo@2.0.1"]
[py_modules.main]
"https://esm.run/libfoo@2.0.1" = "libfooshim"
import libfooshim
so that your code doesn't have an indirect dependency of an outer scope/context/namespace it doesn't know, and that code could be more portable around ... /cc @ntoll
funaudiolibrary, could do something like if is_in_browser: browser_shim = browser.load_js(location="worker", path=__file__ + "../jsAudioShim.js")
So if a consumer of my module does import funaudiolibrary, and my library does that call to load the JS, the consumer doesn't need to think about the details
py_imports and js_imports exposed as API to do runtime imports, you just need an await upfront


pyglet (a rendering library, among other things) on Mac, Linux, Windows, there are platform-specific things happening behind the scenes, but the consumer (largely) doesn't need to know.
pyglet.Window().run() will launch a GUI window on the platform, even though the underlying OS APIs might be totally different. pyglet abstracts that.
It would be great if we could support the browser environment in the same way
try:
from pyscript import js_import
libfooshim, = await js_import("https://esm.run/libfoo@2.0.1")
except:
libfooshim = None
js_import does fit the bill, with the await caveat, and the inability to bundle the .js in the wheel.

js_import does fit the bill, with the await caveat, and the inability to bundle the .js in the wheel. URL.createObjectURL and a base64 encoded version of your dependency that could land with the wheel itslef ... it's slightly convoluted but possiblewindow.import(blob) instead but the await, I am afraid, it's a Web/JS modules limitations when these are not known/static upfront


.py entrypoint executes, right?
It'd be cool if a wheel could somehow declare its own .js component to be pre-loaded in a similar way.
Is this a step too far, too complex? Maybe, but just thinking out loud
.js file in the Python VFS has no meaning for the Web ... you want to load that file to the browser, not just in your virtual Python WASM environment ... so that's a "yes, you can have JS files in the VFS" and a "meh, not much after you can do"import which is what you are asking is always async, there's no way around it
.js shim into the worker or main thread
And if the consumers of my library can import funaudiolibrary and it works, that's cool!












browser_env.json manifest in their wheel, but micropip/pypy/etc don't need to understand it




browser_env.json manifest and how it might work for funaudiolibrary


import js
# in some component
js.setTimer(self._load_data, 0)
Not sure if it is the right way at all, but I have no other idea.



create_proxy call. How do I set pyodide.setDebug(true)?
pyodide.asm.js:10 Uncaught Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callable.
For more information about the cause of this error, use pyodide.setDebug(true)

create_proxy call. How do I set pyodide.setDebug(true)?
pyodide.asm.js:10 Uncaught Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callable.
For more information about the cause of this error, use pyodide.setDebug(true) experimental_create_proxy = "auto" in your config and tell me if that solved? not an answer to your question but curious to know if "we" can make that error disappear

experimental_create_proxy = "auto" in your config and tell me if that solved? not an answer to your question but curious to know if "we" can make that error disappear setDebug(true) we don't have a config value for that (we probably should, right @ntoll ?) but you could try to:
from _pyscript import interpreter
interpreter.setDegug(True)
and see if that works

experimental_create_proxy = "auto" in your config and tell me if that solved? not an answer to your question but curious to know if "we" can make that error disappear 


setDebug if MicroPython has a story for it. I mean, what does setting that flag even do?

setDebug if MicroPython has a story for it. I mean, what does setting that flag even do? 
<function check_version.<locals>.report_version at 0x1090b40>

debug = true in the config should be allowed for Pyodide use cases and maybe be ignored in MicroPython as it doesn't exist





Symbol.iterator which is a special symbol reached out to iterate ... maybe your string conversion is iterating chars instead? https://pyodide.org/en/stable/usage/type-conversions.html (edited)





__getitem__ too would solve?






pyscript.web we created a layer that deals with that out of the box but in your example you are really invoking native JS functions and there is no specification about what these should do when a foreign/non element object is appended, throwing feels like actually the expected behavior, the Pyodide result is surprising to me.

pyscript.web we created a layer that deals with that out of the box but in your example you are really invoking native JS functions and there is no specification about what these should do when a foreign/non element object is appended, throwing feels like actually the expected behavior, the Pyodide result is surprising to me. 

Text with any other outer component/container you'll have a similar issue all over the place, example try to pass a <div> that contains two <hr> in it and see what happens ... so this issue is actually not really an issue to me, just expectations a bit far off in terms of interoperability, and only Text might work because maybe some symbol is retrieved as last resort but symbols cannot travel between worker and main so it's a no-go no matter how you look at that, while passing nodes explicitly will always work. (edited)

Text with any other outer component/container you'll have a similar issue all over the place, example try to pass a <div> that contains two <hr> in it and see what happens ... so this issue is actually not really an issue to me, just expectations a bit far off in terms of interoperability, and only Text might work because maybe some symbol is retrieved as last resort but symbols cannot travel between worker and main so it's a no-go no matter how you look at that, while passing nodes explicitly will always work. (edited)body.append but that cannot possibly work out of workers and it's all Pyodide internals at play there, imho.











objectsAA.py file as defined in the toml. Complains about async and importing packages. - https://pyscript.com/@neon22/tsa-video-game-copy/latest?files=main.py,pyscript.toml
I even tried going back to [fetch] in the toml and no luck... Any ideas anyone ??
"../../objects.py' = '' No idea how to reach it. @Andrea Giammarchi ??




"../../objects.py' = '' No idea how to reach it. @Andrea Giammarchi ?? py-game supports only packages, not files entries in the config ... I did see that coming, will work on a fix tomorrow and publish to fix this issue. I'll file an issue in the meantime.

py-game supports only packages, not files entries in the config ... I did see that coming, will work on a fix tomorrow and publish to fix this issue. I'll file an issue in the meantime. py in a similar way mpy is different from py and py-editor is different from py too: our bad not empathasing that enough ... issue fled, at least files should work or assets and user-land modules can't work in there, apologies: https://github.com/pyscript/pyscript/issues/2309

py in a similar way mpy is different from py and py-editor is different from py too: our bad not empathasing that enough ... issue fled, at least files should work or assets and user-land modules can't work in there, apologies: https://github.com/pyscript/pyscript/issues/2309 py and mpy plus py-game on the same page ... because py-game right now is a main-thread only affair, we wanted to decouple the contract about having only one py or mpy on the main thread, when worker attribute is not there (and py-game cannot run in workers right now)py-editor, the py-game script type has a different goal, scope, constraints, and implicit features ... it's OK to want py features in there, we just need to figure out if all of them are possible or not. [files] is one of those that just weren't fully considered but I don't see why these shouldn't be in thereinterpreter or experimental features might just not be there at this time, yet again [files] should be there and I'll work on it to make it happen


py and mpy plus py-game on the same page ... because py-game right now is a main-thread only affair, we wanted to decouple the contract about having only one py or mpy on the main thread, when worker attribute is not there (and py-game cannot run in workers right now)py-editor, the py-game script type has a different goal, scope, constraints, and implicit features ... it's OK to want py features in there, we just need to figure out if all of them are possible or not. [files] is one of those that just weren't fully considered but I don't see why these shouldn't be in thereinterpreter or experimental features might just not be there at this time, yet again [files] should be there and I'll work on it to make it happenconfig flag? Yes, it could be, but it has to be a dedicated config flag or no other py scripts can run on the same main thread at the momentpy) and an env meant to be created at runtime on demand and with multiple possible visual targets (that's py-game) ... on top of that, we're trying to figure out if py-game should be coupled entirely with pygame-ce package, and the current logic is trying to suggest: it shouldn't!




<script type="py-editor" env="seance1" config='{"packages":["numpy", "matplotlib"]}'>
import numpy as np
import matplotlib.pyplot as plt
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
plt.plot(xpoints, ypoints)
plt.show()
</script>
I get this error in output:
import numpy as np
import matplotlib.pyplot as plt
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
fig, ax = plt.subplots()
plt.plot(xpoints, ypoints)
display(fig)
but I still have the long error message in output.







import numpy as np
import matplotlib.pyplot as plt
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
fig, ax = plt.subplots()
plt.plot(xpoints, ypoints)
display(fig)
but I still have the long error message in output. <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.2.4/core.css">
<script type="module" src="https://pyscript.net/releases/2025.2.4/core.js"></script>
</head>
<body>
<script type="py-editor" env="seance1" config='{"packages":["numpy", "matplotlib"]}'>
import numpy as np
import matplotlib.pyplot as plt
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
fig, ax = plt.subplots()
plt.plot(xpoints, ypoints)
from pyscript import display
display(fig, target="outcome")
</script>
<div id="outcome"></div>
</body>
</html>
of course you need special headers to have workers fully working out of py-editor or not much could happen in there, if you require document access ... that's all covered by our docs: https://docs.pyscript.net/2025.2.4/user-guide/workers/
<py-repl output=โresultat3โ>
CODE HERE
</py-repl>
<div style=โtext-align:centerโ id=โresultat3โ></div>
And now I've had to replace it with :
<script type=โpy-editorโ env=โseance1โ config='{โpackagesโ:[โnumpyโ, โmatplotlibโ]}'>
CODE HERE
</script>
Except that now the ouputs are replaced each time when RUN is clicked again, whereas previously they were added one after the other, which was a behavior that suited me fine.)

<py-repl output=โresultat3โ>
CODE HERE
</py-repl>
<div style=โtext-align:centerโ id=โresultat3โ></div>
And now I've had to replace it with :
<script type=โpy-editorโ env=โseance1โ config='{โpackagesโ:[โnumpyโ, โmatplotlibโ]}'>
CODE HERE
</script>
Except that now the ouputs are replaced each time when RUN is clicked again, whereas previously they were added one after the other, which was a behavior that suited me fine.) clear in a Linux terminal ... when I run same program twice, I'm likely never interested in reading the previous results, even less interested to scrol every time further up to re-read the program I am running, but that might be "just me" although so far it was a shared feeling among others using py-editor too. (edited)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2025.2.4/core.css">
<script type="module" src="https://pyscript.net/releases/2025.2.4/core.js"></script>
</head>
<body>
<script type="py-editor" env="seance1" config='{"packages":["numpy", "matplotlib"]}'>
import numpy as np
import matplotlib.pyplot as plt
xpoints = np.array([1, 8])
ypoints = np.array([3, 10])
fig, ax = plt.subplots()
plt.plot(xpoints, ypoints)
from pyscript import display
display(fig, target="outcome")
</script>
<div id="outcome"></div>
</body>
</html>
of course you need special headers to have workers fully working out of py-editor or not much could happen in there, if you require document access ... that's all covered by our docs: https://docs.pyscript.net/2025.2.4/user-guide/workers/ <script src=โhttps://physique-pcsi.prepa-balzac.fr/statique/mini-coi.jsโ></script> between the <head> tags it works perfectly, thanks! The best part is that it has exactly the behavior I was hoping for: each time RUN is clicked the new graphic is added after the old one instead of replacing it, so it's perfect!!!! matplotlib doesn't work anymore <script src=โhttps://physique-pcsi.prepa-balzac.fr/statique/mini-coi.jsโ></script> in the html header.
Here's the actual destination where it doesn't work:
https://physique-pcsi.prepa-balzac.fr/numerique/equadiffs.php
(you can type anything into the javascript prompt that appears when the page starts).
Here's the โnakedโ page where it works fine:
https://physique-pcsi.prepa-balzac.fr/statique/bacasable.html (edited)

<script src=โhttps://physique-pcsi.prepa-balzac.fr/statique/mini-coi.jsโ></script> between the <head> tags it works perfectly, thanks! The best part is that it has exactly the behavior I was hoping for: each time RUN is clicked the new graphic is added after the old one instead of replacing it, so it's perfect!!!! matplotlib doesn't work anymore <script src=โhttps://physique-pcsi.prepa-balzac.fr/statique/mini-coi.jsโ></script> in the html header.
Here's the actual destination where it doesn't work:
https://physique-pcsi.prepa-balzac.fr/numerique/equadiffs.php
(you can type anything into the javascript prompt that appears when the page starts).
Here's the โnakedโ page where it works fine:
https://physique-pcsi.prepa-balzac.fr/statique/bacasable.html (edited)mini-coi.js file as static asset at the root of your site, you cannot have remote service workers by specs.

mini-coi.js file as static asset at the root of your site, you cannot have remote service workers by specs. 

numerique and statique folders must contain a mini-coi.js or you can put mini-coi.js at the root of your site and use it when needed in pages via <script src="/mini-coi.js"></script> and all pages would equally work.

py in a similar way mpy is different from py and py-editor is different from py too: our bad not empathasing that enough ... issue fled, at least files should work or assets and user-land modules can't work in there, apologies: https://github.com/pyscript/pyscript/issues/2309 https://cdn.jsdelivr.net/npm/@pyscript/core@0.6.37/dist/core.js which you can try already until we release ... all config things should just work out of the box now, and yes ... there were issues even with just packages before, now it should all be good, please let me know if that's not the case, thank you! (edited)

https://cdn.jsdelivr.net/npm/@pyscript/core@0.6.37/dist/core.js which you can try already until we release ... all config things should just work out of the box now, and yes ... there were issues even with just packages before, now it should all be good, please let me know if that's not the case, thank you! (edited)0.6.39 now (edited)







recommended way to do this is to just use pyscript.com and copy it over but is there a way to get completion to work? I've search the server and am not seeing anything other than others asking the same question without any clear answer. Following along with the example I expected to pip install pyscript and write from pyscript import document and get autocompletion in the IDE. I understand it is designed to run in the browser but we write in an IDE.






















main.py I'm importing some not existing object: Wrong and bellow I'm calling some not existing method: plane.wrong() but in the console I do not see any error message.
Perhaps, the issue is due to current project structure (see figure).
Is it possible to structure the code using folders and subfolders?
I did not see any other example that might guide me and I was not able to find documentation on this probably due to my lack of knowledge in the field.

main.py I'm importing some not existing object: Wrong and bellow I'm calling some not existing method: plane.wrong() but in the console I do not see any error message.
Perhaps, the issue is due to current project structure (see figure).
Is it possible to structure the code using folders and subfolders?
I did not see any other example that might guide me and I was not able to find documentation on this probably due to my lack of knowledge in the field. "./cart"="" is not needed only the files.
The py files inside the folder seem correctly defined. To access then you need to import abstract in your main. Have you looked in here: https://docs.pyscript.net/2025.3.1/user-guide/configuration/#files
Also - there is quite a good svg lib I use which is linked on this page. See if it works for you. I use outerHTML rather than as_str to append to dom elements.



svg.Group I also made a mini main2.py - you can check imports etc in there if it usefulstyle. This started in svg2. The code is a lot smaller and simpler to traverse (IMHO). I do recommend that svg.py I pointed you too in my link above. Best of luck

style. This started in svg2. The code is a lot smaller and simpler to traverse (IMHO). I do recommend that svg.py I pointed you too in my link above. Best of luck style because I need to understand how to make the svg and tk interface consistent and at this stage is enough to define the style for each svg element.
I have a working example now (not yet interactive), I would like to integrate an editor on it where the user can define its own geometries and play a bit with the code.
From the documentation it is not clear how I can do it.
Ideally I would like to have some sample code already written in the editor, and the result already rendered in the svg-container, then the user can play with the code and see the result.
I tried following the example https://github.com/pyscript/pyscript/blob/2025.3.1/core/tests/manual/submit.py but raise an AttributeError for both code and process.
Probably I'm missing something stupid.

style because I need to understand how to make the svg and tk interface consistent and at this stage is enough to define the style for each svg element.
I have a working example now (not yet interactive), I would like to integrate an editor on it where the user can define its own geometries and play a bit with the code.
From the documentation it is not clear how I can do it.
Ideally I would like to have some sample code already written in the editor, and the result already rendered in the svg-container, then the user can play with the code and see the result.
I tried following the example https://github.com/pyscript/pyscript/blob/2025.3.1/core/tests/manual/submit.py but raise an AttributeError for both code and process.
Probably I'm missing something stupid. 



































ModuleNotFoundError: No module named 'restricted_checks'
However, the file does exist and is properly referenced in my project structure and pyscript.json file.
project/
โโโ src/
โ โโโ app.html
โ โโโ routes/
โ โ โโโ +layout.js
โ โ โโโ +layout.svelte
โ โ โโโ +page.svelte
โ โ โโโ components/
โ โ โโโ diagram.svelte <-- (PyScript is included here)
โ โ โโโ editor.svelte
โโโ static/
โ โโโ python/
โ โ โโโ config/
โ โ โ โโโ pyscript.json
โ โ โโโ src/
โ โ โ โโโ main.py
โ โ โ โโโ restricted_checks.py
โ โ โ โโโ worker.py <-- (where the import issue occurs)
diagram.svelte: <script type="py" src="python/src/main.py" config="python/config/pyscript.json"></script>
pyscript.json: {
"package": ["ast", "pyscript", "pyodide", "ast", "time", "copy", "js"],
"interpreter": "https://cdn.jsdelivr.net/pyodide/v0.27.0/full/pyodide.mjs",
"files": {
"../src/restricted_checks.py": ""
}
}
worker.py: import restricted_checks
I expected this to work since restricted_checks.py is listed in pyscript.json. However, it is still unable to find the module.
pyscript.json? worker.py? 

pyscript.json file as suggested:
{
"package": ["ast", "pyscript", "pyodide", "time", "copy", "js", "asyncio"],
"interpreter": "https://cdn.jsdelivr.net/pyodide/v0.27.0/full/pyodide.mjs",
"files" : {
"../src/restricted_checks.py": "./restricted_checks.py"
}
}
However, the issue persists. According to PyScriptโs documentation:


pyscript.json file as suggested:
{
"package": ["ast", "pyscript", "pyodide", "time", "copy", "js", "asyncio"],
"interpreter": "https://cdn.jsdelivr.net/pyodide/v0.27.0/full/pyodide.mjs",
"files" : {
"../src/restricted_checks.py": "./restricted_checks.py"
}
}
However, the issue persists. According to PyScriptโs documentation:







input to work... the import thing being BOTH the terminal and worker attributes:
<script type="py" src="mycode.py" terminal worker></script>

worker you can input("question") and retrieve the answer just like you'd do in regular Python ... it's all in our docs https://docs.pyscript.net/2025.3.1/user-guide/workers/



requests library in my PyScript project on pyscript.com. I keep getting a ModuleNotFoundError: No module named 'requests' error.
I've tried a few things based on standard Pyodide/PyScript documentation, but none seem to be working on the pyscript.com platform:
1. Using <py-env> in my HTML:
<py-env>
- requests
- beautifulsoup4
</py-env>
2. Using await micropip.install(['requests', 'beautifulsoup4']) within my <py-script> code.
Here's the traceback I consistently receive:
Traceback (most recent call last):
File "/lib/python312.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
File "/lib/python312.zip/_pyodide/_base.py", line 411, in run_async
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 2, in <module>
ModuleNotFoundError: No module named 'requests'
The module 'requests' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("requests") in Python, or
await pyodide.loadPackage("requests") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
I'm trying to fetch data from my website (trafficcameras.info, where I believe I've correctly configured CORS to allow requests from pyscript.com).
Could anyone on the pyscript.com platform advise on the correct way to install and use external libraries like requests? Is there a specific method or are there any known issues I should be aware of?
Any help would be greatly appreciated! Thank you.



requests library in my PyScript project on pyscript.com. I keep getting a ModuleNotFoundError: No module named 'requests' error.
I've tried a few things based on standard Pyodide/PyScript documentation, but none seem to be working on the pyscript.com platform:
1. Using <py-env> in my HTML:
<py-env>
- requests
- beautifulsoup4
</py-env>
2. Using await micropip.install(['requests', 'beautifulsoup4']) within my <py-script> code.
Here's the traceback I consistently receive:
Traceback (most recent call last):
File "/lib/python312.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
File "/lib/python312.zip/_pyodide/_base.py", line 411, in run_async
coroutine = eval(self.code, globals, locals)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<exec>", line 2, in <module>
ModuleNotFoundError: No module named 'requests'
The module 'requests' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("requests") in Python, or
await pyodide.loadPackage("requests") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
I'm trying to fetch data from my website (trafficcameras.info, where I believe I've correctly configured CORS to allow requests from pyscript.com).
Could anyone on the pyscript.com platform advise on the correct way to install and use external libraries like requests? Is there a specific method or are there any known issues I should be aware of?
Any help would be greatly appreciated! Thank you. requests - we have an equivalent fetch API built into PyScript. Docs here: https://docs.pyscript.net/2025.3.1/api/#pyscriptfetch Happy to answer questions.requests module uses underlying operating system IO which simply isn't available in the browser... hence the fetch API we have that sits on top of the browser's way to make HTTP requests.
It is possible to use requests with Pyodide... but this is a but more involved.




requests module uses underlying operating system IO which simply isn't available in the browser... hence the fetch API we have that sits on top of the browser's way to make HTTP requests.
It is possible to use requests with Pyodide... but this is a but more involved. pyscript.fetch but I consistently get a TypeError: Failed to fetch error in the PyScript console.
I've tried a basic fetch(url) and also included a User-Agent header, but the error persists. Are there any specific configurations or considerations I might be missing when trying to fetch from external websites? Any help or insights would be greatly appreciated!

pyscript.fetch but I consistently get a TypeError: Failed to fetch error in the PyScript console.
I've tried a basic fetch(url) and also included a User-Agent header, but the error persists. Are there any specific configurations or considerations I might be missing when trying to fetch from external websites? Any help or insights would be greatly appreciated! Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://trafficcameras.info/product/m25-100-9a-junction-16-15/. (Reason: CORS header โAccess-Control-Allow-Originโ missing). Status code: 200.



(PY0001): Polyscript: Access to local files
(using [[fetch]] configurations in <py-config>)
is not available when directly opening a HTML file;
you must use a webserver to serve the additional files.
See <a style="text-decoration: underline;" href="https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062">this reference</a>
on starting a simple webserver with Python.
If someone could help or assist in resolving this issue, it would be greatly appreciated. (edited)




[fetch] in toml anymore - use[files] instead.)
The main thing appears to be you are trying to use it as an html file which someone just tries to open on a local machine. The entire design of the www is basically working against you there. So you have two easy solutions:
1. Put your code on pyscript.com - point people to that. All cors issues taken care of - and it all still only runs on your local machine.
2. Once you have that - use the "Install" option on Lower RHS and it will become a PWA on your own system and no longer need internet access at all.

"./configparser7.whl" = "./*" under [files]
What is the right way to import this ?
If I try from configparser7 import * I get a Promise Error: custom.js:189 Uncaught (in promise) ErrnoError
mip.install("https://files.pythonhosted.org/packages/09/fe/f61e7129e9e689d9e40bbf8a36fb90f04eceb477f4617c02c6a18463e81f/configparser-7.2.0-py3-none-any.whl") did not work









<script type="py-editor" target="test" config='{"packages":["numpy", "matplotlib"]}'>
import sys
from pyscript import display
import numpy as np
f = np.array([5, 5])
print(f)
display(f)
</script> (edited)










?key=value to the proxy url doesn't seem to have any effect on the response the target url gives (edited)





packages = ["fpdf2==2.8.1"] beware of version problems. My main.py starts like this:
from fpdf import FPDF # for report writing
from fpdf.fonts import FontFace
from fpdf.enums import TableSpan, Align
from fpdf.svg import SVGObject
This is how I subclass it )as per their docs)
class PDF_base(FPDF):
def __init__(self, title, grouped=False):
self.title = title
self.grouped = grouped
self.table_heights = {'A4': 26, "Letter": 24} # how many lines can I get on the page based on format
super().__init__()
def footer(self):
# Position cursor at 1.5 cm from bottom:
self.set_y(-15)
# Setting font: helvetica italic 8
self.set_font("helvetica", "I", 8)
# Printing page number:
self.cell(0, 10, f"Page {self.page_no()}/{{nb}}", align="C")
If you really need to dig around look inside the quite large: https://pyscript.com/@neon22/working-sectional/latest?files=main.py,pyscript_pyo.toml


























[files]
"./error.wav" = "./"[files]





[files]
"./error.wav" = "./" 






mpy can't do what you want and you have to switch to py. You can probably keep using mpy by putting the pyodide part in a Named worker and getting that job done asynchronously. This hybrid approach is actually the preferred one - Alas you will not find any examples (yet) that demonstrate how to do this. If you want a starter template to have a go with (which also uses the ltk to do Reactive UI components, and allows mpy/py switching) then you could check out this demo here: - https://pyscript.com/@neon22/starter-03-reactiveui/latest?files=README.md One day something like this might make it into "examples". Cheers...






"./xxx.py" = "" this allows you to put that file in a subdirectory E.g. make an assets directory put the file in there and use: "./assets/xxx.py" = ""









curl-cffi > 0.7.. looking
pyfinance are you using. Do you have a demo page on pyscript.com which illuminates what you're trying to do ?
files in the toml so they can be prefected and made available. This might mean editing the above file so teh links are to these local files. but then it might work


files in the toml so they can be prefected and made available. This might mean editing the above file so teh links are to these local files. but then it might work 

pyfinance are you using. Do you have a demo page on pyscript.com which illuminates what you're trying to do ? 
ltk.Div() Ltk kitchensink demo is here: https://pyscript.github.io/ltk/?tab=4&runtime=mpy
These architectural changes would possibly enable that package to work.


ltk.Div() Ltk kitchensink demo is here: https://pyscript.github.io/ltk/?tab=4&runtime=mpy
These architectural changes would possibly enable that package to work.

















from pyscript import document
Is not importing document (this is how you're supposed to do it in the documentation).
@when('dragstart', '.draggable')
def on_dragstarted(event):
print('drag started')
event.dataTransfer.clearData()
event.dataTransfer.setData('text/plain', event.target.id)
event.currentTarget.style.backgroundColor = 'yellow'
@when('dragover', '.dropzone')
def on_dragover(event):
event.preventDefault()
@when('drop', '.dropzone')
def on_drop(event):
print('item dropped on dropzone')
drag_id = event.dataTransfer.getData('text')
drag_element = page[f'#{drag_id}'][0]
dropzone = event.target
dropzone.append(drag_element._dom_element)
It's those last few lines that caught me out.
1. Getting the dragged element via the page['#{drag_id}'][0] code is pretty verbose. Is there really no Python equivalent there to the JS .getElementById() call?
2. The page['#{drag_id}'][0] expression returns a pyscript.web.Element object, but event and event.target are JavaScript objects. This means if I try to just do dropzone.append(drag_element) I don't get the desired behavior. With Pyodide, a new element simply gets created with text like '<pyscript.web.div object at 0xda5490>'. In Micropython, I get some errors:
Aborted(Assertion failed: stringToUTF8Array expects a string (got symbol)) micropython.mjs:1:10797
Uncaught RuntimeError: Aborted(Assertion failed: stringToUTF8Array expects a string (got symbol))
Is there a better way to get the event target so I don't have to use ._dom_element? (edited)

from pyscript import document
Is not importing document (this is how you're supposed to do it in the documentation). 

.getElementById() call than using the page object's .find() call? Using something like page['#my-element-id'] produces a sequence, so you still need to index into it to grab the [0] element. Additionally, if you have the element's ID in a variable, you then need to do something like page[f'#{element_id}'][0], which is very verbose.

[0] and leaves the need to construct the ID w/ the f-string or prepending '#' some other way. Seems like having a specific query method for searching by ID would be helpful. Seems to be the same decision the JavaScript designers came to as well.
ltk.find(selector) works for "#idname", ".aclassname", and any kind of gt, lt etc selector shennanigans that jQuery supports - which is all of them. Also the ltk can force a list (python list) return if you use ltk.find_list() instead of find. or leave it in jQuery land for chaining ops in the same way jQuery does.
pyscript.web.*? The docs just say that 'Usage of these is explained in the user guide,' but the user guide doesn't give those details and refers back to that first page.













strict-origin-when-cross-origin which is stopping Pyodide from working. Contrast this with pyscript.com whose referrer policy is no-referrer.

strict-origin-when-cross-origin which is stopping Pyodide from working. Contrast this with pyscript.com whose referrer policy is no-referrer. 




mini-coi which ensures the local server is configured and serves with the correct headers. Try this command (assuming you have npx installed): npx mini-coi . (to serve your local directory).
I've just tried it and it works - proving that it's as I expected... an issue with the server configuration.python -m http.server is set the way it is. I've just updated to a new laptop and a new (Fedora) version of Linux.http.server is a very naive and simple implementation for local testing purposes only. I'm not sure how easily configurable it is.

http.server and see if we can document it somewhere since many Python folks will default to this without realising mini-coi is available. from http.server import HTTPServer, SimpleHTTPRequestHandler
class CustomHandler(SimpleHTTPRequestHandler):
def end_headers(self):
# Add Referrer-Policy header
self.send_header('Referrer-Policy', 'no-referrer')
super().end_headers()
if __name__ == '__main__':
port = 8000
server_address = ('', port)
httpd = HTTPServer(server_address, CustomHandler)
print(f"Serving on port {port} with Referrer-Policy: no-referrer")
httpd.serve_forever()mini-coi). (edited)
h.set('Cross-Origin-Opener-Policy', 'same-origin');
h.set('Cross-Origin-Embedder-Policy', 'require-corp');
h.set('Cross-Origin-Resource-Policy', 'cross-origin');



ltk.Input() to gather the typed in value.






py-click attribute is deprecated. Use the @when decorator instead. See: https://docs.pyscript.net/2025.7.3/api/#pyscriptwhen Happy to answer questions.
<button id="my-button">Click Me</button>
from pyscript import when
@when("click", "#my-button")
def handle_click(event):
# Do stuff
a= "Foo" and a[::-1] fails... is this on the roadmap for mpy ? Seems it got closed a couple of years ago in mpy issues... So using: "".join(reversed(a))

a= "Foo" and a[::-1] fails... is this on the roadmap for mpy ? Seems it got closed a couple of years ago in mpy issues... So using: "".join(reversed(a)) 








import pyscript or import js features in IDE/VSCode?



pathlib. https://github.com/pyscript/pyscript/blob/67fa31e4eab3b98f3f8fc364990736e528539d2f/core/src/stdlib.js#L36
But MicroPython doesn't have pathlib. Do you ship a patched MicroPython that uses the 3rd party implementation?






packages = [ "fpdf2==2.8.1"]
and then import fpdf2 as PDF in your main (edited)



packages = [ "fpdf2==2.8.1"]
and then import fpdf2 as PDF in your main (edited)







[] Disable cache

[] Disable cache 
assign in js for micropython. Is there a way to do this in mpy, I don't want to have to add a worker just to do this task...
encoded_data = data.encode('utf-8')
my_stream = io.BytesIO(encoded_data)
js_array = Uint8Array.new(len(encoded_data))
js_array.assign(my_stream.getbuffer()) #! FAILS in mpy
file = File.new([js_array], "unused_file_name.txt", {type: "text/plain"})
url = URL.createObjectURL(file)
hidden_link = document.createElement("a")
hidden_link.setAttribute("download", "my_other_file_name.txt")
hidden_link.setAttribute("href", url)
hidden_link.click()




js_array.assign ??? that looks like a JS pollution only Pyodide provide ... we do, however, convert Python things to JS things on occasion and that's via something like:
def as_jsview(buffer):
pyview = memoryview(buffer)
jsview = js.Uint8Array.new(len(pyview))
for i in range(len(pyview)):
jsview[i] = pyview[i]
return jsview
Uint8Array.new(encoded_data) which allows initialization of the data rather than use assign which pyodide put in for adding the data later. This works.
My ref for assign was from the recipe here (which is now out of date) https://pyscript.recipes/2024.5.2/basic/file-download/
I can confirm all works well in mpy and py. I will submit a PR to docs of an improved download routine which uses IO streams as sometimes the file handle is not always available. e.g. when calling something like the RawConfigParser. My new one uses binary or text streams and converts to bin to 'save' so all mimetypes are handled by one routine.


[files]
"./yourdirname/foo.py" = ""
Which has the foo.py file under the directory yourdirname. Cannot stress enough that the first one needs a "./" and after the '=""' has no dot
Then import foo will work as expected









dir(js) or dir(js.window) For some things you have to look in the JS console instead of teh python terminal - especilly if trying to check for bug messages.







ValueError: Can't find a pure Python 3 wheel for: 'pygame-ce'
quickstart.py which does not exist. But you do have a main.py. Either rename the file main.py or edit the src= link in index.html

ValueError: Can't find a pure Python 3 wheel for: 'pygame-ce' 
<script id="console" type="py" terminal worker>
import code
code.interact()
</script>
I'd like to send there code from a code snippet line by line, to execute it there. That's my current code:
return async event => {
const buttonEl = event.currentTarget
const codeEl = buttonEl.nextElementSibling
const myterm = document.querySelector("#console");
let code = getCopyableText(codeEl);
for (const line of code.split('\n')) {
try {
await myterm.process(line);
await new Promise(r => setTimeout(r, 1));
} catch (e) {
console.error(e.message)
}
}
}
The issue is that sometimes it confuses lines (first screenshot), unless I set a high enough timeout (just fine, second screenshot). Is there known tuned value for the timeout this to be reliable or is there a way to enforce synchronous execution? Thank you.
<script id="console" type="py" terminal worker>
import code
code.interact()
</script>
I'd like to push multiple lines to the console say to define a function (visibly in the terminal).
await document.querySelector("#console").process('def hello():')
await document.querySelector("#console").process(' print("hi")')
await document.querySelector("#console").process(' ')
await document.querySelector("#console").process(' ')
I'm not able to exit the ... three dots mode (like still defining function), until I hit a return (enter) on my keyboard in the terminal. process('\n') ends with Cannot read properties of undefined (reading 'inputType'). Any advice appreciated! (edited)

fetch(url, { signal: AbortSignal.timeout(5000) })
Source: https://stackoverflow.com/a/50101022
[js_modules.main]
"https://esm.run/three" = "THREE"
"https://esm.run/three/addons" = "addons"
"https://esm.run/ammo" = "ammo"
#"https://esm.run/ammo.wasm" = "ammo"








sqlite-wasm-3500400.zipjswasm which has sqlite3.wasm in it.
because its mpy I am unsure how to correctly load it.
E.g. this toml files with a faetch error
[files]
"./sqlite-wasm-3500400.zip" = "./*"
[js_modules.main]
"./sqlite-wasm-3500400/jswasm/sqlite3.wasm" = "sqlite3" (edited)
Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "application/wasm". Strict MIME type checking is enforced for module scripts per HTML spec.async function loadWasm() {
const response = await fetch('sqlite3.wasm');
const wasmBytes = await response.arrayBuffer();
const module = await WebAssembly.instantiate(wasmBytes, importObject); // importObject for any imports
// Use module.instance.exports
}
loadWasm();
I have uploaded the sqlite3.wasm file to the pyscript.com page to get around the zip container. - https://pyscript.com/@neon22/csv-to-pandas-sqlite3/latest?files=pyscript_mpy.toml,index.html,main.py

async function loadWasm() {
const response = await fetch('sqlite3.wasm');
const wasmBytes = await response.arrayBuffer();
const module = await WebAssembly.instantiate(wasmBytes, importObject); // importObject for any imports
// Use module.instance.exports
}
loadWasm();
I have uploaded the sqlite3.wasm file to the pyscript.com page to get around the zip container. - https://pyscript.com/@neon22/csv-to-pandas-sqlite3/latest?files=pyscript_mpy.toml,index.html,main.py pyscript.window to sql_obj = await window.initSqlJs({"locateFile": locate_file_js})locate_file_js needs to handle ffi.to_js interop.py
class SQLite:
# .....
async def _perform_initialization(self):
"""Internal method to perform the actual initialization"""
# https://sql.js.org/documentation/global.html#initSqlJs
if not hasattr(window, "initSqlJs"):
raise RuntimeError("initSqlJs not found on window. Make sure sql-wasm.js script tag is in the HTML page.")
# Create locateFile function for WASM loading
def locate_file(file, *args):
if self._cdn == "cdnjs":
return f"https://cdnjs.cloudflare.com/ajax/libs/sql.js/{self._version}/{file}"
elif self._cdn == "jsdelivr":
return f"https://cdn.jsdelivr.net/npm/sql.js@{self._version}/dist/{file}"
else:
return f"https://unpkg.com/sql.js@{self._version}/dist/{file}"
# Convert to JS function
locate_file_js = ffi.to_js(locate_file)
# Initialize SQLite-wasm
sql_obj = await window.initSqlJs({"locateFile": locate_file_js})
if not sql_obj:
raise RuntimeError("Failed to initialize SQLite-wasm")
self._sql = sql_obj
self._initialized = True
See it in action : https://jos_verlinde.pyscriptapps.com/sqlite-wasm-demo/v1/ (edited)



py
stmt = db.prepare("SELECT * FROM test WHERE name LIKE ?")
# Bindings to queries need to be converted to JS array
stmt.bind(ffi.to_js([r"%row%",]))
while stmt.step():
row = stmt.getAsObject()
print(f"Found: {row['name']}") # Should print results
ill be using this in a larger webapp - ill share feedback
<JSProxy> object. it makes even simple object mostly opaque from Python.
( Im rather a fan of typing as that prevents me from making soo many errors)
so to try to understand the format of the row object in the above :
row = stmt.getAsObject()
print("What is a row?")
print(f"{row=}")
print(f"{type(row)=}")
print(f"{repr(row)=}")
print(f"{row.__class__=}")
print(f"{dir(row)=}")
# probably a dictionary-like object
print(f"Found: {row['name']}") # Print results - so its a dict, or a tuple ?
# or a named tuple maybe?
print(f"Found: {row.name}") # Also prints the results, so a TypedDict or named tuple ?
outputs :
What is a row?
row=<JsProxy 185>
type(row)=<class 'JsProxy'>
repr(row)=<JsProxy 185>
row.__class__=<class 'JsProxy'>
dir(row)=['__class__', 'id', '__del__', 'name', 'new']
Found: Second row data
Found: Second row data
the JS API indicates it should be an Array IIUC : https://sql.js.org/documentation/Database.html#.QueryExecResult

py
class SQLite:
# .....
async def _perform_initialization(self):
"""Internal method to perform the actual initialization"""
# https://sql.js.org/documentation/global.html#initSqlJs
if not hasattr(window, "initSqlJs"):
raise RuntimeError("initSqlJs not found on window. Make sure sql-wasm.js script tag is in the HTML page.")
# Create locateFile function for WASM loading
def locate_file(file, *args):
if self._cdn == "cdnjs":
return f"https://cdnjs.cloudflare.com/ajax/libs/sql.js/{self._version}/{file}"
elif self._cdn == "jsdelivr":
return f"https://cdn.jsdelivr.net/npm/sql.js@{self._version}/dist/{file}"
else:
return f"https://unpkg.com/sql.js@{self._version}/dist/{file}"
# Convert to JS function
locate_file_js = ffi.to_js(locate_file)
# Initialize SQLite-wasm
sql_obj = await window.initSqlJs({"locateFile": locate_file_js})
if not sql_obj:
raise RuntimeError("Failed to initialize SQLite-wasm")
self._sql = sql_obj
self._initialized = True
See it in action : https://jos_verlinde.pyscriptapps.com/sqlite-wasm-demo/v1/ (edited)


file.read() ; js.Uint8Array.new(file_data) ; before handing it off to sql["Database"].new takes a considerable amount of time that I assume would be faster by not crossing boundaries for every byte.
Timing for a 6.762.496 board_comparison.db below.
Opening database 'board_comparison.db'...
micropython.mjs:1 20:20:25 reading file_data from 'board_comparison.db'...
micropython.mjs:1 20:20:38 creating db_array from file_data...
micropython.mjs:1 20:20:43 creating Database instance from db_array...
micropython.mjs:1 20:20:43 Done creating Database.
I see similar delays if I fetch the DB ( only worse by fetching) (edited)

<JSProxy> object. it makes even simple object mostly opaque from Python.
( Im rather a fan of typing as that prevents me from making soo many errors)
so to try to understand the format of the row object in the above :
row = stmt.getAsObject()
print("What is a row?")
print(f"{row=}")
print(f"{type(row)=}")
print(f"{repr(row)=}")
print(f"{row.__class__=}")
print(f"{dir(row)=}")
# probably a dictionary-like object
print(f"Found: {row['name']}") # Print results - so its a dict, or a tuple ?
# or a named tuple maybe?
print(f"Found: {row.name}") # Also prints the results, so a TypedDict or named tuple ?
outputs :
What is a row?
row=<JsProxy 185>
type(row)=<class 'JsProxy'>
repr(row)=<JsProxy 185>
row.__class__=<class 'JsProxy'>
dir(row)=['__class__', 'id', '__del__', 'name', 'new']
Found: Second row data
Found: Second row data
the JS API indicates it should be an Array IIUC : https://sql.js.org/documentation/Database.html#.QueryExecResult js.console.log(js_proxy) in there to see what you are dealing withif ref.__class__.__name__ == 'JSProxy':
from pyscript import window
window.console.log(ref)

file.read() ; js.Uint8Array.new(file_data) ; before handing it off to sql["Database"].new takes a considerable amount of time that I assume would be faster by not crossing boundaries for every byte.
Timing for a 6.762.496 board_comparison.db below.
Opening database 'board_comparison.db'...
micropython.mjs:1 20:20:25 reading file_data from 'board_comparison.db'...
micropython.mjs:1 20:20:38 creating db_array from file_data...
micropython.mjs:1 20:20:43 creating Database instance from db_array...
micropython.mjs:1 20:20:43 Done creating Database.
I see similar delays if I fetch the DB ( only worse by fetching) (edited)

if ref.__class__.__name__ == 'JSProxy':
from pyscript import window
window.console.log(ref) window.console.log(ffi.to_js(ref)) works quite well


window.console.log(ffi.to_js(ref)) works quite well
window.console.log(ref) only if ref is a JSProxy, ottherwise you'll log the JS version of that ref but you wouldn't know what ref was in the Python world ... you can mix and match though, both approaches are useful but print works fine for Python things while console.log works fine for JS things, I hope this makes sense.window.console.log(py_ref) would also just show PyProxy ... there is symmetry, I agree both cases are not the best/easiest experience to deal with though.
config="pyscript.json this works fine (well, not really because I need the packages declaration found in the config file for my script, but I'm able to do a hello world). I just get a white/blank page with no error in the JS console script.py and pyscript.json doesn't appear to be requested by the browser, no trace in the web server logs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PyScript Offline</title>
<script type="module" src="pyscript/core.js"></script>
<link rel="stylesheet" href="pyscript/core.css">
</head>
<body>
<py-config>
interpreter = "pyodide/pyodide.mjs"
</py-config>
<script type="py" config="pyscript.json" src="script.py" terminal></script>
</body>
</html>
Thanks!

config="pyscript.json this works fine (well, not really because I need the packages declaration found in the config file for my script, but I'm able to do a hello world). I just get a white/blank page with no error in the JS console script.py and pyscript.json doesn't appear to be requested by the browser, no trace in the web server logs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PyScript Offline</title>
<script type="module" src="pyscript/core.js"></script>
<link rel="stylesheet" href="pyscript/core.css">
</head>
<body>
<py-config>
interpreter = "pyodide/pyodide.mjs"
</py-config>
<script type="py" config="pyscript.json" src="script.py" terminal></script>
</body>
</html>
Thanks! <!-- Import PyScript -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script> (edited)

<!-- Import PyScript -->
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script> (edited) <py-config>
interpreter = "pyodide/pyodide.mjs"
</py-config>
But on my PC, if I run without, this doesn't work, I get this exception:
pyodide.asm.js:8 Uncaught (in promise) PythonError: Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 666, in pyimport_impl
res = __import__(stem, fromlist=fromlist)
ModuleNotFoundError: No module named 'micropip'
The module 'micropip' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("micropip") in Python, or
await pyodide.loadPackage("micropip") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
at new_error (pyodide.asm.js:8:578922)
at pyodide.asm.wasm:0x10f02c
at pyodide.asm.wasm:0x10f0f4
at callPyObjectKwargs (pyodide.asm.js:8:632734)
at Module.callPyObject (pyodide.asm.js:8:633880)
at Function.apply (pyodide.asm.js:8:650121)
at Object.apply (pyodide.asm.js:8:646549)
at Object.pyimport (pyodide.asm.js:8:682760)
But, seem like I can make it work if I add the micropip in the packages list in my pyscript.json!




await fs.mount("/data")). Chrome asked permission the first time and it was granted. Worked fine. Now, even if Chrome show the permissions is granted, I get this exception.... I wonder if someone already had this issue?
Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
...<9 lines>...
.run_async(globals, locals)
File "/lib/python313.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 33, in <module>
File "<exec>", line 26, in initPyscriptEnv
File "/home/pyodide/pyscript/fs.py", line 16, in mount
mounted[E]=await I.mountNativeFS(E,B)
^^^^^^^^^^^^^^^^^^^^^^^^^^
pyodide.ffi.JsException: NotAllowedError: The request is not allowed by the user agent or the platform in the current context.


Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
...<9 lines>...
.run_async(globals, locals)
File "/lib/python313.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 30, in <module>
File "<exec>", line 23, in initPyscriptEnv
File "/home/pyodide/pyscript/fs.py", line 16, in mount
mounted[E]=await I.mountNativeFS(E,B)
^^^^^^^^^^^^^^^^^^^^^^^^^^
pyodide.ffi.JsException: NotAllowedError: The request is not allowed by the user agent or the platform in the current context.

https://cdn.jsdelivr.net/npm/@pyscript/core@0.7.8/dist/core.js (edited)

0.7.10 is better and tested on both main and worker threads ... it works fine on Edge and Chrome/ium or browsers supporting this feature. (edited)






Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
...<9 lines>...
.run_async(globals, locals)
File "/lib/python313.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 30, in <module>
File "<exec>", line 23, in initPyscriptEnv
File "/home/pyodide/pyscript/fs.py", line 19, in mount
A=await C.idb.get(D);B=await get_handler(A)
^^^^^^^^^^^^^^^^^^^^
File "/home/pyodide/pyscript/fs.py", line 4, in get_handler
async def get_handler(details):A=details;B=A.handler;C=A.options;D=await B.queryPermission(C);return B if D=='granted'else _A
^^^^^^^^^
AttributeError: handler
On my "offline build" I get another different one Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
...<9 lines>...
.run_async(globals, locals)
File "/lib/python313.zip/_pyodide/_base.py", line 413, in run_async
await coroutine
File "<exec>", line 39, in <module>
File "<exec>", line 32, in initPyscriptEnv
File "/home/pyodide/pyscript/fs.py", line 20, in mount
if E:B=await A.idb.get(D);C=await get_handler(A,B)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/pyodide/pyscript/fs.py", line 6, in get_handler
A=details;B=A[_A];C=A[_B];D=await B.requestPermission(C)
~^^^^
TypeError: 'pyodide.ffi.JsProxy' object is not subscriptable


A[_A] to A._A (as meta-example) because we caught that on Pyodide side, nothing in 2025.10.3 uses that old accessor, it's all statick and "subscribable" access with latest ... clear your cache, clear in devtools Application the whole storage, hard refresh via Ctrl+R or Cmd+R and you won't see errors anymore, like we cannot see errors anymore with latest. (edited)








https://pyscript.net/releases/{CALVER}/core.js official channel

pyscript. It took sprinkling quite a few to_js and making some callback signatures less strict (*_) because JS doesn't care if you pass 3 argument to a function that only expects 1 (I'm looking at you, Array.prototype.map)
The page starts up kind of ok (not sure why #monthly-move-chart and #monthly-volume-chart don't render) then goes of the rails as soon as you click on those incomplete charts with a bunch of
Error: <rect> attribute x: Expected length, "NaN".
Error: <rect> attribute width: Expected length, "NaN".
Error: <path> attribute transform: Expected number, "translate(undefined, 0)".
.x(d3.scaleTime().domain(to_js([dt.date(1985, 1, 1), dt.date(2012, 12, 31)]))) so I posited that d3 does not like PyProxies so I introduced
def default_converter(value, _ignored1, _ignored2):
if isinstance(value, dt.date):
return js.Date.new(value.year, value.month - 1, value.day)
raise value
and things look happier now. Still need to sort out some CSS stuff which might be because the original uses bootstrap v2.1.1 whereas mine uses v5.3.8
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/releases/2025.10.3/core.css">
<script type="module" src="https://pyscript.net/releases/2025.10.3/core.js"></script>
</head>
<body>
<h1>Book of Alexander</h1>
<p>Using the magic of Alexander's book you can decipher and cipher Common into and out of Runes.</p>
<p>Runes are a magical language used by many highley intelligent users. It's been used to communicate and conjure forth mythical abilities.</p>
<py-script src="main.py"></py-script>
</body>
</html>


pyscript.fs.mount('/tmp') to access your directory then in there you can read files ... PyScript runs on your browser, not on your Operating System


[js_modules.main]
"https://esm.run/three" = "THREE"
"https://esm.run/three/addons" = "addons"
"https://esm.run/ammo" = "ammo"
#"https://esm.run/ammo.wasm" = "ammo" 
