2020-10-30 20:09:25 +00:00
(using_from_javascript)=
2018-06-21 15:19:34 +00:00
# Using Pyodide from Javascript
2020-12-31 12:23:03 +00:00
This document describes using Pyodide directly from Javascript.
2018-06-21 15:19:34 +00:00
## Startup
2020-05-20 16:58:43 +00:00
To include Pyodide in your project you can use the following CDN URL,
2018-06-21 15:19:34 +00:00
2020-12-25 21:05:54 +00:00
https://cdn.jsdelivr.net/pyodide/v0.16.1/full/pyodide.js
2019-05-31 20:02:51 +00:00
2020-05-20 16:58:43 +00:00
You can also download a release from
[Github releases ](https://github.com/iodide-project/pyodide/releases )
(or build it yourself), include its contents in your distribution, and import
the `pyodide.js` file there from a `<script>` tag. See the following section on
2021-03-03 08:11:50 +00:00
[serving Pyodide files ](#serving-pyodide-files ) for more details.
2019-05-31 20:02:51 +00:00
2020-05-20 16:58:43 +00:00
The `pyodide.js` file has a single `Promise` object which bootstraps the Python
environment: `languagePluginLoader` . Since this must happen asynchronously, it
is a `Promise` , which you must call `then` on to complete initialization. When
2021-03-03 08:11:50 +00:00
the promise resolves, Pyodide will have installed a namespace in global scope:
2018-06-21 15:19:34 +00:00
`pyodide` .
2021-02-15 08:38:49 +00:00
```pyodide
2018-11-08 13:25:33 +00:00
languagePluginLoader.then(() => {
2021-03-03 08:11:50 +00:00
// Pyodide is now ready to use...
2021-02-15 08:38:49 +00:00
console.log(pyodide.runPython(`import sys\nsys.version`));
2018-06-21 15:19:34 +00:00
});
```
## Running Python code
2021-02-06 20:17:57 +00:00
Python code is run using the {any}`pyodide.runPython`
2020-10-31 20:00:58 +00:00
function. It takes as input a string of Python
code. If the code ends in an expression, it returns the result of the
expression, converted to Javascript objects (see {ref}`type_conversions`).
2018-06-21 15:19:34 +00:00
2021-02-15 08:38:49 +00:00
```pyodide
2020-07-13 19:46:20 +00:00
pyodide.runPython(`
import sys
sys.version
`);
2018-06-21 15:19:34 +00:00
```
2021-03-03 08:11:50 +00:00
After importing Pyodide, only packages from the standard library are available.
2020-10-31 09:02:23 +00:00
See {ref}`loading_packages` documentation to load additional packages.
2020-05-20 16:58:43 +00:00
## Complete example
Create and save a test `index.html` page with the following contents:
2021-02-15 08:38:49 +00:00
```html-pyodide
2020-05-20 16:58:43 +00:00
<!DOCTYPE html>
< html >
2020-07-13 19:46:20 +00:00
< head >
< script type = "text/javascript" >
2021-03-03 08:11:50 +00:00
// set the Pyodide files URL (packages.json, pyodide.asm.data etc)
2020-12-25 21:05:54 +00:00
window.languagePluginUrl = 'https://cdn.jsdelivr.net/pyodide/v0.16.1/full/';
2020-07-13 19:46:20 +00:00
< / script >
2020-12-25 21:05:54 +00:00
< script src = "https://cdn.jsdelivr.net/pyodide/v0.16.1/full/pyodide.js" > < / script >
2020-07-13 19:46:20 +00:00
< / head >
< body >
Pyodide test page < br >
2021-03-03 08:11:50 +00:00
Open your browser console to see Pyodide output
2020-05-20 16:58:43 +00:00
< script type = "text/javascript" >
2020-07-13 19:46:20 +00:00
languagePluginLoader.then(function () {
console.log(pyodide.runPython(`
import sys
sys.version
`));
2021-02-15 08:38:49 +00:00
console.log(pyodide.runPython(`print(1 + 2)`));
2020-07-13 19:46:20 +00:00
});
2020-05-20 16:58:43 +00:00
< / script >
2020-07-13 19:46:20 +00:00
< / body >
< / html >
2020-05-20 16:58:43 +00:00
```
2020-10-13 09:58:59 +00:00
## Alternative Example
```html
<!DOCTYPE html>
2020-10-30 20:09:25 +00:00
< html >
2020-10-13 09:58:59 +00:00
< head >
< script type = "text/javascript" >
2020-12-25 21:05:54 +00:00
window.languagePluginUrl = 'https://cdn.jsdelivr.net/pyodide/v0.16.1/full/';
2020-10-13 09:58:59 +00:00
< / script >
2020-12-25 21:05:54 +00:00
< script src = "https://cdn.jsdelivr.net/pyodide/v0.16.1/full/pyodide.js" > < / script >
2020-10-13 09:58:59 +00:00
< / head >
< body >
< p > You can execute any Python code. Just enter something in the box below and click the button.< / p >
2020-10-30 20:09:25 +00:00
< input id = 'code' value = 'sum([1, 2, 3, 4, 5])' >
2020-10-13 09:58:59 +00:00
< button onclick = 'evaluatePython()' > Run< / button >
< br >
< br >
< div >
Output:
< / div >
< textarea id = 'output' style = 'width: 100%;' rows = '6' disabled > < / textarea >
< script >
2020-10-30 20:09:25 +00:00
const output = document.getElementById("output");
const code = document.getElementById("code");
2020-10-13 09:58:59 +00:00
function addToOutput(s) {
2020-10-30 20:09:25 +00:00
output.value += '>>>' + code.value + '\n' + s + '\n';
2020-10-13 09:58:59 +00:00
}
2020-10-30 20:09:25 +00:00
output.value = 'Initializing...\n';
2021-03-03 08:11:50 +00:00
// init Pyodide
2020-10-30 20:09:25 +00:00
languagePluginLoader.then(() => { output.value += 'Ready!\n'; });
2020-10-13 09:58:59 +00:00
function evaluatePython() {
pyodide.runPythonAsync(code.value)
.then(output => addToOutput(output))
2020-10-30 20:09:25 +00:00
.catch((err) => { addToOutput(err) });
2020-10-13 09:58:59 +00:00
}
< / script >
< / body >
< / html >
```
2021-03-03 08:11:50 +00:00
## Accessing Python scope from Javascript
2020-10-13 09:58:59 +00:00
2021-03-03 08:11:50 +00:00
You can also access from Javascript all functions and variables defined in Python using the {any}`pyodide.globals` object.
2020-10-13 09:58:59 +00:00
2021-03-03 08:11:50 +00:00
For example, if you initialize the variable `x = numpy.ones([3,3])` in Python, you can access it from Javascript in your browser's developer console as follows: `pyodide.globals.get("x")` . The same goes for functions and imports. See {ref}`type_conversions` for more details.
2020-10-13 09:58:59 +00:00
You can try it yourself in the browser console:
```js
2021-02-23 19:25:10 +00:00
pyodide.runPython(`x=numpy.ones([3, 3])`);
pyodide.globals.get("x");
2020-10-13 09:58:59 +00:00
// >>> [Float64Array(3), Float64Array(3), Float64Array(3)]
// create the same 3x3 ndarray from js
2021-02-23 19:25:10 +00:00
let x = pyodide.globals.get("numpy").ones(new Int32Array([3, 3]));
2020-10-13 09:58:59 +00:00
// x >>> [Float64Array(3), Float64Array(3), Float64Array(3)]
```
2021-03-03 08:11:50 +00:00
Since you have full scope access, you can also re-assign new values or even Javascript functions to variables, and create new ones from Javascript:
2020-10-13 09:58:59 +00:00
```js
// re-assign a new value to an existing variable
2021-02-23 19:25:10 +00:00
pyodide.globals.set("x", 'x will be now string');
2020-10-13 09:58:59 +00:00
// create a new js function that will be available from Python
// this will show a browser alert if the function is called from Python
2021-02-23 19:25:10 +00:00
pyodide.globals.set("alert", alert);
2020-10-13 09:58:59 +00:00
// this new function will also be available in Python and will return the squared value.
2021-02-23 19:25:10 +00:00
pyodide.globals.set("square", x => x*x);
2020-10-13 09:58:59 +00:00
```
Feel free to play around with the code using the browser console and the above example.
2021-03-03 08:11:50 +00:00
## Accessing Javascript scope from Python
2020-10-13 09:58:59 +00:00
2021-03-03 08:11:50 +00:00
The Javascript scope can be accessed from Python using the `js` module (see {ref}`type_conversions_using_js_obj_from_py`). This module represents the global object `window` that allows us to directly manipulate the DOM and access global variables and functions from Python.
2020-10-13 09:58:59 +00:00
```python
import js
div = js.document.createElement("div")
div.innerHTML = "< h1 > This element was created from Python< / h1 > "
js.document.body.prepend(div)
```
2021-03-03 08:11:50 +00:00
See {ref}`serving_pyodide_packages` to distribute Pyodide files locally.