Skip to content

Commit 441c89d

Browse files
committed
Edits.
1 parent 50a92ee commit 441c89d

File tree

5 files changed

+107
-78
lines changed

5 files changed

+107
-78
lines changed

docs/faq.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,10 @@ done"` message is written to the browser's console.
705705

706706
Applications need third party packages and [PyScript can be configured to
707707
automatically install packages for you](user-guide/configuration/#packages).
708-
Yet packaging can be a complicated beast, so here are some
708+
Yet [packaging can be a complicated beast](#python-packages), so here are some
709709
hints for a painless packaging experience with PyScript.
710710

711-
There are essentially four ways in which a third party package can become
711+
There are essentially five ways in which a third party package can become
712712
available in PyScript.
713713

714714
1. The module is already part of either the Pyodide or MicroPython
@@ -724,10 +724,11 @@ available in PyScript.
724724
3. Reference hosted Python source files, to be included on the file
725725
system, via the [`files` setting](../user-guide/configuration/#files).
726726
4. Create a folder containing the package's files and sub folders, and create
727-
a hosted `.zip` or `.tgz`/`.tar.gz`/`.whl` archive to be decompressed into the file
728-
system (again, via the
727+
a hosted `.zip` or `.tgz`/`.tar.gz`/`.whl` archive to be decompressed into
728+
the file system (again, via the
729729
[`files` setting](../user-guide/configuration/#files)).
730-
5. provide your own `.whl` package as part of the `packages = [...]` list to see it available within your project
730+
5. Provide your own `.whl` package and reference it via a URL in the
731+
`packages = [...]` list.
731732

732733
#### Host a package
733734

@@ -1207,19 +1208,23 @@ js.callback(
12071208
)
12081209
)
12091210
```
1211+
!!! info
12101212

1211-
Ultimately though, Pyodide maps can be consumed out of the box as literals, so that *some* required conversion might not be needed anymore and `to_js` might be enough, without specifying the `dict_converter` as that's inferred, once consumed, behind the scene.
1213+
Thanks to a
1214+
[recent change in Pyodide](https://github.com/pyodide/pyodide/pull/4576),
1215+
such `Map` instances are
1216+
[duck-typed](https://en.wikipedia.org/wiki/Duck_typing) to behave like
1217+
object literals. Conversion may not be needed anymore, and `to_js` may just
1218+
work without the need of the `dict_converter`. Please check.
12121219

1213-
In addition, MicroPython's version of `to_js` takes the opposite approach (for
1220+
MicroPython's version of `to_js` takes the opposite approach (for
12141221
many of the reasons stated above) and converts Python dictionaries to object
12151222
literals instead of `Map` objects.
12161223

12171224
As a result, **the PyScript `pyscript.ffi.to_js` ALWAYS returns a JavaScript
12181225
object literal by default when converting a Python dictionary** no matter if
12191226
you're using Pyodide or MicroPython as your interpreter.
12201227

1221-
That being said, in MicroPython things work closely to JS users' expectations, memory friendly too, so using the `to_js` is more a cross-interpreter guard than a necessity these days.
1222-
12231228
#### Caveat
12241229

12251230
!!! warning

docs/user-guide/builtins.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,13 +573,20 @@ sync.hello("PyScript")
573573
574574
### `pyscript.py_modules`
575575
576-
Bootstrapping *Pyodide* or *MicroPython* with a lot of packages might degrade the time to readyness.
576+
!!! warning
577+
578+
**This is an experimental feature.**
577579
578-
When some dependency is needed only under certain conditions or after some specific user action, we are offering an asynchronuos way to lazily import packages that were not present already in the *config*.
580+
Feedback and bug reports are welcome!
579581
580-
A bare minimal example of how this feature works can be summarized as such:
582+
If you have a lot of packages referenced in your configuration, startup
583+
performance may be degraded as these are downloaded.
581584
582-
```html title="pyscript.py_modules example"
585+
If a package is only needed under certain circumstances, we provide an
586+
asynchronous way to import packages that were not originally referenced in your
587+
configuration.
588+
589+
```html title="a pyscript.py_modules example"
583590
<script type="py" async>
584591
from pyscript import py_modules
585592
@@ -589,8 +596,8 @@ print(matplotlib, regex)
589596
</script>
590597
```
591598

592-
The `py_modules` then returns an asynchronous tuple with one or more modules passed as string and it's compatible with `.whl` packages too.
593-
599+
The `py_modules` call returns an asynchronous tuple containing the modules
600+
referenced as string arguments.
594601

595602
## HTML attributes
596603

docs/user-guide/editor.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ contained therein in a non-blocking worker.
1818

1919
!!! info
2020

21-
Once clicked, the *Run* button will show a spinner until the code is executed. This might not be visible if the code took nothing to execute, but if the code took any measurable time longer, one will notice such spinner before results will be shown.
21+
Once clicked, the "run" button will show a spinner until the code is
22+
executed. This may not be visible if the code evaluation completed quickly.
2223

2324

2425
The interpreter is not loaded onto the page until the run button is clicked. By
@@ -137,43 +138,40 @@ not expect the same behavior regular *PyScript* elements follow, most notably:
137138

138139
## Read / Write / Execute
139140

140-
Behind the scene, we bootstrap an editor that provides:
141-
142-
* highlights around the Python code in it
143-
* a Run button to execute the code
144-
* a `target` reference where the code output lands, once printed
145-
146-
This is all great and sound, but there is also a way to read the *editor* code, and update it with ease, that's the `code` accessor any editor gets, once bootstrapped:
141+
Sometimes you need to programatically read, write or execute code in an
142+
editor. Once PyScript has started, every py-editor/mpy-editor script tag gets
143+
a `code` accessor attached to it.
147144

148145
```python
149146
from pyscript import document
150147

151-
# grab the editor script reference
148+
# Grab the editor script reference.
152149
editor = document.querySelector('#editor')
153150

154-
# output its content
151+
# Output the live content of the editor.
155152
print(editor.code)
156153

157-
# or update its content
154+
# Update the live content of the editor.
158155
editor.code = """
159156
a = 1
160157
b = 2
161158
print(a + b)
162159
"""
163-
```
164-
165-
To execute that new editor content a user might click the *Run* button one more time, or the driver of such editor can use `editor.process(editor.code)`, or any other arbitrary code, to actually bypass the need to click *Run* and execute the code passed along the `.process(...)` invoke.
166160

167-
These utilities are helpful to let consumers of the editor change its view state and/or execute it out the box.
168-
169-
## Config
170-
171-
Differently from `<script type="py">` or `<py-script>`, and the `mpy` counterpart, a *PyEditor* is not affected by the presence of `<py-config>` elements in the page: it requires an explicit `config="..."` attribute to specify its dependencies, behavior and whatnot.
161+
# Evaluate the live code in the editor.
162+
# This could be any arbitrary code to evaluate in the editor's Python context.
163+
editor.process(editor.code)
164+
```
172165

173-
If a `setup` editor is present though, that's the only *PyEditor* that needs a config, so that any further related editor will have already such config parsed and bootstrapped.
166+
## Configuration
174167

175-
That is: do not expect `<py-config>` to dictate the behavior of a `py-editor`, these are *two different kind of custom script* so that an editor, when needed, must use a `config` attribute.
168+
Unlike `<script type="py">` or `<py-script>` (and the `mpy` equivalents), a
169+
PyEditor is not influenced by the presence of `<py-config>` elements in the
170+
page: it requires an explicit `config="..."` attribute.
176171

172+
If a `setup` editor is present, that's the only PyEditor that needs a config.
173+
Any subsequent related editor will reuse the config parsed and bootstrapped for
174+
the `setup` editor.
177175

178176
## Still missing
179177

docs/user-guide/terminal.md

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -153,20 +153,36 @@ may wish to use.
153153

154154
### MicroPython
155155

156-
When it comes to *MicroPython*, we recently enabled a proper *REPL* mode that offers an easier way to have a fully functional terminal, including:
157-
158-
* all *Ctrl+X* strokes are handled, including *paste mode* and kill switches
159-
* **history** works out of the box, *arrow up* and see what you pasted or typed before
160-
* **tab completion** works too, *tab* away to see your previously referenced variables or available globals
161-
* **copy and paste** improved, out of a singe terminal entry or a *paste mode* enabled variant
162-
163-
In few words, the *MicroPython* terminal is somehow superior and broadly aligned with a regular *MicroPython terminal / REPL* experience, and strawberry on top, it works on both *main* thread and *worker* related one, and these are the differences:
164-
165-
* **main thread terminal**
166-
* the `input` is, as blocking requirement, delegated to the native Web [prompt](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) utility
167-
* there is no guard against blocking executing code, such as `while True:` loops and friends
168-
* **worker thread terminal**
169-
* full support for `input` directives without ever blocking the main thread or showing *prompt* blocking relates UI around
170-
* `while True:` loops, or any other loop based, or blocking, directive, is handled out of the box without blocking the main thread UI
171-
172-
In short, we still encourage the usage of `worker` attribute to bootstrap a *MicroPython* terminal, but fear not, the script without such attribute will not throw anymore on *input* calls and it will just work almost as fine out of the main thread as long as nothing is really blocking such thread execution.
156+
MicroPython has a
157+
[very complete REPL](https://docs.micropython.org/en/latest/reference/repl.html)
158+
already built into it.
159+
160+
* All `Ctrl+X` strokes are handled, including paste mode and kill switches.
161+
* History works out of the box. Access this via the up and down arrows to
162+
view your command history.
163+
* Tab completion works like a charm. Use the `tab` key to see available
164+
variables or objects in `globals`.
165+
* Copy and paste is much improved. This is true for a single terminal entry,
166+
or a
167+
[paste mode](https://docs.micropython.org/en/latest/reference/repl.html#paste-mode)
168+
enabled variant.
169+
170+
As a bonus, the MicroPython terminal works on both the main thread and in
171+
web workers, with the following caveats:
172+
173+
* **Main thread:**
174+
* Calls to the blocking `input` function are delegated to the native browser
175+
based
176+
[prompt](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt)
177+
utility.
178+
* There are no guards against blocking code (e.g. `while True:` loops).
179+
Such blocking code _could freeze your page_.
180+
* **Web worker:**
181+
* Conventional support for the `input` function, without blocking the main
182+
thread.
183+
* Blocking code (e.g. `while True:` loops) does not block the main thread
184+
and your page will remain responsive.
185+
186+
We encourage the usage of `worker` attribute to bootstrap a MicroPython
187+
terminal. But now you have an option to run the terminal in the main thread.
188+
Just remember not to block!

docs/user-guide/workers.md

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,17 @@ into the DOM and access some `window` based APIs.
147147
comes great responsibility... and we've given you a bazooka (so please
148148
remember not to shoot yourself in the foot with it).
149149

150-
## PyWorker
150+
## Common Use Case
151151

152-
It is possible to bootstrap either a *micropython* or a *pyodide* worker from either *micropython* or *pyodide* and within *Python* code.
152+
While it is possible to start a MicroPython or Pyodide worker from either
153+
MicroPython or Pyodide running on the main thread, the most common use case
154+
we have encountered is MicroPython on the main thread starting a Pyodide
155+
worker.
153156

154-
Due different bootstrap time, the most common use case that is going to be tackled in here is *MicroPython* bootstrapping *Pyodide* out of *Python* code, underlying each step within the process.
157+
Here's how:
155158

156-
#### Structure
157-
158-
For highlight goodness and simplicity sake, we are going to use an `mpy` script on the main page, which points at a `main.py` file that bootstraps a `worker.py` file.
159-
160-
**html**
161-
```HTML title="Pyodide worker via MicroPython"
159+
**index.html**
160+
```HTML title="Evaluate main.py via MicroPython on the main thread"
162161
<!DOCTYPE html>
163162
<html lang="en">
164163
<head>
@@ -176,48 +175,52 @@ For highlight goodness and simplicity sake, we are going to use an `mpy` script
176175
```
177176

178177
**main.py**
179-
```Python title="MicroPython bootstrapping a Pyodide worker"
178+
```Python title="MicroPython's main.py: bootstrapping a Pyodide worker."
180179
from pyscript import PyWorker, document
181180

182-
# bootstrap the pyodide worker with optional config too
183-
# the worker here is:
184-
# * owned by this script, no JS or Pyodide code in the same page can access it
185-
# * it allows pre-sync methods exposure
186-
# * it exposes a ready Promise to await pyodide on the worker side
187-
# * it then allows using post-sync (utilities exposed by pyodide)
181+
# Bootstrap the Pyodide worker, with optional config too.
182+
# The worker is:
183+
# * Owned by this script, no JS or Pyodide code in the same page can access
184+
# it.
185+
# * It allows pre-sync methods to be exposed.
186+
# * It has a ready Promise to await for when Pyodide is ready in the worker.
187+
# * It allows the use of post-sync (methods exposed by Pyodide in the
188+
# worker).
188189
worker = PyWorker("worker.py", type="pyodide")
189190

190-
# expose an utility that can be invoke *out of the box* in worker.py
191+
# Expose a utility that can be immediately invoked in the worker.
191192
worker.sync.greetings = lambda: print("Pyodide bootstrapped")
192193

193194
print("before ready")
194-
# await for Pyodide to complete its bootstrap
195+
# Await until Pyodide has completed its bootstrap, and is ready.
195196
await worker.ready
196197
print("after ready")
197198

198-
# await any exposed utility exposed via Pyodide
199+
# Await any exposed methods exposed via Pyodide in the worker.
199200
result = await worker.sync.heavy_computation()
200201
print(result)
201202

202-
# show the result at the end of the body
203+
# Show the result at the end of the body.
203204
document.body.append(result)
204205

205-
# here we free memory and get rid of everything
206+
# Free memory and get rid of everything in the worker.
206207
worker.terminate()
207208
```
208209

209210
**worker.py**
210-
```Python title="A Pyodide worker"
211+
```Python title="The worker.py script runs in the Pyodide worker."
211212
from pyscript import sync
212213

213-
# use any already exposed utility from main.py
214+
# Use any methods from main.py on the main thread.
214215
sync.greetings()
215216

216-
# expose any method meant to be used from main
217+
# Expose any methods meant to be used from main.
217218
sync.heavy_computation = lambda: 6 * 7
218219
```
219220

220-
Save these files in a *tmp* folder and use `npx mini-coi ./tmp` to reach out that `index.html` and see the following outcome in *devtools*:
221+
Save these files in a `tmp` folder, ensure [your headers](#http-headers) (just
222+
use `npx mini-coi ./tmp` and update `index.html`) then see the following
223+
outcome in the browser's devtools.
221224

222225
```
223226
before ready

0 commit comments

Comments
 (0)