Outils pour utilisateurs

Outils du site


lang:python:wasm

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 :

  • On copie le contenu de l'archive pyodide afin d'elle soit accessible via l'URL : http://localhost/pyodide/pyodide.js. Il faut bien mettre toute l'archive, y compris les fichiers .data.
  • On initialise le chargement de la librairie :
  <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>
  • Puis, on charge les paquets systèmes (compilés en webassembly) dont on a besoin, soit juste avec le nom, soit avec son URL complet :
<script>
document.getElementById("demo").innerHTML = "Loading!";
languagePluginLoader.then(() => {
    pyodide.loadPackage(['numpy', 'https://localhost/pyodide/matplotlib.js']);
});
</script>
  • Enfin, on charge dans le système de fichiers interne au navigateur les modules python. Pour cela, on exécute un programme python qui va créer un fichier contenant le module python (ici : angle.py).

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>
lang/python/wasm.txt · Dernière modification : 2021/01/02 09:19 de root