mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 10:17:23 -05:00
committed by
GitHub
parent
69b8884045
commit
a1268f1aa2
@@ -30,6 +30,7 @@
|
||||
# as it works transparently in both the main thread and worker cases.
|
||||
|
||||
from pyscript.display import HTML, display
|
||||
from pyscript.fetch import fetch
|
||||
from pyscript.magic_js import (
|
||||
RUNNING_IN_WORKER,
|
||||
PyWorker,
|
||||
|
||||
64
pyscript.core/src/stdlib/pyscript/fetch.py
Normal file
64
pyscript.core/src/stdlib/pyscript/fetch.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import json
|
||||
|
||||
import js
|
||||
|
||||
|
||||
def _as_bytearray(buffer):
|
||||
ui8a = js.Uint8Array.new(buffer)
|
||||
size = ui8a.length
|
||||
ba = bytearray(size)
|
||||
for i in range(0, size):
|
||||
ba[i] = ui8a[i]
|
||||
return ba
|
||||
|
||||
|
||||
class _Fetch:
|
||||
def __init__(self, url, **kw):
|
||||
# avoid both Pyodide and MicroPython FFI
|
||||
options = js.JSON.parse(json.dumps(kw))
|
||||
self._url = url
|
||||
self._fetch = js.fetch(url, options)
|
||||
|
||||
async def _arrayBuffer(self):
|
||||
response = await self._response()
|
||||
return await response.arrayBuffer()
|
||||
|
||||
async def _response(self):
|
||||
response = await self._fetch
|
||||
if not response.ok:
|
||||
msg = f"URL {self._url} failed with status {response.status}"
|
||||
raise Exception(msg)
|
||||
return response
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/Response/arrayBuffer
|
||||
# returns a memoryview of the buffer
|
||||
async def arrayBuffer(self):
|
||||
buffer = await self._arrayBuffer()
|
||||
# works in Pyodide
|
||||
if hasattr(buffer, "to_py"):
|
||||
return buffer.to_py()
|
||||
# shims in MicroPython
|
||||
return memoryview(_as_bytearray(buffer))
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/Response/blob
|
||||
async def blob(self):
|
||||
response = await self._response()
|
||||
return await response.blob()
|
||||
|
||||
# return a bytearray from the uint8 view of the buffer
|
||||
async def bytearray(self):
|
||||
buffer = await self._arrayBuffer()
|
||||
return _as_bytearray(buffer)
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/Response/json
|
||||
async def json(self):
|
||||
return json.loads(await self.text())
|
||||
|
||||
# https://developer.mozilla.org/en-US/docs/Web/API/Response/text
|
||||
async def text(self):
|
||||
response = await self._response()
|
||||
return await response.text()
|
||||
|
||||
|
||||
def fetch(url, **kw):
|
||||
return _Fetch(url, **kw)
|
||||
75
pyscript.core/test/fetch.html
Normal file
75
pyscript.core/test/fetch.html
Normal file
@@ -0,0 +1,75 @@
|
||||
<!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="../dist/core.css">
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import fetch from 'https://esm.run/@webreflection/fetch';
|
||||
|
||||
globalThis.fetch_text = await fetch("config.json").text();
|
||||
globalThis.fetch_json = JSON.stringify(await fetch("config.json").json());
|
||||
globalThis.fetch_buffer = new Uint8Array((await fetch("config.json").arrayBuffer())).length;
|
||||
|
||||
document.head.appendChild(
|
||||
Object.assign(
|
||||
document.createElement('script'),
|
||||
{
|
||||
type: 'module',
|
||||
src: '../dist/core.js'
|
||||
}
|
||||
)
|
||||
);
|
||||
</script>
|
||||
<script type="mpy" async>
|
||||
import js, json
|
||||
from pyscript import document, fetch
|
||||
|
||||
fetch_text = await fetch("config.json").text()
|
||||
if (fetch_text != js.fetch_text):
|
||||
raise Exception("fetch_text")
|
||||
|
||||
fetch_json = await fetch("config.json").json()
|
||||
if (json.dumps(fetch_json).replace(" ", "") != js.fetch_json):
|
||||
raise Exception("fetch_json")
|
||||
|
||||
fetch_buffer = await fetch("config.json").bytearray()
|
||||
if (len(fetch_buffer) != js.fetch_buffer):
|
||||
raise Exception("fetch_buffer")
|
||||
|
||||
print(await fetch("config.json").bytearray())
|
||||
print(await fetch("config.json").blob())
|
||||
|
||||
try:
|
||||
await fetch("shenanigans.nope").text()
|
||||
except:
|
||||
document.documentElement.classList.add('mpy')
|
||||
</script>
|
||||
<script type="py" async>
|
||||
import js, json
|
||||
from pyscript import document, fetch
|
||||
|
||||
fetch_text = await fetch("config.json").text()
|
||||
if (fetch_text != js.fetch_text):
|
||||
raise Exception("fetch_text")
|
||||
|
||||
fetch_json = await fetch("config.json").json()
|
||||
if (json.dumps(fetch_json).replace(" ", "") != js.fetch_json):
|
||||
raise Exception("fetch_json")
|
||||
|
||||
fetch_buffer = await fetch("config.json").bytearray()
|
||||
if (len(fetch_buffer) != js.fetch_buffer):
|
||||
raise Exception("fetch_buffer")
|
||||
|
||||
print(await fetch("config.json").bytearray())
|
||||
print(await fetch("config.json").blob())
|
||||
|
||||
try:
|
||||
await fetch("shenanigans.nope").text()
|
||||
except:
|
||||
document.documentElement.classList.add('py')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -78,3 +78,8 @@ test('Pyodide + multiple terminals via Worker', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/py-terminals.html');
|
||||
await page.waitForSelector('html.first.second');
|
||||
});
|
||||
|
||||
test('MicroPython + Pyodide fetch', async ({ page }) => {
|
||||
await page.goto('http://localhost:8080/test/fetch.html');
|
||||
await page.waitForSelector('html.mpy.py');
|
||||
});
|
||||
|
||||
1
pyscript.core/types/stdlib/pyscript.d.ts
vendored
1
pyscript.core/types/stdlib/pyscript.d.ts
vendored
@@ -3,6 +3,7 @@ declare namespace _default {
|
||||
"__init__.py": string;
|
||||
"display.py": string;
|
||||
"event_handling.py": string;
|
||||
"fetch.py": string;
|
||||
"magic_js.py": string;
|
||||
"util.py": string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user