Saltar al contenido

Pyodide y Pybonacci

Pyodide es un proyecto de código abierto salido de las tripas de Mozilla y liberado bajo la licencia Mozilla Public License 2.0.

Permite ejecutar código Python en el navegador.

Pero, ¿cómo?

Compilando CPython a WebAssembly. Pero, además de haber hecho eso con CPython también lo han hecho con toda la biblioteca estándar y con paquetes del stack científico como numpy, pandas, matplotlib, scipy, sympy, scikit-learn, statsmodels, astropy,…

¿Qué tiene que ver eso con Pybonacci?

Pues que gracias a Pyodide ahora puedes utilizar Python desde Pybonacci sin necesidad de instalar nada. Esto puede ser interesante cuando estás en el móvil, en un PC sin lo que necesitas instalado, etc. En la barra de menús de arriba de la página ahora verás una opción que se llama ‘RunPy’ desde la que podrás acceder a Python en tu navegador.

¿Cómo se ha metido en Pybonacci (y cómo lo puedes meter tú en tu página?

En lo que figura a continuación voy a describir una serie de cosas que he tenido que hacerle a Pyodide para que sea más usable en el navegador.

Layout de la página

El layout dispone de dos columnas, en la parte izquierda se puede ver:

  • un botón para ejecutar el código (también se puede ejecutar usando “Shift+Enter”, como en una celda de Jupyter Notebook).
  • Un área que es donde podemos escribir código. Para escribir código se usa codemirror para tener un editor más interesante.
  • Un área donde se puede ver el resultado de los prints, etc.

En la parte derecha se ve, inicialmente, una zona en blanco pero es la zona donde se pintarán los gráficos de matplotlib si decides hacer gráficos.

Editor sin gráficos
Editor sin gráficos en la parte derecha
Editor con gráfico a la derecha

El código del layout se reduce basicamente a esto:

Funcionalidad de la página, librerías de terceros

Para que la página funcione hace falta cargar una serie de bibliotecas Javascript (codemirror, pyodide).

AVISO sobre privacidad: En este momento, las librerías de terceros se cargan desde un CDN (jsdeliver) por lo que además de a Pybonacci estaréis haciendo peticiones a otra página.

Funcionalidad de la página, javascript local para añadir funcionalidad

El resto del código que uso es un script en Javascript que personaliza un poco como se usa Pyodide desde Pybonacci. Pongo el código completo del script a continuación y lo comento posteriormente:

El código anterior lo podemos desgajar en varias partes. En la primera parte accedo a varios elementos del DOM que usaré más tarde e instancio la clase CodeMirror para poder configurar un poco el editor de código que se usa. Indico que quiero que aparezca el número de línea, que el tema del editor sea cobalt (oscuro),…:

La función addToOutput lo único que hace es añadir información en la textarea que hay debajo del editor, que es la zona donde sale la información de un print, por ejemplo:

La función run_shortcut añade la funcionalidad necesaria para que al pulsar ‘Shift+Enter’ se lea el código que contiene el editor y se mande a Pyodide para que lo ejecute (con ayuda de la función evaluatePython):

Lo siguiente tiene un poco más de miga. En esta parte se inicializa el editor. Cada vez que se inicializa se inyecta algo de código Python que evalúa Pyodide.

¿Qué se inyecta y por qué?

  • Por defecto, la función print que todos conocemos de Python en Pyodide se muestra en la consola Javascript del navegador. Es decir, para ver la información del print tienes que abrir las herramientas del desarrollador de tu navegador e ir a la consola Javascript para ver lo que está mostrando Python. Como esto es un poco engorroso lo he modificado un poco para poder usar algo mínimamente más conveniente. Cuando se inicia Pyodide en Pybonacci sobreescribo la función print y el print original de Python se renombra como _print. Por tanto, el print que te encontrarás en el editor es una versión muy básica de print que te permite mostrar cosas sencillas en la zona de textarea debajo del editor. Si quieres usar el print completo de Python lo tendrás que llamar usando _print y el resultado se mostrará en la consola Javascript de tu navegador. Todo esto lo hago inyectando este código al inicio:
  • Por otra parte, al usar matplotlib desde Pyodide, cuando hacemos, por ejemplo, un plt.show no sabe dónde debe dibujar las cosas. En el escritorio disponemos de una serie de backends gráficos (Qt, Tk, etc). En el navegador no mostrará nada y no se verá la figura. Para facilitar un poco el poder usar matplotlib en Pyodide desde Pybonacci he inyectado algo más de código. El código es un context manager que envuelve un poco el resultado de la gráfica y lo mete en una etiqueta html img y se añade al DOM de la página. El código es el siguiente:

El anterior context manager me permite crear las Figures y Axes de matplotlib y que el resultado se vea posteriormente en la página. Se puede hacer así:

Si quieres meter varios Axes en la misma Figure podrías hacer:

La última parte de la inicialización incluye el ejecutar el código que he inyectado mediante Pyodide para que print, _print y el context manager Plot que he creado estén disponibles de primeras en el editor sin necesidad de que hagas nada por tu parte.

Por último, para que se ejecute el código del editor después de que pulses el botón ‘Run’ o de que pulses las teclas ‘Shift+Enter’ se usa la función evaluatePython:

La función anterior, primero limpia la zona del output (donde se muestra el resultado de un print). Limpia también la zona donde se muestran los gráficos para que se añadan los nuevos, si los hubiera en el nuevo código que estamos evaluando, y ejecuta el código del editor.

Mejoras y errores

Si quieres ver mejoras o algo no funciona bien puedes comentarlo en este artículo o puedes ir al repositorio que he creado para esto:

https://github.com/kikocorreoso/pybonacci-runpy

7 comentarios en «Pyodide y Pybonacci»

  1. Hola,

    ¿crees que se podría utilizar pyodide para correr algún add-on en Firefox?

    Estuve mirando y aparentemente todos los add-on están escritos en Java:(

    Gracias anticipadas,

    1. No sé lo que quieres hacer pero la mejor opción que tienes es usar directamente Javascript (que no java) y otras tecnologías web. Este puede ser un buen punto de partida: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension
      Potencialmente podrías usar Brython para escribir tu addon con Python: https://brython.info/
      Con Pyodide nunca me lo he planteado, la verdad, pero no veo porqué no podría funcionar también.

  2. Muchas gracias por tu comentario Kiko!

    Lo que estoy intentando hacer es un add-on para extraer información de páginas webs de noticias (artículo, título, fecha y autor) para descargarlo en un word, según tu tutorial de docx;)

    1. No necesitas un addon en un navegador para eso. Cosas como beautifulsoup, lxml, requests, requests-html, gazpacho,…, te resultarán más sencillas para lo que quieres hacer.

      1. Gracias de nuevo por el comentario Kiko,

        pensaba en un add-on por su sencillez de uso (pulsas un botón y se ejecuta) frente a beautifulsoup con python en el que tendría que abrir el programa, pegar la url, etc..

        1. Que sea sencillo de usar no implica que no sea complejo por dentro. Apretar un botón es fácil, que haga todo lo que deseas no tiene porqué ser así… Lo que quieres hacer no es trivial y te va a tocar aprender cosas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

− one = six

Pybonacci