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
-
AlmaLinux 10.0 Beta Released
The AlmaLinux OS Foundation has announced the availability of AlmaLinux 10.0 Beta ("Purple Lion") for all supported devices with significant changes.
-
Gnome 47.2 Now Available
Gnome 47.2 is now available for general use but don't expect much in the way of newness, as this is all about improvements and bug fixes.
-
Latest Cinnamon Desktop Releases with a Bold New Look
Just in time for the holidays, the developer of the Cinnamon desktop has shipped a new release to help spice up your eggnog with new features and a new look.
-
Armbian 24.11 Released with Expanded Hardware Support
If you've been waiting for Armbian to support OrangePi 5 Max and Radxa ROCK 5B+, the wait is over.
-
SUSE Renames Several Products for Better Name Recognition
SUSE has been a very powerful player in the European market, but it knows it must branch out to gain serious traction. Will a name change do the trick?
-
ESET Discovers New Linux Malware
WolfsBane is an all-in-one malware that has hit the Linux operating system and includes a dropper, a launcher, and a backdoor.
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.