PyScript is a framework that lets users create Python apps in the browser. This tutorial will teach you the basics to get you started with it.
Table of Contents
- What's PyScript
- How to Use PyScript
- How to Run Python Code in PyScript
- How to Import Libraries
- How to Interact With HTML Elements
- Other Topics
These past few days, I've been playing around with PyScript. I built an interactive cheat sheet for pandas and a cookbook of the most popular Python data visualization libraries.
I've learned a few things about how it works, so I thought of putting together these notes in case others may find them useful. This article covers the minimum you should know about PyScript to build a simple web app with it.
I deliberately left out topics that I didn't find as useful or interesting. But if you want a more detailed introduction, you should read this great tutorial from Real Python.
Let's get to it!
PyScript is a framework that lets users create Python applications in the browser. It's built on top of Pyodide, a CPython port to WebAssembly (WASM).
PyScript's main selling point is that you no longer need a server to use Python and its extensive number of libraries when building a web app. You can plug in PyScript, make a few adjustments, and use many Python libraries in your web app.
People often compare PyScript with Dash and Streamlit. But PyScript works quite differently. It operates on the client side, so no server is required. You could host a web app that uses PyScript for free using services like GitHub Pages.
Dash and Streamlit, on the other hand, require a server, making apps built with these libraries more difficult to deploy and usually more expensive. Furthermore, the server bears the majority of the computational load.
How to Use PyScript
The good thing about PyScript is that there isn't any installation required. You just need to add it to the
head of your HTML file.
I'll assume you have a file named
index.html with this content for this and the following sections:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My Awesome app!</title> </head> <body> </body> </html>
The code above is a minimal example we'll use as a starting point. Next, I'll show you how to use PyScript. You can do it in two ways:
- Download a copy of the latest version of PyScript, and add the required files to
headin your HTML document:
<head> ... <link rel="stylesheet" href="path/to/pyscript.css" /> <script defer src="path/to/pyscript.js"></script> </head>
- Add the CDN version of PyScript's JS and CSS files to
headin your HTML document:
<head> ... <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" /> <script defer src="https://pyscript.net/latest/pyscript.js"></script> </head>
PyScript is still under heavy development. If you use the second method, your app may break when new versions are released.
To test your changes locally, use Live Server if you like working with VS Code or try any of these methods if you prefer other code editors.
How to Run Python Code in PyScript
There are two ways to run Python code in PyScript: using
py-repl tags. These elements inside go inside
body in your HTML document.
You can run code using the
py-script tag in two ways:
- Wrap your code with a
<body> ... <py-script>print("Hello, world!")</py-script> ... </body>
- Load an external script using the
srcattribute from the
<body> ... <py-script src='path/to/script.py'></pyscript> ... </body>
The latter is usually preferred to avoid having formatting issues. If you use an HTML auto-formatter, it may break the python code you put inside
You can also run code using an interactive interpreter, usually known as read–eval–print loop (REPL). Using a REPL makes it feel like you're running code in a Jupyter notebook.
You can create a REPL with PyScript using the
py-repl tag as follows:
<body> <py-repl>print("Hello, world!")</py-repl> </body>
If you try using multiple
py-repl in the same page, you may find some unexpected behavior in the output. I came across two issues related to this but it looks like they'll get fixed soon.
How to Import Libraries
You can make Python libraries available in your environment when your app loads by specifying them in the
py-env tag as follows:
<head> ... <py-env> - numpy - pandas - seaborn </py-env> </head>
Or you can load them programmatically using
<py-script> async def main(): await micropip.install(["numpy", "pandas", "seaborn]) await loop.run_until_complete(main()) </py-script>
How to Interact With HTML Elements
document, let you read and make changes to elements from the Document Object Model (DOM). While
console lets you interact with your browser's integrated console.
For example, you could use
document to select a specific element from the DOM:
<body> ... <py-script> # Select an element using its ID document.getElementById("input-code") # Select an element using its class document.querySelector(".table") </py-script> ... </body>
document to read attributes from elements and make changes to them, and print information using
<body> <ul id="users-list"> <li>Dylan</li> <li>John</li> <li>Paul</li> <li>Jane</li> </ul> <py-script> users = ["Dylan", "John", "Jane"] ul = document.querySelectorAll("ul > li") for li in ul: if li.innerHTML not in users: console.log(li.innerHTML) li.remove() </py-script> </body>
You could also make your Python code react to changes in the DOM. But that requires some magic to work because the web browser cannot natively handle Python functions when an event such as a click on a button happens.
create_proxy to make your Python code react to changes as follows:
<body> <input type="text" name="" id="input-text"> <button type="submit" id="button-submit" for="input-text">Submit!</button> <div id="text-length"></div> <py-script> from pyodide import create_proxy input_button = document.getElementById("button-submit") def get_text_length(x): document.getElementById("text-length").innerHTML = len(document.getElementById("input-text").value) input_button.addEventListener("click", create_proxy(get_text_length)) </py-script> </body>
The code lets the user input a text and run the
get_text_length Python function, after he or she clicks on the button on the screen. This function calculates the length of the text that the user entered.
Finally, it's worth mentioning that PyScript also provides you with the
Element class. It's a basic interface that lets you select elements by ID and do certain operations on them. I found it a bit limited, which is why I didn't cover it in this section.
There are many topics I didn't cover in this article. So I wanted to provide some resources additional resources I've found useful:
- PyScript visual components: PyScript provides a few elements you can use to build the UI of your web app. The Real Python tutorial covers them.
- Accessing the file system: Accessing files is a bit tricky. John Hanley made very detailed tutorials about this topic.
- PyScript and plotly: Getting plotly graphs to work with PyScript is tricky. This article explains how to do it.
- Hosting PyScript: If you don't need to store data from your users in a server, you can simply host a static page. The easiest way to do that is using GitHub Pages. That's what I've used in my projects.
PyScript is an experimental Python framework that lets you run Python on the web browser. This article covers the basics of PyScript, and will show you how to:
- Use PyScript on a web page
- Run Python code using PyScript
- Interact with the DOM using PyScript
If you have any questions or feedback, let me know in the comments!