Using Python in the browser
Snake Charmer
PyScript lets you use your favorite Python libraries on client-side web pages.
While there are some great Python web server frameworks such as Flask, Django, and Bottle, using Python on the server side adds complexity for web developers. To use Python on the web, you also need to support JavaScript on client-side web pages. To address this problem, some Python-to-JavaScript translators, such as JavaScripthon, Js2Py, and Transcrypt, have been developed.
The Brython (which stands for Browser Python) project [1] took the first big step in offering Python as an alternative to JavaScript by offering a Python interpreter written in JavaScript. Brython is a great solution for Python enthusiasts, because it's fast and easy to use. However, it only supports a very limited selection of Python libraries.
PyScript [2] offers a new, innovative solution to the Python-on-a-web-page problem by allowing access to many of the Python Package Index (PyPI) repository libraries. The concept behind PyScript is a little different. It uses Pyodide, which is a Python interpreter for the WebAssembly (Wasm) virtual machine. This approach offers Python within a virtual environment on the web client.
In this article, I will introduce PyScript with some typical high school or university engineering examples. I will also summarize some of the strengths and weakness that I've found while working with PyScript.
Getting Started
PyScript doesn't require any special software on either the server or client; all the coding is done directly on the web page. For PyScript to run, it needs three things (Figure 1):
- a definition in the header for the PyScript CSS and JS links,
- a
<py-config>
section to define the Python packages to load, and - a
<py-script>
section for the Python code.
In Figure 1, the <py-script>
section uses terminal=true (the default) to enable Python print()
statements to go directly to the web page. A little bit later, I'll show you how to put PyScript data into HTML tags.
Figure 2 shows the running web page. This math example performs the Python SymPy simplify
function on a complex equation to reduce the equation to its simplest form. The pprint()
(pretty print) function outputs the equation into a more presentable format on the page's py-terminal
element (the black background section shown in Figure 2).
Debugging code is always an issue. The web browser will highlight some general errors in the PyScript pages. To see more detailed Python errors, right-click on the page and select the Inspect option and then click on the Console heading. Figure 3 shows a very typical error: a print()
function missing a closing quote character.
Calling PyScript Functions
In the previous example, PyScript was called just once, which is similar to how a JavaScript <script>
block is executed when it is embedded within a web page's <body>
section.
There are several ways to call a PyScript function. You can use the traditional JavaScript approach of adding a function reference within a tag reference as shown in the following button example:
<button py-click="my_pyfunc()" id="button1">Call Pyscript</button>
PyScript supports a wide range of actions. For the button, a click event is defined with the py-click
option, but other actions such as a double-click (py-dblclick
) or a mouseover (py-mouseover
) event could also be added.
Listing 1 shows a button click action that calls a function, current_time()
, to print the present time into a PyScript terminal section (Figure 4).
Listing 1
Button Click Action
<!DOCTYPE html> <html lang="en"> <head> <title>Current Time</title> <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" /> <script defer src="https://pyscript.net/latest/pyscript.js"></script> </head> <body> <h1>Py-click to call a Pyscript Function</h1> <!-- add py-click into the button tag --> <button py-click="current_time()" id="get-time" class="py-button">Get current time</button> <py-script> import datetime # this function is called from a button def current_time(): print( datetime.datetime.now()) </py-script> </body> </html>
A more Pythonic approach to calling a PyScript function is available with the @when API. The syntax for this is:
<py-script> from pyscript import when # define id and action, # then next line is the function @when("click", selector="#button1") def my_pyfunc(): print("Button 1 pressed") </py-script>
You can also use the @when
function to refresh an HTML tag, which I cover in the next section.
A Calendar Example
Now I'll provide a calendar example (Listing 2) that uses a button and PyScript to replace the contents of an HTML tag. To keep things simple, the Python's calendar output will be left as ASCII and an HTML <pre>
tag will be used (Figure 5).
Listing 2
PyScript Yearly Calendar
01 <html> 02 <head> 03 <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" /> 04 <script defer src="https://pyscript.net/latest/pyscript.js"></script> 05 <title>Pyscript Calendar Example</title> 06 </head> 07 08 <body> 09 <h1>Pyscript Calendar Example</h1> 10 Move Years: 11 <button id="btn_back"> Back </button> 12 <button id="btn_forward"> Forward </button> 13 <pre id="calzone"></pre> 14 15 <py-script> 16 from pyscript import when 17 import calendar 18 19 thisyear = 2023 20 display(calendar.calendar(thisyear), target="calzone" ) 21 22 @when("click", selector="#btn_back") 23 def back_year(): 24 global thisyear 25 thisyear -= 1 26 display(calendar.calendar(thisyear), target="calzone", append=False ) 27 28 @when("click", selector="#btn_forward") 29 def forward_year(): 30 global thisyear 31 thisyear += 1 32 display(calendar.calendar(thisyear), target="calzone", append=False ) 33 34 </py-script> 35 </body> 36 </html>
The calendar page has Back and Forward buttons (lines 10-11) and a <pre>
section (line 12).
In the <py-script>
section, the when
and calendar
libraries are imported on lines 15-17. These two libraries are part of the base PyScript/Python that is loaded into Pyodide, so a <py-config>
section is not needed.
Like calling PyScript functions, there are multiple ways to read and write web content. PyScript has a built-in display()
function that is used to write to HTML tags (lines 20, 26, and 32). The syntax for the display() function is:
display(*values, target="tag-id", append=True)
The *value can be a Python variable or an object like a Matplotlib figure.
The @when
function (lines 22 and 28) connects the Back and Forward button clicks to the functions back_year()
and forward_year()
.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.
-
VirtualBox 7.1.4 Includes Initial Support for Linux kernel 6.12
The latest version of VirtualBox has arrived and it not only adds initial support for kernel 6.12 but another feature that will make using the virtual machine tool much easier.
-
New Slimbook EVO with Raw AMD Ryzen Power
If you're looking for serious power in a 14" ultrabook that is powered by Linux, Slimbook has just the thing for you.
-
The Gnome Foundation Struggling to Stay Afloat
The foundation behind the Gnome desktop environment is having to go through some serious belt-tightening due to continued financial problems.
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.