Introduction
Setting up Python event handlers in Pyscript requires special handling. Pyodide provides a proxy so that DOM events can use Python functions as callbacks.
To create a proxy, call the pyodide.create_proxy()
function [link].
1 2 3 4 |
from pyodide import create_proxy # Create a Python proxy for the callback function function_proxy = create_proxy(myFunction) |
The Python function myFunction
is a normal Python function that will be called on an event.
1 2 3 |
def myFunction(): # do something here pass |
To assign the proxy function to a listener:
1 2 |
# Set the listener to the callback document.getElementById("button").addEventListener("click", function_proxy) |
Pyscript Examples
Here is a complete example that increments a counter for each button press. You can see this example on my website.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<!DOCTYPE html> <html> <head> <title>Button Event Proxy</title> <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" /> <script defer src="https://pyscript.net/alpha/pyscript.js"></script> <style> .button { background-color: #4CAF50; /* Green */ border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; } </style> </head> <body> <p>This example shows how to process a button event</p> <br /> <div id="msg">Loading page, please wait ...</div> <br /> <button class="button" type="button" id="button">Click Me</button> <br /> <br /> <div id="msg"> <py-script> from js import document from pyodide import create_proxy count = 0 def button_click(event): global count count += 1 document.getElementById("msg").innerHTML = 'Button Clicked ' + str(count) def setup(): # The page is ready, clear the "page loading" document.getElementById("msg").innerHTML = '' # Create a JsProxy for the callback function click_proxy = create_proxy(button_click) # Set the listener to the callback e = document.getElementById("button") e.addEventListener("click", click_proxy) setup() </py-script> </body> </html> |
Time-Based Callbacks
Python developers typically write procedural code. When designing for the browser, you want to be careful to not lock up the user interface. A web browser provides one thread for a web application. To use more threads, you must use Web Workers. There are times that you want to perform tasks on a schedule, for example, updating a stock quote, refreshing page content, etc. Browsers provide the API setInterval()
[link] to callback to your application at a fixed interval.
This example sets up a callback every 1,000 ms and updates the browser page with a counter. Once the counter reaches 15, the interval callback is canceled.
Notice that the same call to create_proxy()
is used.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<body> <div id="status">Loading page ...</div> <br> <div id="msg"></div> <br> <py-script> import js from js import document from pyodide import create_proxy counter = 0 document.getElementById("status").innerHTML = 'Python loaded and running ...' def myFunc(param): global counter, interval_id counter += 1 document.getElementById("msg").innerHTML = "Counter = " + str(counter) # Stop the Interval timer at 15 if counter == 15: document.getElementById("status").innerHTML = 'Interval timer stopped' js.clearInterval(interval_id) # Create a proxy for the callback proxy = create_proxy(myFunc) # Start an Interval timer for every 1,000 ms interval_id = js.setInterval(proxy, 1000, "a parameter"); </py-script> </body> |
Summary
Interfacing with HTML and JavaScript is fairly easy to do. Pyscript and Pyodide have created very nice libraries and interfaces for Python development in the browser.
More Information
- Other articles that I have written on Pyscript
- MDN – Event Reference
- MDN – EventTarget.addEventListener()
- MDN: setInterval()
- MDN: clearInterval()
- Pyodide Python API
Photography Credit
I write free articles about technology. Recently, I learned about Pexels.com which provides free images. The image in this article is courtesy of Tina Nord at Pexels.
I design software for enterprise-class systems and data centers. My background is 30+ years in storage (SCSI, FC, iSCSI, disk arrays, imaging) virtualization. 20+ years in identity, security, and forensics.
For the past 14+ years, I have been working in the cloud (AWS, Azure, Google, Alibaba, IBM, Oracle) designing hybrid and multi-cloud software solutions. I am an MVP/GDE with several.
1 Pingback