Table des matières

pyodide

Présentation

C'est tout le code javascript généré depuis le runtime python.

Site github Archive v0.16.1 Documentation

Attention, c'est encore un projet dont la viabilité n'est pas encore sûre.

Exemple d'application

L'archive pyodide contient tous les fichiers javascript (*.js) et webassembly (*.data). On voit que certaines dépendances sont énormes (scipy : 170 Mo) et peuvent clairement être rédhibitoires pour une utilisation en ligne.

Les fichiers javascript de pyodide doivent être chargés via le protocole http:// et non pas via file://. Il faut donc charger le fichier index.html via une adresse de type localhost://.../index.html plutôt que file:///C:/.../index.html. Sous Windows, l'utilisation de WampServer est parfaite pour installer rapidement un serveur apache.

Le principe est simple :

  <head>
      <script type="text/javascript">
          // set the pyodide files URL (packages.json, pyodide.asm.data etc)
          window.languagePluginUrl = '/pyodide/';
      </script>
      <script src="/pyodide/pyodide.js"></script>
  </head>
  <body>
    <script>
      languagePluginLoader;
    </script>
  </body>
<script>
document.getElementById("demo").innerHTML = "Loading!";
languagePluginLoader.then(() => {
    pyodide.loadPackage(['numpy', 'https://localhost/pyodide/matplotlib.js']);
});
</script>

Exemple complet :

load_python.js
function loadPyModule(module, callback) {
  xmlHttp = new XMLHttpRequest();
  xmlHttp.open( 'GET', '/' + module + '.py', true );
  xmlHttp.overrideMimeType("text/plain; charset=x-user-defined"); 
 
  xmlHttp.onload = function() {
    document.source = this.responseText
    document.module = module
    // Enregistre le fichier dans le système de fichier du runtime Python.
    pyodide.runPython(`
import js
 
import sys
sys.path.insert(0, '/')
 
print ("python" + js.document.module + ".py")
 
with open(js.document.module + ".py", "w") as fd:
  fd.write(js.document.source)
`);
 
    // Nécessaire pour le moment.
    // Je n'arrive pas à importer un module ultérieurement.
    pyodide.runPython(`
import ` + module + `
`);
    callback();
  }
 
  xmlHttp.send('');
}
 
function loadPyModules(modules, callback, finalCallback, i = 0) {
  if (Object.is(modules.length - 1, i)) {
    loadPyModule(modules[i], finalCallback)
  } else {
    loadPyModule(modules[i], () => {
      callback(modules[i])
      loadPyModules(modules, callback, finalCallback, i + 1);
    })
  }
}
index.html
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      // set the pyodide files URL (packages.json, pyodide.asm.data etc)
      window.languagePluginUrl = '/pyodide/';
    </script>
    <script type="text/javascript" src="load_python.js"></script>
    <script src="/pyodide/pyodide.js"></script>
  </head>
<body>
 
<p id="demo"></p>
 
<script>
 
progressBar = document.getElementById("demo")
progressBar.innerHTML = "Start loading python.";
languagePluginLoader.then(() => {
  progressBar.innerHTML = "Python loaded. Loading numpy package.";
  pyodide.loadPackage(['numpy']).then(() => {
  progressBar.innerHTML = "numpy loaded. Loading scipy package.";
  pyodide.loadPackage(['scipy']).then(() => {
  progressBar.innerHTML = "scipy loaded. Loading python modules.";
  loadPyModules(['angle', 'compute'], module => { progressBar.innerHTML = module + " loaded." }, () => {
    progressBar.innerHTML = "All python modules loaded. Run example.";
 
    pyodide.runPython(`
print (angle.Angle(3.14, angle.Angle.Unite.RADIAN).get_deg())
 
print (compute.get_timestamp_ns())
`);
 
    document.getElementById("demo").innerHTML = "Success.";
  });
  });
  });
});
</script> 
 
</body>
</html>