Crea interfaces fácil y rápido con Python (Eel)

Publicado por Jack el 25 de Agosto de 2020 a las 01:47

Introducción

Python es un lenguaje de programación cuya popularidad ha ido aumentando en los últimos años, a pesar de ser pensado originalmente como un lenguaje de puro backend ha incentivado a adaptar distintas bibliotecas como QT para poder ser utilizados con Python. A lo largo de los años he probado distintas bibliotecas para añadirle interfaces a mis programas en python desde QT, Tkinder hasta PyGame! He notado que si bien hay mucha documentación y el potencial para utilizar estas bibliotecas es tu imaginación, no todos tenemos el tiempo para dedicarle tiempo a que se vean bien y realmente parezcan interfaces competitivas.
Eel es una herramienta que nos permitirá realizar interfaces gráficas al estilo Electron pero de una forma sencilla, eso si, necesitaremos de un navegador web como Chrome, Edge, firefox, etc., esto por que eel monta un pequeño servicio web en el que javascript y python se comunican entre si a través de un websocket, suena complicado, pero, es más sencillo de lo que piensas, si ya tienes experiencia realizando paginas web esto te será muy familiar.

Con este tutorial veremos como hacer una interfaz sencilla pero utilizando bootstrap como base para darle una mejor presentación que si lo hiciéramos a mano.

Requisitos

  • Navegador Web
  • Python >=3.6

Paso a paso

Para este tutorial crearemos un proyecto para obtener información de animes provenientes de la pagina MyAnimeList utilizando la API Jikan.

Creando el proyecto

Para darle estructura al proyecto, vamos a utilizar la siguiente estructura, para la carpeta de bootstrap pueden descargar aquí, para el archivo eel.js lo descargan aquí Los archivos de init.py, main.py y MyAnimeList.py quedaran en blanco por el momento.

Instalando modulos

Para poder ejecutar el proyecto necesitamos instalar eel y jikan, lo hacemos de la siguiente forma:
$ pip install eel
$ pip install jikanpy

Obteniendo la información

En este apartado no voy a explicar mucho ya que no es el objetivo de este tutorial, con el siguiente script podremos obtener la información de un anime proveniente de la pagina MyAnimeList:

La información devuelta es un diccionario con todos los datos:

Creando la pagina de inicio

Para la pagina de inicio de momento pondremos una estructura simple en HTML, crearemos un archivo llamado index.html en la carpeta gui con los siguientes datos:

Para el archivo main.py añadiremos el siguiente código:

import eel #Importamos la biblioteca eel
def main():
    eel.init('gui') # Carpeta de la interfaz
    eel.start('index.html') # Archivo con la inferfaz
if name == 'main':
    main()
Después de hacer esto podemos ejecutar nuestro programa usando python main.py y se verá algo como esto:

Añadiendo funcionalidad

Exponiendo javascript a python

Para la funcionalidad modificaremos la función que creamos en javascript, pero además necesitamos cargar el archivo eel.js.
Añadimos la siguiente linea a nuestro código HTML:

<script src="./eel.js"></script>
Modificamos nuestras funciones con el siguiente código:
  // BUSCAR ANIME
  function sendData() {
    alert("Buscando el anime: "+document.getElementById('anime_name').value); 
return false; // Detenemos el envio del form } // MOSTRAR DATOS ANIME function mostrar_datos(anime){ var anime_data = JSON.stringify(anime); console.log(anime_data); } eel.expose(mostrar_datos); // Exponemos esta funcion a Python
La linea importante aquí es eel.expose(mostrar_datos); ya que esta linea lo que hace es exponer una función que definimos previamente (mostrar_datos) a Python, es decir, Python podrá acceder "directamente" a la función desde el backend.

Exponiendo python a javascript

Ahora, para que javascript pueda acceder a alguna función que definamos es necesario añadir un decorador el cual es @eel.expose
La funcion que definimos para que podamos llamar a la clase que definimos en python desde javascript es la siguiente.

@eel.expose #Exponemos la funcion a javascript
def buscar_anime(nombre):
    anime = MAL.get_anime(nombre)
    eel.mostrar_datos(anime) # accedemos a javascript desde python
    return
Notemos que el resultado de get_anime lo guardamos en la variable anime, para poder enviarla de regreso a javascript usamos eel.mostrar_datos(anime)

Llamando python desde javascript

Por ultimo así como en python usamos eel para llamar a javascript, haremos de forma análoga para llamar a python, modificaremos la funcion de send_data para que cuando enviemos el formulario mandemos a llamar a la funcion que busca el anime.

  // BUSCAR ANIME
  function sendData() {
    anime = document.getElementById('anime_name').value;
    eel.buscar_anime(anime);
    return false; // Detenemos el envio del form
  }

Mostrando datos

Ya que terminamos de unir las piezas podemos ver que cuando buscamos un anime el resultado que arroja python se imprime en la consola:

Usando jquery podemos cambiar los elementos de nuestra pagina para que se reemplacen por los que obtuvimos del anime.
  // MOSTRAR DATOS ANIME
  function mostrar_datos(anime){
    console.log(anime);
    $("#titulo").html(anime["title"]);
    $("#episodios").html("Episodios: "+anime["episodes"]);
    $("#al_aire").html("Estatus: "+anime["airing"]);
    $("#score").html("Calificación: "+anime["score"]);
    $("#sinpopsis").html("Sinpopsis: "+anime["synopsis"]);
    $("#generos").html("Generos: "+anime["genres"]);
    $("#trailer").attr('src',anime["trailer"]);
    $(".collapse").collapse('show');
  }
La pagina de prueba quedaría de la siguiente manera:

Aquí un gif de como quedaría:

Conclusión

Como pudimos ver en este tutorial integrar eel es relativamente sencillo, podemos crear interfaces web y comunicar javascript con python de una forma casi transparente, además de que no tenemos que batallar con frameworks más complicados, eel nos provee varias opciones para configurar y crear nuestras interfaces. Como podemos ver Eel es muy amigable para las personas que apenas empiezan, pero también para quienes ya tienen experiencia web y quieran hacer interfaces modernas. Con eel puedes importar todas tus bibliotecas, estilos y templates de tu preferencia, hay muchísimos ejemplos en Internet.
El ejemplo final lo puedes ver en el siguiente gif:

Si quieres probar el proyecto en tu computadora local puedes descargarlo en el link que anexo en el apéndice.

Apendice