MPyC Web is a port of the MPyC Python framework for Web Browsers. It uses:
- PyScript for running Python code in the browser via WebAssembly
- PeerJS for peer-to-peer connections via WebRTC
- Demo (stable):
- GitHub Pages - https://e-nikolov.github.io/mpyc-web
- Netlify - https://mpyc-web.netlify.app
- Demo (test):
- GitHub Pages - https://e-nikolov.github.io/mpyc-test
- Netlify - https://mpyc-test.netlify.app
- Starter:
- GitHub Pages - https://e-nikolov.github.io/mpyc-web-starter
- Netlify - https://mpyc-web-starter.netlify.app
- Starter - https://github.com/e-nikolov/mpyc-web/tree/master/mpyc-web-starter/index.html
- Starter Standalone - https://github.com/e-nikolov/mpyc-web-starter
- Demo - https://github.com/e-nikolov/mpyc-web/tree/master/mpyc-web-demo
import { MPCManager, PeerJSTransport, PyScriptWorkerRuntime } from 'https://cdn.jsdelivr.net/npm/@mpyc-web/core/+esm';
The MPCManager
requires a transport and a runtime:
let mpyc = new MPCManager(
() => new PeerJSTransport(),
() => new PyScriptWorkerRuntime()
);
// Triggered when the mpc runtime writes to stdout:
mpyc.on("runtime:display", async (message) => {
// Do something with the message, e.g. write it to a xterm.js terminal
})
// Triggered when the mpc runtime writes to stderr:
mpyc.on("runtime:display:error", async (error) => {
// Do something with the error, e.g. write it to a xterm.js terminal
})
// Triggered when the transport is ready and has an ID
mpyc.on("transport:ready", async (partyID) => {
// Do something with our ID, e.g. send it to someone else via a chat message so they can connect to us
})
// Triggered when someone has connected to us
mpyc.on("transport:conn:ready", async (peerID) => {
// Do something with their ID
});
// Triggered when someone has disconnected from us
mpyc.on("transport:conn:disconnected", async (peerID) => {
// Do something with their ID
});
mpyc.transport.connect("<the other party's ID>")
mpyc.runMPC('<Python source code using the MPyC framework>', '<filename to be shown in debug outputs>');
mpyc-web relies on some relatively new browser features:
Some of those features only work in secure contexts, which requires some additional headers to be specified by the server:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
If it is not possible to configure the server to supply those headers, e.g. on GitHub Pages, an alternative is to use a ServiceWorker to intercept the responses and add the necessary headers, see coi-serviceworker. This solution however does not work in some cases, e.g. a private window on Firefox.
- Install nix
- Linux with Systemd or MacOS - https://github.com/DeterminateSystems/nix-installer/
- Linux without Systemd - https://nixos.org/download.html
- Start a development shell with all necessary tools -
nix develop --impure
- Install the JavaScript dependencies -
yarn install
yarn dev
yarn build
python -m http.server -d dist