To the moon and back

Python on the web

Filipe Fernandes

Dec 08, 2022

Before we start

What are our needs?

  • We need a fast serveless solution.
  • With the basic scientific packages (numpy, scipy, pandas, matplotlib),
  • and at least some met/ocean specific packages like: netCDF4 (netcdf-c, hdf5), geopandas (geos), cartopy (proj), cftime (cython extension), cf_units (udunits2), etc.

Please keep this in mind as we navigate this presentation.

Bit of history

Python on the web is not a new idea. There were many, attempts with different degrees of success, in the past years.

Running on a server

https://www.pythonanywhere.com/

Running on a server

https://streamlit.io

Cloud plans

https://discuss.streamlit.io/t/what-happened-to-streamlit-cloud-plans/24894

Running on a server

https://htmx.org

HTMX Project

https://github.com/renceInbox/fastapi-todo

Transpilation

https://www.transcrypt.org

Transcrypt

In-browser re-implementation (failed live demos)

Brython

Skulpt

Can we do better than transpiling to/or reimplementing in JS?

Wasm is the closest we ever got to a universal binary.

(Maybe) some successful live demos

pypyjs

Pyodide

Why is Pyodide a good option?

  • Based on Emscripten
  • Heavy download but fast execution
  • Full CPython + scientific distribution
  • Pure Python packages are installable
  • Compiled packages can be added

What else is missing?

We need to be able to:

  • Easily deploy Apps as HTML without compiling or downloading you own Pyodide
  • Control the installed packages
  • Choose the pyodide version
  • Access to the DOM and some JS ↔︎ Python exchange
  • Some pre-built “web comfort” functions

Enter PyScript

https://pyscript.net

  • Builds on top of and manages pyodide
  • No installation required
  • Environment management

pyscript

How to use it?

<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>

and a pyscript tag,

<py-script> print('Hello, World!') </py-script>

What is the difference between PyScript and Pyodide?

Flexible config: control pyodide version

<py-config>
  [[runtimes]]
  src = "https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js"
  name = "pyodide-0.21.3"
  lang = "python"
</py-config>

Flexible config: modules and even local wheels

<py-config src="./custom.toml">
  [[fetch]]
  files = ["./utils.py"]
  packages = [
      "numpy",
      "matplotlib",
      "./static/wheels/mypackage-0.1.3-py3-none-any.whl"
    ]
</py-config>

PyScript: Labeled elements

    <b><p>Today is <u><label id='today'></label></u></p></b>
    <br>
    <div id="pi" class="alert alert-primary"></div>
    <py-script>
      import datetime as dt
      pyscript.write('today', dt.date.today().strftime('%A %B %d, %Y'))

      def compute_pi(n):
          pi = 2
          for i in range(1,n):
              pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
          return pi

      pi = compute_pi(100000)
      pyscript.write('pi', f'pi is approximately {pi:.3f}')
    </py-script>

pi

Many built-in functionalities

But… Before we dive into that…

Still under heavy-development

Some of the built-in functionalities

<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<div id="display-write"></div>
<button py-click="display_to_div()" id="display">Say Things!</button>
<button py-click="print_to_page()" id="print">Print Things!</button>

click

JavaScript to PyScript

<script>
    name = "Guido" //A JS variable

    // Define a JS Function
    function addTwoNumbers(x, y){
        return x + y;
    }
</script>
<py-script>
    # Import and use JS function and variable into Python
    from js import name, addTwoNumbers

    print(f"Hello {name}")
    print("Adding 1 and 2 in Javascript: " + str(addTwoNumbers(1, 2)))
</py-script>

PyScript to JavaScript

<body>
    <py-script>x = 42</py-script>

    <button onclick="showX()">Click Me to Get 'x' from Python</button>
    <script>
        function showX(){
            console.log(`In Python right now, x = ${PyScript.globals.get('x')}`)
        }
    </script>
</body>

display

What can our community do with this?

glider of the day

ioos_qc explorer

ioos_qc csv uploader

What if we cannot access the web?

https://github.com/ocean-data-qc/ocean-data-qc

Summary

  • Python in the browser: Enable drop-in content, external file hosting, and application hosting without the reliance on server-side configuration (no subscriptions, no remote downtime, no data is exchanged)
  • Python ecosystem: Run many popular packages of Python and the scientific stack (such as numpy, pandas, scikit-learn, and more)

Summary

  • Python with JavaScript: Bi-directional communication between Python and Javascript objects and namespaces
  • Environment management: Allow users to define what packages and files to include for the page code to run
  • Ship your app zero dependencies: Easy upgrades for legacy systems
  • Visual application development: Use readily available curated UI components, such as buttons, containers, text boxes, and more

Questions?