-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
469e552
commit 9a82670
Showing
2 changed files
with
142 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,38 @@ | ||
# Welcome to `pyjs` | ||
|
||
Welcome | ||
Pyjs is a python - javascript FFI for webassembly. | ||
It allows you to write python code and run it in the browser. | ||
|
||
|
||
## Quickstart | ||
|
||
Access Javascript from Python: | ||
|
||
```python | ||
import pyjs | ||
|
||
# hello world | ||
pyjs.js.console.log("Hello, World!") | ||
|
||
# create a JavaScript function to add two numbers | ||
js_function = pyjs.js.Function("a", "b", """ | ||
console.log("Adding", a, "and", b) | ||
return a + b | ||
""") | ||
|
||
# call the function | ||
result = js_function(1, 2) | ||
``` | ||
|
||
Access Python from Javascript: | ||
|
||
```JavaScript | ||
// hello world | ||
pyjs.eval("print('Hello, World!')") | ||
|
||
// eval a python expression and get the result | ||
const py_list = pyjs.eval("[i for i in range(10)]") | ||
|
||
/// access | ||
console.log(py_list.get(0)) // same as py_list[0] on the python side | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# Installation | ||
|
||
## Prerequisites: | ||
|
||
https://repo.mamba.pm/emscripten-forge. | ||
Before we start, lets introduce a few concepts and tools that are used in the pyjs workflow. | ||
### Conda-forge Emscripten-Forge | ||
|
||
[Emscripten-forge](https://github.com/emscripten-forge/recipes) is similar to [conda-forge](https://conda-forge.org/) and provides packages compiled to webassembly using emscripten. | ||
|
||
### Empack | ||
https://github.com/emscripten-forge/empack is a tool to "pack" conda environments into a set of files that can be consumed by pyjs. | ||
|
||
|
||
|
||
## Installation Steps | ||
|
||
So we assume there is a directory called `/path/to/deploy` where we will | ||
put all tools which need to be served to the user. | ||
|
||
### Define a conda environment | ||
Pyjs has a conda-like workflow. This means the first step | ||
is to create a environment with the `pyjs` package installed | ||
and all packages required for the project. | ||
|
||
```yaml | ||
name: my-pyjs-env | ||
channels: | ||
- https://repo.mamba.pm/emscripten-forge | ||
- conda-forge | ||
dependencies: | ||
- pyjs | ||
- numpy | ||
``` | ||
The name of the environment can be choosen by the user. | ||
The `channels` section specifies the conda channels to use. | ||
The `https://repo.mamba.pm/emscripten-forge` is mandatory to install the `pyjs` package. | ||
The `conda-forge` channel is used to install `noarch`. | ||
All compiled packages need to be available in the `emscripten-forge` channel. | ||
|
||
### Create the environment | ||
Assuming the yaml file above is called `environment.yml` and is in the current directory, the environment can be created using `micromamba`: | ||
|
||
```Bash | ||
micromamba create -f environment.yml --platform emscripten-wasm32 --prefix /path/to/env | ||
``` | ||
|
||
### Copy pyjs | ||
Copy the pyjs binary from the environment to the deploy directory. | ||
This should move pyjs_runtime_browser.js and pyjs_runtime_browser.wasm to the deployment directory. | ||
|
||
```Bash | ||
cp /path/to/env/js_bin/pyjs/* /path/to/deploy | ||
``` | ||
|
||
|
||
|
||
### Pack the environment | ||
|
||
After the environment is defined, the next step is to pack the environment using `empack`. | ||
|
||
```Bash | ||
empack pack env --env-prefix /path/to/env --output /path/to/deploy | ||
``` | ||
This will create a tarball for each package in the environment and a `empack_env_meta.json` file that describes the environment. | ||
|
||
|
||
### The html/JavaScript code | ||
|
||
The last step is to create a html file that loads the pyjs runtime and the packed environment. | ||
|
||
```html | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Pyjs Example</title> | ||
<script src="pyjs_runtime_browser.js"></script> | ||
<script> | ||
async function runPyjs() { | ||
let locateFile = function(filename){ | ||
if(filename.endsWith('pyjs_runtime_browser.wasm')){ | ||
return `./pyjs_runtime_browser.wasm`; // location of the wasm | ||
// file on the server relative | ||
// to the pyjs_runtime_browser.js file | ||
} | ||
}; | ||
let pyjs = await createModule({locateFile}); | ||
await pyjs.bootstrap_from_empack_packed_environment( | ||
"./empack_env_meta.json", // location of the environment | ||
// meta file on the server | ||
"." // location of the packed | ||
// environment on the server | ||
); | ||
|
||
// now we can use pyjs | ||
pyjs.eval("print('hello world')"); | ||
} | ||
|
||
</script> | ||
</head> | ||
<body> | ||
<h1>Pyjs Example</h1> | ||
</body> | ||
``` |