Uncategorized

PyScript (alpha version) code demo

PyConUS2022 announced PyScript to execute Python code in the browser, relying on pyodide (CPython for WebAssembly). It is much closer to the web development experience than pyodide. The published alpha version output Python version information is: 3.10.2 (main, Apr 9 2022, 20:52:01) [Clang 14.0.0 (https://github.com/llvm/llvm-project 78e87970af888bbbd5652c31f3a8

Install

Just add HTML tags to load the files:


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

But it will request pyodide.asm related files from cdn.jsdelivr.net. The entire dependency has 22MB, requiring a good network setup first.

Usage

Embed Python code in HTML using the <py-script> tag. Take two scenarios very commonly used in web development: fetch data from api and query data from database.

Fetch data

This version of pyscript cannot yet initiate web requests directly with the Python library, and calls to http.client will report the following error:

  File "/lib/python3.10/http/client.py", line 941, in connect
    self.sock = self._create_connection(
  File "/lib/python3.10/socket.py", line 845, in create_connection
    raise err
  File "/lib/python3.10/socket.py", line 833, in create_connection
    sock.connect(sa)
BlockingIOError: [Errno 26] Operation in progress

Even call asyncio to do the processing, the browser initiates the WebSocket connection by default. Call pyodide.http.open_url to get the data or use Javascript’s fetch to get the data from the interface and display it on the page with the following code.

 
<table class="table">
  <thead>
    <tr>
      <th>Key</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody id="table-data-rows">
  <tbody>
</table>

    <py-script>
import asyncio
from pyodide.http import open_url
import json

from js import fetch, document

async def request_github_api():
    url = "https://api.github.com/"
    r = await fetch(url)
    data = await r.json()
    # data = json.loads(open_url(url).read()) # open_url

    rows = document.getElementById("table-data-rows") # The handling of loop bodies is all Javascript syntax
    for k, v in data.object_entries():
    # for k, v in data.items(): # open_url return dict
        tr = document.createElement('tr') 
        key_td, value_td = document.createElement('td'), document.createElement('td')
        key_td.innerHTML = k
        value_td.innerHTML = v
        tr.append(key_td, value_td)
        rows.appendChild(tr)
asyncio.ensure_future(request_github_api())
    </py-script>

Accessing the database

List of Python packages supported by pyodide: https://github.com/pyodide/pyodide/tree/main/packages

Sqlalchemy, the main ORM package, is already supported. But can’t connect to remote databases yet because of missing dependencies and browser limitations, use Sqlite’s inmemory mode with the following code.


    <py-env>
      - sqlalchemy # 其他包使用 <py-env> 引入
    </py-env>
    <py-script>
from sqlalchemy import create_engine, text

engine = create_engine("sqlite+pysqlite:///:memory:", future=True) # Sqlite Connection
with engine.connect() as conn:
    conn.execute(text("CREATE TABLE sites (name string, domain string)")) # Create table, insert data and commit
    conn.execute(
            text("INSERT INTO sites (name, domain) VALUES (:name, :domain)"),
            [{"name": "Dmyz1", "domain": "http://dmyz.org"}, {"name": "Dmyz2", "domain": "http://dmyz.net"}],
        )
    conn.commit()

    result = conn.execute(text("SELECT * FROM sites"))
    for row in result.all(): # Iterate results and directly print
        print("Site: {}, Domain: {}".format(row[0], row[1]))

    </py-script>

REPL

Afterwords

WebAssembly has been developed for nearly a decade, and “let the browser run C/C++ code” sounds as novel as nodejs, but there are only some simple demos. When I came across iodide and pyodide a few years ago, I only thought they were similar to Jupyterhub, but I didn’t think they were suitable for that purpose.

PyScript seemed to be just pyodide with a few HTML tags, but it was much smoother to use. My first impression was that it was a hybrid of PHP/JSP, and then I realized that it advanced the goal of WebAssembly: to make C(Python)/C++ a real language that can be directly parsed by browsers and is easy to use. Although limited by Internet speed, browser performance and other factors, can not replace Javascript, but for some specific areas, especially Python is good at data processing / machine learning, PyScript should be able to take away some from Javascript. And Python engineers, the future is a veritable Web full-stack.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments