Using Python in the browser

Snake Charmer

© Photo by Godwin Angeline Benjo on Unsplash

© Photo by Godwin Angeline Benjo on Unsplash

Article from Issue 278/2024
Author(s):

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.
Figure 1: The main components of a PyScript web page.

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).

Figure 2: PyScript using the Python SymPy library.

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.

Figure 3: Debug PyScript with the browser's Inspect option.

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>
Figure 4: Button click to call a PyScript function.

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>
Figure 5: PyScript calendar with @when functions.

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

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Analytics with Python and KDD

    The Knowledge Discovery in Data Mining (KDD) method breaks the business of data analytics into easy-to-understand steps. We'll show you how to get started with KDD and Python.

  • Practical Python in Linux

    We’ll introduce you to Python, an easy-to-learn scripting language, and also help you get started creating your own practical Python scripts.

  • Workspace: Pi-Based Backup

    With some creativity and a little scripting, you can easily turn your Raspberry Pi into an effective backup device.

  • Gimp Scripting

    Many users turn to GIMP for pictures in the window, but some may not realize GIMP also has scripting capabilities that allow you to automate recurring tasks. The Python scripting language is a useful alternative to the GIMP’s integrated Lisp dialect.

  • Probability Party

    At a party with 23 guests, having two guests with the same birthday in more than 50 percent of cases may sound fairly unlikely to amateur mathematicians. Armed with statistical methods, party animal Mike Schilli sets out to prove this claim.

comments powered by Disqus
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.

Learn More

News