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
-
Thousands of Linux Servers Infected with Stealth Malware Since 2021
Perfctl is capable of remaining undetected, which makes it dangerous and hard to mitigate.
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.