this is my first question on SO. Please give me directions if the question is not clear.
I am trying to get an image from a public API and write it on a webpage using PyScript.
However, I am not able to get the image to display on the webpage. I tried different packages to read the image (PIL, matplotlib, imageio) and different methods to display the output (Setting "output" at the beginning of pyscript, using pyscript.write() ). Below you can find a full (non-working) example.
img
is formatted as a Numpy array with uint8
values.
UPDATE: The data is obtained correctly from the API. If I treat the data as Numpy array I can see all the pixel values. However, I am not able to display the image on the webpage afterwards.
<!DOCTYPE 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>
- matplotlib
- imageio
</py-env>
</head>
<body>
<h1>PyScript - images from API</h1>
<div>
<p>
This webpage fetches a cat image from <a href="https://cataas.com/#/", target="_blank">cataas</a> and displays it below.
</p>
</div>
<div id="image"></div>
<py-script output="image">
from pyodide.http import pyfetch
import asyncio
from io import BytesIO
import matplotlib.pyplot as plt
import imageio.v3 as iio
response = await pyfetch(url="https://cataas.com/cat", method="GET")
img = iio.imread(BytesIO(await response.bytes()), index=None)
imgplot = plt.imshow(img)
imgplot
</py-script>
</body>
</html>
I tested on both Chrome and Firefox, but the image is never displayed.
Thanks in advance!
you need to assign the output image to some element in HTML document. Inside pyscript node add something like:
document.querySelector("img").setAttribute("src", img)
will display the image in tag:
<img id ="img" src="src">
Use id="img" for .CSS
And, I dont know how your code for downloading the images works but I googled a lot (dont remember the source, most likely this: https://www.jhanley.com/pyscript-loading-python-code-in-the-browser/) and created two functions:
async def download(url):
filename = Path(url).name
response = await pyfetch(url)
if response.status == 200:
status = response.status
with open(filename, mode="wb") as file:
file.write(await response.bytes())
return filename, status
else:
status = response.status
filename = None
return filename, status
async def process_response(url):
response_content = await loop.run_until_complete(
download(url)
)
if response_content[1] == 200:
data = base64.b64encode(open(response_content[0], "rb").read()).decode("utf-8")
src = f"data:image/png;base64,{data}"
return src
else:
src = None
return src
img = await process_response("url")
document.querySelector("img").setAttribute("src", img)