> ## Content Index
> Fetch the complete content index at: https://sudosecurity.org/llms.txt
> Use this file to discover other available public pages before exploring further.

# PyScript: Running Python in the Web Browser
- URL: https://sudosecurity.org/run-python-in-the-web-browser/
- Published: 2022-06-16T23:36:11.000Z
- Updated: 2026-11-11T03:34:34.000Z
- Description: PyScript, created by Anaconda, is an experimental but promising new technology that makes the Python runtime available as a scripting language in WebAssembly-enabled browsers. Every modern, commonly used browser now supports WebAssembly, the high-speed runtime standard that many languages (like…
- Author: Traven
- Tags: Python, Web Applications, #coderoasis-archive, Web Development, Programming, Software Development

# PyScript: Running Python in the Web Browser

[Web Development](https://sudosecurity.org/tag/web-development/) • Jun 16, 2022[](https://www.facebook.com/sharer/sharer.php?u=https://coderoasis.com/run-python-in-the-web-browser/)[](https://twitter.com/intent/tweet?text=PyScript%3A%20Running%20Python%20in%20the%20Web%20Browser&url=https://coderoasis.com/run-python-in-the-web-browser/&ref=sudosecurity.org)

PyScript, created by Anaconda, is an experimental but promising new technology that makes the Python runtime available as a scripting language in WebAssembly-enabled browsers.

Every modern, commonly used browser now supports WebAssembly, the high-speed runtime standard that many languages (like C, C++, and Rust) can compile to. Python's reference implementation is written in C, and one earlier project, [Pyodide](https://pyodide.org/en/stable/?ref=sudosecurity.org), provided a WebAssembly port of the Python runtime.

PyScript, though, aims to provide a whole in-browser environment for running Python as a web scripting language. It builds on top of Pyodide but adds or enhances features like the ability to import modules from the standard library, use third-party imports, configure two-way interactions with the Document Object Model (DOM), and do many other things useful in both the Python and JavaScript worlds.

Right now, PyScript is still a prototypical and experimental project. Anaconda doesn't recommend using it in production. But curious users can try out examples on the PyScript site and use the available components to build experimental Python-plus-JavaScript applications in the browser.

## Programming with PyScript

At its core, PyScript consists of a single JavaScript include that you can add to a web page. This include loads the base PyScript runtime and automatically adds support for custom tags used in PyScript.

Here is a simple example of a "hello, world" project in PyScript:

```html
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
        <script defer src="https://pyscript.net/unstable/pyscript.js"></script>
    </head>
    <body>

<py-script output="out">
print("Hello world")
</py-script>

<div id="out"></div>

    </body>

</html>
```

The `script` tag in the document's `head` loads the core PyScript functionality. The `pyscript.css` stylesheet is optional, but useful. Among other things, it inserts notices to the user at the page's load time about what the page is doing—loading the Python runtime, initializing, and so on.

Python code is enclosed in the custom `py-script` tag. Note that the code should be formatted according to Python's conventions for indentation, or it won't run properly. Be aware of this if you use an editor that reformats HTML automatically; it might mangle the contents of the `py-script` block and make it unrunnable.

Any Python code is evaluated once the PyScript components finish loading. If the script in the tags writes to `stdout` (as with a `print`) statement, you can direct where on the page to show the output by supplying an `output` property. In this example, `stdout` for the script gets directed into the `div` with the ID `"out"`.

If you save this into a file and open it in a web browser, you'll first see a "loading" indicator and a pause, as the browser obtains the PyScript runtime and sets it up. The runtime should remain cached on future loads but will still take a moment to activate. After that, `Hello world` should appear on the page.

## Using libraries from PyPI

What if we want to install a package from PyPI and use that? PyScript has another tag, `py-env`, that specifies third-party packages need to be installed. Let's replace the `py-script` block in the original script with these two blocks:

```
<py-env>
- humanize
</py-env>

<py-script output="out">
from datetime import datetime
import humanize
now_int = int(datetime.timestamp(datetime.now()))
now_fmt = humanize.intcomma(now_int)
print("It has been", now_fmt, "seconds since the epoch.")
</py-script>
```

The `py-env` block lets us list packages to add, in the same way we might list them in a `requirements.txt` file for a Python project. We can then import and use them as we would any other Python package. In this example, we're using a third-party package called `humanize` to make numerical output easier to read.

Note that not all packages from PyPI will install and run as expected. For instance, `requests` requires access to networking components that aren't yet supported. (A possible workaround for this issue is to use `pyodide.http.pyfetch`, which is [supported natively](https://community.anaconda.cloud/t/pyfetch-example/20316?ref=sudosecurity.org).) But pure Python packages, like `humanize`, should run fine. And packages used in the examples provided by Anaconda, like `numpy`, `pandas`, `bokeh`, or `matplotlib`, will also work.

## Interacting with JavaScript event listeners

Because PyScript is based on `pyodide`, it uses `pyodide`'s mechanisms for interacting with the DOM. For instance, if we wanted to get the value of an input box on a web page and use it in our Python code, we'd do this:

```
<input id="txt">

<py-script>
from js import document, console
from pyodide import create_proxy

def _eventlog(e):
    console.log(f"Input value: {e.target.value}")

eventlog = create_proxy(_eventlog)

document.getElementById("txt").addEventListener("input", eventlog)
</py-script>
```

The `js` library provides a Python interface to many common JavaScript entities, like the `document` and `console` objects. They behave almost exactly the same way in PyScript as they do in JavaScript. The `create_proxy` function in `pyodide` lets us take a Python function object and generate a JavaScript interface for it, so it can be used as the event listener for the `input` box. Any keystrokes in the `input` box are logged to the console, but they can also be handled on the Python side.

## Importing locally

For another common scenario, let's say you want to import from other Python scripts in the same directory tree as your web page. Using imports makes it easier to move more of your Python logic out of the web page itself, where it's intermixed with your presentation and may become difficult to work with.

Normally, Python uses the presence of other `.py` files in the file system as indications of what it can import. PyScript can't work this way, so you'll need to specify which files you want to make available as importable modules.

Let's say you have a web page named `index.html` in a given directory on your web server, and you want to place a Python file named `main.py` next to it. This way your in-page script can be just `import main`, and you can confine the majority of the Python logic to the actual `.py` files.

Specify the Python files you want to make importable in your `py-env` block:

`- paths:  
 - ./main.py`

This would allow `main.py`, in the same web server directory as the web page itself, to be importable with `import main`.

An important thing to keep in mind: You can't perform imports like this on a web page you've launched *locally* in the browser. This is due to restrictions on file system access imposed by the WebAssembly runtime and the browser itself. Instead, you'd need to host the pages on a web server to serve the web page and the `.py` file.

## Standard library imports

Scripts using Python's builtins alone are only somewhat useful. Python's standard library is available in PyScript the same way you'd use it in regular Python: simply `import` and get to work. Standard library imports should just work in PyScript.

If you wanted to modify the above script block to display the current time, you wouldn't need to do it any differently than you would in conventional Python:

```
import datetime
print ("Current date and time:",    datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
```

### Tags

- [Web Development](https://sudosecurity.org/tag/web-development/)
- [Software Development](https://sudosecurity.org/tag/software-development/)
- [Python](https://sudosecurity.org/tag/python/)
- [WebAssembly](https://sudosecurity.org/tag/webassembly/)
- [Application Development](https://sudosecurity.org/tag/application-development/)
- [Web Applications](https://sudosecurity.org/tag/web-applications/)