Skip to content

Commit 8cab69a

Browse files
committed
restore
1 parent 955f206 commit 8cab69a

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed

examples/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Example Code
2+
==================
3+
4+
Below is a gallery of examples

examples/js_api_tour.js

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// %% [markdown]
2+
// # pyjs JavaScript API Tour
3+
// Welcome to the tour of the pyjs JavaScript API. This notebook demonstrates how to use the PYJS JavaScript API to run Python code in the browser.
4+
5+
// %% [markdown]
6+
// # Loading the pyjs module
7+
8+
// %% [code]
9+
// load the pyjs runtime by importing the pyjs_runtime_browser.js file
10+
// the url differs depending on the deployment
11+
importScripts("../../../../xeus/bin/pyjs_runtime_browser.js");
12+
13+
// the locateFile function is used to locate the wasm file
14+
// which sits next to the pyjs_runtime_browser.js file
15+
// in thism deployment
16+
let locateFile = function(filename){
17+
if(filename.endsWith('pyjs_runtime_browser.wasm')){
18+
return `../../../../xeus/bin/pyjs_runtime_browser.wasm`;
19+
}
20+
};
21+
22+
// the createModule function in from the pyjs runtime
23+
// is used to create the pyjs module
24+
let pyjs = await createModule({locateFile:locateFile});
25+
26+
// load the python packages (includung the python standard library)
27+
// from the empack environment
28+
packages_json_url = "../../../../xeus/kernels/xpython/empack_env_meta.json"
29+
package_tarballs_root_url = "../../../../xeus/kernel_packages/"
30+
await pyjs.bootstrap_from_empack_packed_environment(
31+
packages_json_url,
32+
package_tarballs_root_url
33+
);
34+
35+
36+
// %% [markdown]
37+
// # Evaluating Python expressions:
38+
// From now on, you can use the pyjs module to run python code.
39+
// Here we use "eval" to evaluate a python expression
40+
41+
// %% [code]
42+
pyjs.eval("print('hello world')");
43+
44+
// %% [markdown]
45+
// # Executing Python code
46+
// Here we execute a python code block using "exec" function
47+
48+
// %% [code]
49+
pyjs.exec(`
50+
import numpy
51+
print(numpy.random.rand(3))
52+
`);
53+
54+
// %% [markdown]
55+
// # Executing Python code and returning the last expression
56+
// Here we execute a python code block using "exec" function and return the last expression.
57+
58+
59+
// %% [code]
60+
let rand_arr = pyjs.exec_eval(`
61+
import numpy
62+
numpy.random.rand(2,4,3)
63+
`);
64+
rand_arr.delete()
65+
66+
// %% [markdown]
67+
68+
// # Using the pyobject class
69+
// When a python object is returned, it is wrapped in a pyobject class.
70+
// This class provides methods to interact with the python object.
71+
// Any created instance of the pyobject class needs to be deleted using the "delete" method.
72+
73+
// %% [code]
74+
// create a numpy array with [0,1,2,3] as value
75+
let arr = pyjs.exec_eval(`
76+
import numpy
77+
numpy.arange(0,4)
78+
`);
79+
80+
// get the shape
81+
let arr_shape = arr.shape
82+
83+
// get the square function
84+
const square_func = pyjs.eval('numpy.square')
85+
86+
// any function call / __call__ like operator on the python side
87+
// is called via "py_call"
88+
const res = square_func.py_call(arr)
89+
90+
// print the result
91+
console.log(res)
92+
93+
// delete all the created pyobjects
94+
res.delete()
95+
square_func.delete()
96+
arr_shape.delete()
97+
arr.delete()
98+
99+
// %% [markdown]
100+
// # Type Conversion
101+
// pyjs provides methods to convert between JavaScript and Python types.
102+
// ## Explicit conversion
103+
104+
// %% [code]
105+
// python list to javascript array
106+
const py_list = pyjs.eval("[1,2,3]")
107+
const js_arr = pyjs.to_js(py_list)
108+
py_list.delete()
109+
console.log(js_arr)
110+
111+
// python dict to js map
112+
const py_dict = pyjs.eval("dict(a=1, b='fobar')")
113+
const js_map = pyjs.to_js(py_dict)
114+
py_dict.delete()
115+
116+
// values
117+
console.log(Array.from(js_map.keys()))
118+
// keys
119+
console.log(Array.from(js_map.values()))
120+
121+
// %% [markdown]
122+
// ## Implicit conversion
123+
// Fundamental types are automatically converted between Python and JavaScript.
124+
// This includes numbers, strings, booleans and null.
125+
126+
// %% [code]
127+
// sum is a plain javascript number
128+
const sum = pyjs.eval("sum([i for i in range(0,101)])")
129+
sum
130+
131+
// %% [code]
132+
// is_true is a plain javascript boolean
133+
const is_true = pyjs.eval("sum([i for i in range(0,101)]) == 5050")
134+
is_true
135+
136+
// %% [code]
137+
// none will be undefined
138+
let none = pyjs.eval('None')
139+
console.log(none)
140+
141+
// %% [markdown]
142+
// # Asynchronous execution
143+
// The pyjs module provides a way to run python code asynchronously using the "exec_async" function.
144+
145+
// %% [code]
146+
const py_code = `
147+
import asyncio
148+
await asyncio.sleep(2)
149+
sum([i for i in range(100)])
150+
`
151+
result = await pyjs.async_exec_eval(py_code)
152+
console.log(result);

