mirror of https://github.com/pyodide/pyodide.git
Add example here and reenable auto-deployment
This commit is contained in:
parent
34f297a679
commit
a2dfc50277
22
.travis.yml
22
.travis.yml
|
@ -30,17 +30,17 @@ install:
|
|||
script:
|
||||
- make test
|
||||
|
||||
# deploy:
|
||||
# provider: pages
|
||||
# github-token: "$GITHUB_TOKEN"
|
||||
# skip-cleanup: true
|
||||
# keep-history: false
|
||||
# repo: iodide-project/pyodide-demo
|
||||
# verbose: false
|
||||
# local-dir: build
|
||||
# target-branch: master
|
||||
# on:
|
||||
# branch: master
|
||||
deploy:
|
||||
provider: pages
|
||||
github-token: "$GITHUB_TOKEN"
|
||||
skip-cleanup: true
|
||||
keep-history: false
|
||||
repo: iodide-project/pyodide-demo
|
||||
verbose: false
|
||||
local-dir: build
|
||||
target-branch: master
|
||||
on:
|
||||
branch: master
|
||||
|
||||
env:
|
||||
global:
|
||||
|
|
6
Makefile
6
Makefile
|
@ -40,7 +40,7 @@ PANDAS_LIBS=\
|
|||
|
||||
SITEPACKAGES=root/lib/python$(PYMINOR)/site-packages
|
||||
|
||||
all: build/pyodide.asm.html build/pyodide.js build/pyodide_dev.js
|
||||
all: build/pyodide.asm.html build/pyodide.js build/pyodide_dev.js build/python.html
|
||||
|
||||
|
||||
build/pyodide.asm.html: src/main.bc src/jsimport.bc src/jsproxy.bc src/js2python.bc \
|
||||
|
@ -62,6 +62,10 @@ build/pyodide.js: src/pyodide.js
|
|||
sed -i -e 's#{{DEPLOY}}#https://iodide-project.github.io/pyodide-demo/#g' $@
|
||||
|
||||
|
||||
build/python.html: src/python.html
|
||||
cp $< $@
|
||||
|
||||
|
||||
build/test.html: src/test.html
|
||||
cp $< $@
|
||||
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Python - iodide</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://iodide-project.github.io/dist/iodide.pyodide-20180420.css">
|
||||
</head>
|
||||
<body>
|
||||
<script id="jsmd" type="text/jsmd">
|
||||
%% meta
|
||||
{
|
||||
"title": "Python",
|
||||
"languages": {
|
||||
"js": {
|
||||
"pluginType": "language",
|
||||
"languageId": "js",
|
||||
"displayName": "Javascript",
|
||||
"codeMirrorMode": "javascript",
|
||||
"module": "window",
|
||||
"evaluator": "eval",
|
||||
"keybinding": "j",
|
||||
"url": ""
|
||||
},
|
||||
"py": {
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide-project.github.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
},
|
||||
"lastExport": "2018-04-06T14:10:51.879Z"
|
||||
}
|
||||
|
||||
%% md
|
||||
# Pyodide 🐍
|
||||
|
||||
Pyodide adds support for Python in an Iodide notebook, running inside your browser.
|
||||
|
||||
**This is early days. Everything here is subject to change.**
|
||||
|
||||
(A major shortcoming is that `print` from Python currently prints to the Javascript debugger console, rather than to the notebook cell, so some of these examples are more contrived than they need to be.)
|
||||
|
||||
First, let's use a plugin cell to load the Python interpreter and tell Iodide about the new cell type.
|
||||
|
||||
%% plugin
|
||||
{
|
||||
"languageId": "py",
|
||||
"displayName": "python",
|
||||
"codeMirrorMode": "python",
|
||||
"keybinding": "p",
|
||||
"url": "https://iodide-project.github.io/pyodide-demo/pyodide.js",
|
||||
"module": "pyodide",
|
||||
"evaluator": "runPython",
|
||||
"pluginType": "language"
|
||||
}
|
||||
|
||||
%% md
|
||||
**Wait for a few seconds here...** It takes a while for Python to load, and the UI doesn't currently provide feedback about when loading and compiling is complete. (You can look in the debugger console for "Python initialization complete" however, if you're curious).
|
||||
|
||||
## Make a Python cell. Import stuff and use it.
|
||||
|
||||
Most of the standard library (at least the parts that make sense) are here and available to use.
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
import sys
|
||||
sys.version
|
||||
|
||||
%% md
|
||||
## Basic data types
|
||||
|
||||
The basic data types (None, bool, ints, floats, lists, and dicts) are converted from Python to Javascript when they are output and displayed using the standard mechanisms in Iodide.
|
||||
|
||||
%% code {"language":"py"}
|
||||
[0, 1, 32.0, 'foo', {'a': 10, 'b': '20'}, b'bytes']
|
||||
|
||||
%% md
|
||||
## Sharing objects between Python and Javascript
|
||||
|
||||
The Python and Javascript sides can pass objects back and forth.
|
||||
|
||||
So, you can set a value in Javascript code:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
secret = "Wklv#lv#olnh#pdjlf$"
|
||||
|
||||
%% md
|
||||
...and use it from Python by using `from js import ...`:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
from js import secret
|
||||
|
||||
decoded = ''.join(chr(ord(x) - 3) for x in secret)
|
||||
|
||||
%% md
|
||||
...and then get it back from Javascript using `pyodide.pyimport`:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var decoded = pyodide.pyimport("decoded")
|
||||
decoded
|
||||
|
||||
%% md
|
||||
## Custom data types
|
||||
|
||||
Non-basic data types, such as class instances, functions, File objects etc., can also be passed between Python and Javascript.
|
||||
|
||||
### Using Python objects from Javascript
|
||||
|
||||
For example, say we had the following Python function that we wanted to call from Javascript:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
def square(x, integer=False):
|
||||
if integer:
|
||||
x = int(x)
|
||||
return x * x
|
||||
|
||||
%% md
|
||||
To call a Python callable from Javascript, we use its `call` method, which takes two arguments: the positional arguments as an array, and the keyword arguments as an object.
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var square = pyodide.pyimport("square")
|
||||
square.call([2.5], {integer: true})
|
||||
|
||||
%% md
|
||||
This is equivalent to the following Python syntax:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
square(2.5, integer=True)
|
||||
|
||||
%% md
|
||||
You can also get the attributes of objects in a similar way. Say we had an instance of the following Python custom class:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
class Foo:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
foo = Foo(42)
|
||||
foo
|
||||
|
||||
%% md
|
||||
We can get the value of its `val` property as so:
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
var foo = pyodide.pyimport("foo")
|
||||
foo.getattr("val")
|
||||
|
||||
%% md
|
||||
### Using Javascript objects from Python
|
||||
|
||||
Likewise, you can use Javascript objects from Python, and since the overloading features of Python are a little more dynamic, the syntax for doing so is also a little bit easier.
|
||||
|
||||
%% js
|
||||
// javascript
|
||||
function square(x) {
|
||||
return x*x;
|
||||
}
|
||||
|
||||
%% md
|
||||
To call this function from Python...
|
||||
|
||||
%% code {"language":"py"}
|
||||
from js import square
|
||||
square(4)
|
||||
|
||||
%% md
|
||||
## Exceptions
|
||||
|
||||
Python exceptions are converted to Javascript exceptions, and they include tracebacks.
|
||||
|
||||
%% code {"language":"py"}
|
||||
x = 5 / 0
|
||||
|
||||
%% md
|
||||
## World DOMination
|
||||
|
||||
By using `from js import document`, you can easily access the Web API from Python.
|
||||
|
||||
For example, get the title of the document:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
from js import document
|
||||
document.title
|
||||
|
||||
%% md
|
||||
You can set it, too:
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
document.title = 'My mind is blown'
|
||||
|
||||
%% md
|
||||
We can set up a special `div` element from a markdown cell, and then manipulate it from Python.
|
||||
|
||||
<div id="targetDiv">This is a div we'll target from Python</div>
|
||||
|
||||
%% code {"language":"py"}
|
||||
# python
|
||||
# Turn the div red
|
||||
document.getElementById("targetDiv").setAttribute("style", "background-color: red")
|
||||
|
||||
%% md
|
||||
## Numpy
|
||||
|
||||
You bet, [Numpy](http://numpy.org) works.
|
||||
|
||||
(Except the `numpy.fft` module -- we're working on that, but you can get a lot done without it in a lot of use cases...)
|
||||
|
||||
%% code {"language":"py"}
|
||||
import numpy as np
|
||||
|
||||
%% md
|
||||
Let's make a simple array of zeros. When it's displayed, it's using the same output code that Iodide uses for Javascript.
|
||||
|
||||
(On a technical level, it's important to note that Pyodide doesn't need to copy the whole array over to the Javascript side to do this: it's only accessing the parts of the array it needs to make the display.)
|
||||
|
||||
%% code {"language":"py"}
|
||||
np.zeros((16, 16))
|
||||
|
||||
%% md
|
||||
### Estimating pi
|
||||
|
||||
Here's a fun example where we can estimate pi by generating a bunch of random (x, y) points and calculating the ratio of them that fall within the unit circle.
|
||||
|
||||
%% code {"language":"py"}
|
||||
from numpy import random
|
||||
points = (random.rand(1000, 2) * 2.0) - 1.0
|
||||
|
||||
%% code {"language":"py"}
|
||||
x = points[:, 0]
|
||||
y = points[:, 1]
|
||||
inside_circle = (x*x + y*y) < 1.0
|
||||
pi = (float(np.sum(inside_circle)) / float(len(points))) * 4.0
|
||||
pi
|
||||
|
||||
%% md
|
||||
## Coming soon..
|
||||
|
||||
A couple things that already work that will be coming to this example notebook soon...
|
||||
|
||||
- Pandas support
|
||||
- Plotting using D3 from Python
|
||||
|
||||
%% js
|
||||
</script>
|
||||
<div id='page'></div>
|
||||
<script src='https://iodide-project.github.io/dist/iodide.pyodide-20180420.js'></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue