blockly-samples icon indicating copy to clipboard operation
blockly-samples copied to clipboard

chore: add python interpreter demo

Open alicialics opened this issue 2 years ago • 3 comments

The basics

This is a proof-of-concept demo to add a Python Interpreter, which is almost identical to JS-Interpreter demo (in terms of both UI and code) minus the backwards-execution example. Both step-execution and async-exection are expected to work.

The details

It uses MicroPhython to evaluate python code.

The interpreter will check if the site has web worker support or not. It will run MicroPython on a Web Worker if possible, otherwise it will use the main thread while evaluating python code.

Most existing files are largely identical to the JS-Interpeter demo (with minor edits) with the exception of interpreter.js

Proposed Changes

The inspiration came from @BeksOmega's suggestion on how to add a python interepreter in the blockly developer group. I am not sure how closely it aligns with the team's philosophy (if at all) so I am fine with just leaving it here without merging it.

Test Coverage

See deployed demo: https://alicialics.github.io/blockly-samples/

Documentation

N/A

Additional Information

N/A

alicialics avatar Oct 09 '23 01:10 alicialics

@NeilFraser please take a look at this one

rachel-fenichel avatar Oct 18 '23 17:10 rachel-fenichel

This is great!

First, a quick comment relating to copyright boilerplate. You should claim credit for your code. For instance, interpreter.js should replace this:

* Copyright 2013 Google LLC with: * Copyright 2023 Zoey Li

And the resulting five line @license block should be applied to interpreter-worker.js as well (that file is currently unlicensed).

Second, this demo is missing the documentation link (for obvious reasons): → More info on running code with JS-Interpreter

The information on that link is pretty important for developers to understand how to use and configure the interpreter. Would you consider writing a version of this page (from the JS-Interpreter header): https://developers.google.com/blockly/guides/app-integration/running-javascript#js-interpreter We'd include it as a new page titled "Generating and Running Python". Markdown or Word/Google Doc or any other format is fine, we can polish it up to match the docs style. Just email the contents to [email protected] and I'll get it published.

It took me a bit of research to understand that MicroPython doesn't provide the same step-by-step protections that JS-Interpreter does. For example, a single block that becomes an infinite loop will spin harmlessly in JS-Interpreter, but should crash MicroPython: Screenshot 2023-10-19 at 12 28 02 Actually it doesn't crash MicroPython since this interpreter only handles 30 bit numbers, so it gets wrapped negative. But the point remains. Basically this interpreter is relying on Blockly's STATEMENT_PREFIX/SUFFIX to add an await

That said, Blockly's blocks don't tend to generate vulnerable code. Furthermore, MicroPython seems to be pretty good at throwing memory errors before it gets into too much trouble. So this seems like an acceptable solution.

NeilFraser avatar Oct 19 '23 17:10 NeilFraser

Thanks @NeilFraser! I've updated the PR with some simplifications to only execute code in a worker. I will see if I can draft something up regarding instructions and send it your way.

It took me a bit of research to understand that MicroPython doesn't provide the same step-by-step protections that JS-Interpreter does.

It is possible to do this with sys.settrace() in micropython however the build I am currently using does not provide this out of the box.

For example, a single block that becomes an infinite loop will spin harmlessly in JS-Interpreter, but should crash MicroPython:

MicroPython has a memory limit of 256MB and will throw an exception if this memory is exceeded. In terms of infinite loops, because the execution is done in a worker (instead of the main thread), it would keep the worker busy but not affect the main-thread (or throw an error if there is one). I've added some code to terminate the worker and start a new one when we abort mid-execution but in general if there is some kind of infinite loop it would not generally affect user experience for the blockly UI.

alicialics avatar Oct 22 '23 22:10 alicialics

I'm going to go ahead and close this since maintaining docs about integrations with other tooling is a high knowledge-maintainance burden for us.

BeksOmega avatar Jul 01 '24 16:07 BeksOmega