Brython: On replacing JavaScript with Python for front-end development
Rajiv Abraham
Posted on May 5, 2020
This article was originally posted at https://blog.rajivabraham.com/posts/brython
Purpose.
This blog article will:
- give a brief introduction to using Brython, a Python implementation for front-end development on the browser
The entire project is here
Introduction
Jealous of JavaScript programmers, a cabal of Python programmers secretly met to discuss the future of Python in this apocalyptic world. JavaScript was everywhere and eating Python's lunch. With Node.js, JavaScript had invaded Python territory and ended its dominance as everyone's favorite language after Ruby(not very dominant then, is it? Mr. Author). It was time to make a thrust into the heart of JavaScript land: The Browser.
Don't forget your history(and future)
The cabal were not the only gentlemen concerned with this dilemma. The author of Transcrypt believed in poison and espionage. He decided to write a Python compiler which compiled to JavaScript code. Like good poison, there was no trace of Python. It looked very promising. But the author of this boring post found a bug and raised an issue which was unsolved/unattended for ages. So he felt it wise to abandon this side plot.
Others wanted to learn from history. Just immigrate the entire family. At least, that's what Pyodide thought of doing. Their strategy was to create an enclave on the side with a full Python Interpreter which can run Python code. Thus you could run any Python code including most of the data science stack which contains C language bindings (e.g. Numpy, Pandas).
This looks very promising too. But on initial lazy tests by this author, the initial page load was a bit slow(The real reason was that the author also could not find an easy way to make this work and was happy to not pursue it any further.)
So the cabal decided to do what every cabal is supposed to do i.e. create another Python to JavaScript compiler but this time, compile it to JavaScript when the page loads(unlike Transcrypt which compiles to JavaScript ahead of time). Thus, the fellowship of Brython was formed. One snake to rule them all.
Hello World
Let's code up the customary 'Hello World'
The Brython paratroopers(compiler) is here.
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js">
</script>
We activate it on page load
<body onload="brython()">
...
</body>
Within the body
tag above, we write the Brython Code:
<script type="text/python">
from browser import document
document <= "Hello World"
</script>
We just add Hello World
to the document element. Hmmm. That was easy.
In complete form, it's shown below.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython@3.8.8/brython.min.js">
</script>
</head>
<body onload="brython()">
<script type="text/python">
from browser import document
document <= "Hello World"
</script>
</body>
</html>
This will simply print "Hello World" to the page.
Calculator
Let's now make a calculator(code courtesy: Brython). The full code is here
Yes, you were right. We do need a table. Let's make one.
from browser import document, html
calc = html.TABLE()
Let's add the first row only. Just the display box(we'll name it result
) and C
.
calc <= html.TR(html.TH(html.DIV("0", id="result"), colspan=3) +
html.TD("C"))
Yes, I'm not very sure of this <=
syntax either. But hey, for such a lovely library, I'll settle for it too :).
Let's now add the number pad
lines = ["789/", "456*", "123-", "0.=+"]
calc <= (html.TR(html.TD(x) for x in line) for line in lines)
Finally, we add calc
to the document
document <= calc
Now that's all good. How do we make it work? First, we need to capture a reference to the result
element to manipulate it when the number pad is pressed.
result = document["result"] # direct access to an element by its id
Next, we need to update the result
whenever any element in the number pad is clicked. Let's make an event handler. We'll trust the Brython developers that this code works. Notice the manipulation of result
based on the button you clicked.
def action(event):
"""Handles the "click" event on a button of the calculator."""
# The element the user clicked on is the attribute "target" of the
# event object
element = event.target
# The text printed on the button is the element's "text" attribute
value = element.text
if value not in "=C":
# update the result zone
if result.text in ["0", "error"]:
result.text = value
else:
result.text = result.text + value
elif value == "C":
# reset
result.text = "0"
elif value == "=":
# execute the formula in result zone
try:
result.text = eval(result.text)
except:
result.text = "error"
Finally, we associate the event handler above to the click
event of all buttons.
for button in document.select("td"):
button.bind("click", action)
See, how easy it is when someone else writes the code :P. But seriously, Brython is a wonderful work of engineering and perhaps the best display of programmer love for their beloved Python language. Please support the developers, at least with a star on their Github repo!
For the advanced reader
Posted on May 5, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.