examples/py_api_tour.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# %% [markdown]
2+
# # A tour of the Python API
3+
4+
5+
# %% [code]
6+
import pyjs
7+
8+
# %% [markdown]
9+
# # Accessing the the JavaScript global object
10+
#
11+
# The global object in javascript is accessible via `pyjs.js`.
12+
# Since this example runs **not** in the main thread, but only
13+
# in a worker thread, we can not acces the window object, but
14+
# only whats available in the workers global scope / globalThis.
15+
# We can for instance print the page origin like this:
16+
#
17+
18+
# %% [code]
19+
pyjs.js.location.origin # equivalent to the javascript expression `location.origin` / `globalThis.location.origin`
20+
21+
# %% [markdown]
22+
# # Create JavaScript functions on the fly
23+
24+
# %% [code]
25+
# define the function
26+
js_function = pyjs.js.Function("a", "b", "return a + b")
27+
28+
# %% [code]
29+
# call the function
30+
result = js_function(1, 2)
31+
result
32+
33+
# %% [markdown]
34+
# # Type conversion
35+
#
36+
# Pyjs allows to convert between python and javascript types.
37+
#
38+
# ## Explicit conversion
39+
40+
# %% [code]
41+
# convert a python list to a javascript array
42+
js_list = pyjs.js.eval("[1,2,3]")
43+
# pylist is a vanilla python list
44+
py_list = pyjs.to_py(js_list)
45+
py_list
46+
47+
# %% [code]
48+
# convert a nested javascript object to a python dict
49+
js_nested_object = pyjs.js.Function("return{ foo:42,bar:[1,{a:1,b:2}]};")()
50+
py_dict = pyjs.to_py(js_nested_object)
51+
py_dict
52+
53+
# %% [markdown]
54+
# ### Custom converters
55+
#
56+
# Pyjs allows to register custom converters for specific javascript classes.
57+
58+
# %% [code]
59+
# Define JavaScript Rectangle class
60+
# and create an instance of it
61+
rectangle = pyjs.js.Function("""
62+
class Rectangle {
63+
constructor(height, width) {
64+
this.height = height;
65+
this.width = width;
66+
}
67+
}
68+
return new Rectangle(10,20)
69+
""")()
70+
71+
# A Python Rectangle class
72+
class Rectangle(object):
73+
def __init__(self, height, width):
74+
self.height = height
75+
self.width = width
76+
77+
# the custom converter
78+
def rectangle_converter(js_val, depth, cache, converter_options):
79+
return Rectangle(js_val.height, js_val.width)
80+
81+
# Register the custom converter
82+
pyjs.register_converter("Rectangle", rectangle_converter)
83+
84+
# Convert the JavaScript Rectangle to a Python Rectangle
85+
r = pyjs.to_py(rectangle)
86+
assert isinstance(r, Rectangle)
87+
assert r.height == 10
88+
assert r.width == 20
89+
90+
# %% [markdown]
91+
# ## Implicit conversion
92+
# ## Implicit conversion
93+
# Fundamental types are automatically converted between Javascript and Python.
94+
# This includes numbers, strings, booleans and undefined and null.
95+
96+
# %% [code]
97+
# this will convert the javascript string to a python string
98+
origin = pyjs.js.location.origin
99+
assert isinstance(origin, str)
100+
101+
# or results from a javascript function
102+
js_function = pyjs.js.Function("a", "b", "return a + b")
103+
result = js_function("hello", "world")
104+
assert isinstance(js_function("hello", "world"), str)
105+
assert isinstance(js_function(1, 2), int)
106+
assert isinstance(js_function(1.5, 2.0), float)
107+
assert isinstance(js_function(1.5, 2.5), int) # (!)

0 commit comments

Comments
 (0)