Una guía introductoria a Brython

En esta introducción a Brython, veremos qué es, cómo instalarlo y cómo inicializar un proyecto de Brython, además de cómo realizar tareas básicas, con ejemplos.

Introducción

Cuando desarrollamos aplicaciones web, comúnmente usamos varias tecnologías y lenguajes. Un back-end se puede construir fácilmente en Java (Spring Boot), Python (Django o Flask) o JavaScript (Node.js), aunque el front-end se hace más comúnmente en JavaScript (React, Angular, etc.). A veces, incluso adoptamos el enfoque híbrido de tener páginas renderizadas del lado del servidor, con retoques finales realizados en marcos front-end como React.

A lo largo de los años, dada su prevalencia en la web, la comunidad de JavaScript amplió la funcionalidad original para habilitar back-end basados ​​en JavaScript, incluidos los front-end. La forma más común de codificar aplicaciones web en JavaScript es usar la pila MEAN. Una base de datos MongoDB, Node.js con Express.js para el back-end y Angular (o más recientemente, React) para el front-end.

Pero, ¿qué pasa si realmente prefieres desarrollar tus aplicaciones usando Python? Si bien no es aconsejable centrarse estrictamente en un lenguaje de programación (los lenguajes son herramientas, y estar obsesionado con una herramienta lo hace menos flexible), todavía hay espacio para aplicaciones de un solo idioma.

¡Brython podría ser la solución! Es una biblioteca de JavaScript que le permite ejecutar código Python dentro de su navegador.

Probablemente lo hayas adivinado, Brython significa Browser Python

Como sugiere su nombre, el objetivo principal de Brython es reemplazar JavaScript e impulsar a Python como el principal lenguaje de secuencias de comandos para navegadores web, para su aplicación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<html>
    <head>
        <script src="/brython.js"></script>
    </head>
    <body onload="brython()">
        <script type="text/python">
            import browser
            browser.document <= "Hello world!"
         </script>
    </body>
</html>

El <script> que normalmente no admite el tipo text/python puede interpretar el código Python que hemos escrito. Aquí, hemos impreso un mensaje Hello World en el browser.document, que es análogo al document de JavaScript.

En esta Guía de introducción a Brython, veremos cómo instalar Brython, cómo inicializar un proyecto de Brython, cómo diseñar páginas y compararlo con algunas alternativas.

Cómo instalar Brython

Cómo aprovechar las redes de entrega de contenido {#aprovechando las redes de entrega de contenido}

Probablemente, la forma más conveniente de instalar Brython es, de hecho, no instalarlo. Si no necesita instalarlo localmente en su PC, y solo necesita que se cargue en una página web estática para agregar alguna funcionalidad dinámica a la página, debería considerar simplemente importar un recurso externo.

La idea es cargar la biblioteca brython.js en la sección <head> de la página HTML. De esta forma, el cliente descargará la biblioteca al mismo tiempo que se carga la página HTML en su PC.

Para lograr este comportamiento, cargaremos nuestra biblioteca desde algunos de los CDN (Content Delivery Networks) que alojan la última versión estable de Brython en línea.

Una red de entrega de contenido es, en términos básicos, un grupo de servidores distribuidos que alojan algunos datos (código, contenido de video, imágenes...). Estos tipos de redes son altamente confiables y casi no tienen tiempo de inactividad. Eso los hace ideales para albergar bibliotecas de códigos.

Hay varios CDN disponibles para elegir, sin embargo, tres populares son:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Option 1 : jsDelivr CDN -->
<script src="https://cdn.jsdelivr.net/npm/[correo electrónico protegido]/brython.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[correo electrónico protegido]/brython_stdlib.js"></script>

<!-- Option 2: CloudFlare CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.9.1/brython_stdlib.min.js"></script>

<!-- Option 3: GitHub as the CDN -->
<!-- Choose this option if you want to use the latest developement version -->
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython.js"></script>
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython_stdlib.js"></script>

Instalación de Brython mediante Pip

Si desea más flexibilidad con Brython, puede instalarlo localmente:

1
$ pip3 install brython

pip descargará e instalará el paquete en su máquina local sin sudar. Verifiquemos que Brython se haya instalado correctamente:

1
$ pip show brython 

Esto imprime la versión, así como alguna información básica sobre el paquete Brython:

1
2
3
4
5
6
7
Name: brython
Version: 3.9.2
Summary: Brython is an implementation of Python 3 running in the browser
Home-page: http://brython.info
Author: Pierre Quentel
Author-email: [correo electrónico protegido]
License: BSD

Cómo inicializar un proyecto Brython

Después de instalar Brython, el próximo paso obvio es crear un proyecto simple para probar sus capacidades. Para crear el proyecto, cree una nueva carpeta y acceda a ella:

1
2
$ mkdir brython-project
$ cd brython-project

Ahora puede ejecutar el siguiente comando para inicializar un proyecto Brython:

1
$ brython-cli --install

Esto crea e inicializa un proyecto Brython, incluido el directorio del proyecto inicial y la jerarquía de archivos:

1
2
3
4
5
6
7
brython-project
    | brython.js
    | brython_stdlib.js
    | demo.html
    | index.html
    | README.md
    | unicode.txt

Primero, expliquemos para qué sirven todos estos archivos:

  • brython.js - El motor central de Brython, incluye los módulos más utilizados como browser, browser.html, javascript... Este archivo se incluye en la página HTML usando < script> etiqueta si elegimos no instalar Brython localmente.
  • brython_stdlib.js: consta de todos los paquetes y módulos de la biblioteca estándar de Python compatibles con Brython.
  • demo.html - Una página HTML simple que ejecuta Brython, muestra algunos casos de uso interesantes y ejemplos de cómo podemos utilizar Brython para modificar páginas HTML estáticas.
  • index.html - Una simple página HTML Hello World.

Es posible abrir demo.html usando solo un navegador web simple, pero este enfoque tiene sus limitaciones, por lo que se recomienda que primero inicie un servidor localhost.

Si aún no tiene instalado el módulo http, también puede instalarlo a través de pip:

1
$ pip3 install http

Una vez instalado, podemos activar el servidor:

1
$ python3 -m http.server

Ahora, debe tener localhost iniciado en un puerto 8000 (predeterminado), y debería poder acceder a la página demo.html navegando a http://localhost:8000/demo.html (o http://0.0.0.0:8000/demo.html) en la barra de direcciones del navegador web de su elección.

Si algún otro proceso utiliza actualmente el puerto 8000, deberá definir otro puerto para utilizar (por ejemplo, 8080):

1
$ python3 -m http.server 8080

Para crear una nueva página HTML que pueda ejecutar Python, solo necesita importar los archivos brython.js y brython_stdlib.js en la sección head del archivo. Luego puede pasar a escribir Python en el propio archivo HTML:

1
2
<script src="brython.js"></script>
<script src="brython_stdlib.js.js"></script>

Cómo funciona Brython

Brython nos permite escribir y ejecutar código Python en el navegador transpilar a JavaScript. Este código podrá ejecutarse en todos los navegadores modernos compatibles con JavaScript, porque Brython evita deliberadamente generar JavaScript con una sintaxis nueva no compatible.

Puedes pensar en transpilar como un subconjunto de compilar.

El proceso de compilación generalmente convierte el código fuente escrito en algún lenguaje de programación de alto nivel (por ejemplo, C) en algún lenguaje de nivel inferior (por ejemplo, código de máquina).

Por otro lado, la transpilación es un proceso de convertir un lenguaje de alto nivel en otro lenguaje de alto nivel (por ejemplo, Python a JavaScript).

La transpilación en Brython ocurre al mismo tiempo que se carga la página HTML. Aquí, llamamos a la función brython() en la etiqueta cuerpo del documento HTML:

1
<body onload="brython()">

La función brython() realiza la transpilación del código Python que está escrito en las etiquetas <script type="text/python"> del documento HTML. Todo el código de Python debe estar rodeado por la etiqueta <script type="text/python">:

1
2
3
<script type="text/python">
    <!-- Python code -->
</script>

Alternativamente, podemos incluir código Python externo usando el siguiente comando para cargarlo en el documento HTML:

1
<script type="text/python" src="test.py"></script>

Todos los navegadores web modernos admiten JavaScript como el principal lenguaje de secuencias de comandos, pero no tienen soporte para Python. Por lo tanto, todo el código de Python debe traducirse a JavaScript y luego ejecutarse en el tiempo que lleva cargar la página HTML.

Primero, la función brython() busca todo el código de Python en la página HTML al inspeccionar todos los scripts que tienen un tipo de text/python y luego traduce todo ese código a JavaScript:

El resultado de esta traducción es una representación de cadena simple del código JavaScript. Esa cadena debe ejecutarse como código JavaScript en un navegador.

Brython usa la función eval() de JavaScript para ejecutar todo el código traducido. Alternativamente, puede hacer uso del comando JavaScript nueva función (nombre_función, fuente) (módulo) para ejecutar el código en algunos navegadores.

Esta no es la forma preferida de ejecutar JavaScript. El uso de eval() puede ser peligroso porque podría exponer la aplicación a código de terceros potencialmente malicioso. Además, eval() es bastante lento en comparación con las alternativas.

Si el código Python se carga en el documento HTML a través de <script type="text/python" src="url">, Brython realiza una llamada Ajax para obtener el contenido del archivo cargado. Ese código se traduce a JavaScript y se ejecuta de la misma manera que se describe anteriormente.

Trabajar con Brython - Ejemplos

Ahora, repasemos algunos ejemplos simples para que tengas una idea de cómo funciona Brython y de lo que es capaz:

Hola mundo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<html>
    <head>
        <script src="/brython.js"></script>
    </head>
    <body onload="brython()">
        <script type="text/python">
            import browser
            browser.document <= "Hello world!"
        </script>
    </body>
</html>

Nos centraremos en el código de Python entre las etiquetas <script type="text/python"></script>:

  • importar navegador carga el paquete navegador en el script. Es el paquete que agrupa todos los nombres y módulos específicos de Brython, utilizados principalmente para representar elementos DOM y eventos utilizados en JavaScript.
  • browser.document es un objeto que representa el documento HTML que se muestra actualmente.
  • browser.document <= "¡Hola mundo!" - Estamos usando la notación <= en lugar de =. El document "receive" el nuevo elemento que contiene la cadena Hello world!. Un enfoque alternativo es usar la siguiente sintaxis: browser.document.attach("Hello world!").

En el lado del cliente, una vez que se procesa este código, da como resultado:

1
2
3
4
5
6
7
8
<html>
    <head>
        <script src="/brython.js"></script>
    </head>
    <body onload="brython()">
        Hello world!
    </body>
</html>

Adición de elementos y atributos

Modifiquemos el ejemplo anterior y agreguemos algunos párrafos y formato de texto. La interfaz del navegador nos proporciona el módulo html, que expone etiquetas HTML que podemos usar para crear dinámicamente una estructura HTML a partir del código de Python. La sintaxis para crear un objeto es:

1
browser.html.TAG("content", [attributes])

Qué salidas:

1
<TAG [attributes]>content</TAG>
  • browser.html.H2("¡Hola mundo!") envuelve la cadena Hola mundo con la etiqueta <h2>.
  • browser.html.A("enlace", href="wikihtp.com") crea una etiqueta <a href="wikihtp.com">.

Anidar también es posible con este tipo de sintaxis, simplemente al incluir un html.element dentro de otro elemento. Agreguemos algunos elementos a nuestra página:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<html>
    <head>
        <script src="/brython.js"></script>
    </head>
    <body onload="brython()">
        <script type="text/python">
            import browser
            
            title = browser.html.H2("Hello world!")

            bold = browser.html.B("bold text")
            url = browser.html.A("link", href="wikihtp.com")
            paragraph = browser.html.P("This is a paragraph. This is " + bold + ", and this is a " + url)

            browser.document <= title
            browser.document <= paragraph         
        </script>
    </body>
</html>

Alternativamente, en lugar de crear un objeto con argumentos como url = browser.html.A("link", href="wikihtp.com"), puede crearlo sin ningún argumento y construirlo:

1
2
3
4
5
6
7
8
9
# Creating an <a></a> tag
url = browser.html.A()

# Adding content between created tags
# <a>Url Text</a>
url <= "Url Text"
# Adding href attribute
# <a href="wikihtp.com">Url Text</a>
url.href = "wikihtp.com"

Cuando terminemos con el código de Python y abramos la página en un navegador, la página HTML generada debería verse así:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<html>
    <head>
        <script src="/brython.js"></script>
    </head>
    <body onload="brython()">
        <h2>Hello world!</h2>
        <p>
            This is a paragraph. This is <b>bold text</b>, and this is a 
            <a href="wikihtp.com">link</a>.
        </p>
    </body>
</html>

Tenemos un elemento <p>, dentro del cual hemos usado un elemento <b> y <a>, construidos de antemano.

Creación de tablas con Brython

Las tablas se pueden crear con la misma lógica que hemos estado aplicando hasta ahora:

1
table = browser.html.TABLE()

Ahora, vamos a crear varias filas con algunos datos simulados y agregarlos a la tabla:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Creating the row
row = browser.html.TR()
# Adding header cells
row <= browser.html.TH("Header1")
row <= browser.html.TH("Header2")
# Appending the row to the table
table <= row

# Adding a first row
row = browser.html.TR()
row <= browser.html.TD("Data 1")
row <= browser.html.TD("Data 2")
table <= row

Finalmente, optamos por mostrar la tabla en el banco <div id="table-zone"> elemento creado en la página HTML:

1
2
tableZone = browser.document["table-zone"] 
tableZone <= table

Esto da como resultado una tabla HTML en nuestra página:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<div id="table-zone">
    <table>
        <thead>
            <tr>
              <th>Header 1</th>
              <th>Header 2</th>
            </tr>
        </thead>
        <tbody>
            <tr>
              <td>Data 1</td>
              <td>Data 2</td>
            </tr>
        </tbody>
    </table>
</div>

Agregando Estilos a los Elementos Existentes

Agreguemos algo de estilo a los elementos <div id="table-zone"> y table:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
tableZone.style = {
            "background-color": "#dedfdd",
            "width": "50%",
            "min-height": "100px",
            "margin": "auto"
            }
            
table.style = {
            "border": "1px solid #333",
            "margin": "auto"
            }

Esto resultará en etiquetas HTML modificadas con el atributo estilo agregado:

1
2
3
<div id="table-zone" style="background-color: rgb(222, 223, 221); width: 50%; min-height: 100px; margin: auto;">
    
<table style="border: 1px solid rgb(51, 51, 51); margin: auto;">

Acciones de vinculación y lectura de contenido de elementos {#acciones de vinculación y lectura de contenido de elementos}

Las páginas web no son solo para mostrar datos, también sirven para capturar datos. Los formularios son una de las formas más fundamentales en que podemos solicitar a los usuarios que envíen datos. Hagamos un formulario en Brython, usando la función FORM(), junto con otros elementos HTML como INPUT() y LABEL():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Create a <div id="form-div"> element as a container for a new form
formDiv = browser.html.DIV(id="form-div")
# Create a <form> element 
form = browser.html.FORM()

# Create the <input type="text"> field wit the label and add it to the form
input = browser.html.INPUT()
input.type = "text"
input.id = "input-name"
# Add label and to the form
form <= browser.html.LABEL("Enter your name: ") + input

# Create the submit button and add it to the form
button = browser.html.INPUT()
button.type = "button"
button.value = "Submit"
button.id = "submit-button"
form <= button

# Add form to the container <div> element
formDiv <= form
# Add the <h4 id="form-response"> to show the value from the form
formDiv <= browser.html.H4("Your name is: ", id="form-response")
# Display the div element containing form on the page
browser.document <= formDiv

Un formulario que no hace nada no es muy útil. También podemos usar funciones personalizadas dentro de Brython. Hagamos una función de Python que se invoque al hacer clic en el botón Enviar. Alertará al usuario de que se ha hecho clic en el botón y actualizará el valor del elemento <h4 id="form-response">:

1
2
3
4
5
6
7
def onSubmit(ev):
    # Get the value of the <input id="input-name"> field
    name = browser.document["input-name"].value
    # Append the stored value to the content in the <h4 id="form-response"> tag
    browser.document["form-response"] <= name
    # Alert the user that the button has been clicked
    browser.alert("The Submit Button is Clicked")       

Finalmente, vinculamos el evento click del submit-button con la función onSubmit() creada, para que tengamos el comportamiento deseado al hacer clic en el botón:

1
browser.document["submit-button"].bind("click", onSubmit)

¿Cómo se compara Brython con las alternativas? {#¿Cómo se compara Brython con las alternativas?}

Hay varias otras soluciones para ejecutar el código Python en el navegador web además de Brython, entonces, ¿cuál debería elegir?

 System      Time of compilation          Running mechanism

BRYTHON Al cargar la página Transpila Python a JavaScript Transcrypt Ahead-of-time Transpila Python a JavaScript Batavia Ahead-of-time Python runtime in a browser Skulpt After page load Transpiles Python to JavaScript PyPy.js After page load Python runtime in a browser Pyodide After page load Python runtime in a browser

Algunos de ellos tienden a reemplazar por completo a JavaScript, y otros simplemente crean un entorno de Python útil para los navegadores web, como una posible alternativa a JavaScript. Por el contrario, algunas de las soluciones transpilan código de Python a JavaScript, como Brython, Skulpt y Transcrypt.

En lo que respecta al momento de la compilación, se realiza antes, después o en el momento de cargar un documento HTML.

Al comparar la velocidad de ejecución del código Python en el navegador, Brython generalmente se encuentra en el extremo más rápido del espectro. Tiende a hacer un compromiso entre la ejecución rápida de las soluciones que compilan (transpilan) Python a JavaScript con anticipación y los archivos grandes que contienen código traducido que el cliente debe (descargar) para ejecutar los scripts en " enfoque de “anticipación”.

Parece que Brython está muy cerca de ese punto dulce.

Obviamente, los puntos de referencia no siempre pueden ser representativos de situaciones del mundo real, ya que los resultados pueden variar según el código ejecutado, pero pueden brindar una comparación bastante buena entre el rendimiento de diferentes soluciones.

Nota: Por definición, Brython siempre será más lento que simplemente usar JavaScript para el mismo código. Esto se debe al paso adicional de transpilación, que nunca es de 0 ms, después del cual se ejecuta el código JavaScript.

Conclusión

Si está buscando una alternativa a JavaScript como lenguaje de secuencias de comandos para la web y no le importa demasiado el rendimiento, entonces Brython podría ser una muy buena solución.

Su enfoque equilibrado de la inevitable compensación entre la velocidad de ejecución y el exceso de uso de memoria necesario para cargar la biblioteca, lo convierte en una de las soluciones de mejor rendimiento para ejecutar Python en el navegador.

Por otro lado, Brython no tiene una gran comunidad y no es ampliamente aceptado o utilizado. Los recursos de aprendizaje son muy limitados y estará limitado principalmente a la documentación oficial sin muchos proyectos reales a gran escala a los que acudir en busca de orientación.

En última instancia, la pregunta principal es si vale la pena reemplazar JavaScript. Incluso los proyectos de Brython a pequeña escala pueden ser hasta 2 veces más lentos de ejecutar en comparación con exactamente los mismos proyectos escritos en JavaScript. A diferencia de Brython, JavaScript tiene una gran comunidad de desarrolladores, toneladas de recursos y proyectos del mundo real que muestran todo su potencial.

No olvidemos todos los marcos de JavaScript, son la columna vertebral de la popularidad de JavaScript. Sin su ayuda, JavaScript sería simplemente otro lenguaje de secuencias de comandos que nos brinda la capacidad de cambiar dinámicamente el contenido de las páginas HTML estáticas. Por ejemplo, imagine codificar una lógica compleja del lado del servidor en JavaScript puro. Incluso si eso fuera factible, ciertamente no sería una experiencia muy agradable.

Desafortunadamente, Brython no tiene marcos desarrollados para él, por lo que está restringido al código Python puro, que no es razonable para nada más que casos de uso simples. Es probable que no pueda crear una aplicación web compleja de una página con Brython, como podría hacerlo con JavaScript y Angular. Brython es una gran herramienta para los desarrolladores que desean usar solo Python para la programación del lado del servidor y del lado del cliente, pero es probable que esté muy lejos de reemplazar a JavaScript. aScript.