Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pyodide support for AstroPi visualisations #913

Draft
wants to merge 52 commits into
base: main
Choose a base branch
from
Draft

Conversation

tuzz
Copy link
Contributor

@tuzz tuzz commented Jan 30, 2024

This is a work-in-progress pull request that adds support for AstroPi visualisations in PyodideRunner. We have already completed a large piece of work to migrate the _internal_sense_hat.js shim from a Skulpt module to a plain ES6 module. See the last two pages of the technical analysis document for how this was achieved. We now need to integrate this new ES6 module with the editor-ui project's <AstroPiModel> component.

To do so, we need to refactor it so that it doesn't use the Sk.sense_hat global state and instead passes senseHatConfig properties to the React component tree. I think we have successfully completed this refactor and made <AstroPiModel> work with the existing PythonRunner.jsx (Skulpt) but we now need to get it to work with Pyodide. The tests are also broken and need to be updated to provide the senseHatConfig.

Previously, I thought we needed to set these HTTP headers for the web
worker to enable SharedArrayBuffer usage, but we actually need to set
them for requests to the top-level web page. Therefore, ensure the
crossorigin attribute is added to script/link tags for cross-origin
resources.
The worker and its dependencies (pygal / _internal_sense_hat) use ES6
so we need to make sure this is transpiled as part of the standard
webpack build so that it works with all browsers.
…rams

https://pyodide.org/en/stable/usage/api/js-api.html#pyodide.FS

In the future, we could open this up to support other file types
(not just .py, .txt and .csv) and we could allow users to create files
with Python and then save the result to a component in the project, e.g.
to display an image of the Mandelbrot set.
I originally tried implementing this with redux by dispatching an event
containing the ‘content’ object but this isn’t always serialisable, e.g.
for turtle it is a JavaScript Map object. Redux prints a warning if the
object isn’t serialisable. Therefore, instead, use a channel pattern
that allows the sub-component (VisualOutput) to subscribe to the
handleVisual method calls and update its DOM.
Most of this code was copied from PythonRunner.js and then adapted to
implement the handleInput function and set the stdinBuffer array. See
this commit for more information:

RaspberryPiFoundation/python-execution-prototypes@42a7001
Previously, if you ran the following program in the editor using Pyodide
there was no way to cleanly exit:

```python
import sys

for line in sys.stdin:
    print(line)
```

This wasn’t an issue before because Skulpt only supported the input()
function which scans to the end of the line and does not look for EOF
when the standard input is closed.

To support this, add the ability to press control-d which sets the first
element in the stdinBuffer to -1. This signals to the worker that stdin
is closed, which it signals to Pyodide by returning 0 from read(buffer).
These keys are used for copying and undoing on Windows.
Jest doesn’t support Web Workers and was erroring because the
importScripts function isn’t available. Best practice seems to be to
mock the module and returned canned responses. Currently, we don’t have
Jest tests for the experimental PyodideRunner.js so an empty
implementation is sufficient but we could change this later.

https://stackoverflow.com/questions/42567535#answer-62436219
@sra405 sra405 mentioned this pull request Feb 13, 2024
Base automatically changed from pyodide-runner to main February 13, 2024 14:22
tuzz added a commit that referenced this pull request Feb 13, 2024
This pull request adds experimental support for running Python programs
using Pyodide. The code is based on the
[python-execution-prototypes](https://github.com/RaspberryPiFoundation/python-execution-prototypes)
and the [technical
analysis](https://docs.google.com/document/d/1mpKliJaqYYkPJR1hGLZxUDhNFOwgBm69nc70iiVj_3I/edit#heading=h.3orc9tdzyy4b)
document. The related GitHub issue is
#891.

The PyodideRunner.jsx can be used instead of the current
PythonRunner.jsx (Skulpt) by provided a `?pyodide=true` parameter in the
URL as shown in the screenshot below:

<img width="1439" alt="Screenshot 2024-01-30 at 11 39 01"
src="https://github.com/RaspberryPiFoundation/editor-ui/assets/892251/a0185ec3-aaf5-40d4-a5e8-e9973fb1c98f">

### Notes

The PyodideRunner supports the following features:
- Execution of Python programs
- Importing of [most
of](https://pyodide.org/en/stable/usage/wasm-constraints.html) Python's
standard library
- Importing of [many
common](https://pyodide.org/en/stable/usage/packages-in-pyodide.html)
Python packages
- Importing of pure Python packages from PyPi
- Stopping execution
- Sending standard input to Python programs
- Closing the standard input stream by pressing `Ctrl-d`
- Visualising turtle graphics using the [modified turtle
package](https://github.com/RaspberryPiFoundation/turtle)
- Visualising pygal charts using the [modified pygal
package](https://github.com/RaspberryPiFoundation/pygal.js)

Due to time constraints, the following tasks remain outstanding:

- Visualising sense_hat graphics using the [modified sense_hat
package](https://github.com/RaspberryPiFoundation/sense_hat)
- There is a work-in-progress pull request
[here](#913)
- Apply HTTP headers in a service worker (see
#903)
- Note that `crossorigin` will need to be added to cross-domain
resources once the HTTP headers are added
- Add unit/integration tests that run real Python programs through the
PyodideRunner.jsx
- Manual testing for backwards compatibility of existing Python
programs, projects and the WebComponent
- Implementing the p5 package to work with Pyodide
- See
https://github.com/RaspberryPiFoundation/python-execution-prototypes/issues/1
- Implementing a dedicated SQL editor for use in the Ada CS project
- Note that Pyodide supports importing `sqlite3` so we can add a UI
wrapper around it

---------

Co-authored-by: Scott Adams <[email protected]>
@loiswells97 loiswells97 temporarily deployed to previews/pyodide-astro-pi February 26, 2024 11:52 — with GitHub Actions Inactive
@loiswells97 loiswells97 temporarily deployed to previews/pyodide-astro-pi February 26, 2024 14:11 — with GitHub Actions Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants