PyConUS2022公布的PyScript可以在浏览器执行Python代码,依赖于pyodide(WebAssembly的CPython)。相比pyodide更接近Web的开发体验。公布的 alpha 版本输出 Python 版本信息是: 3.10.2 (main, Apr 9 2022, 20:52:01) [Clang 14.0.0 (https://github.com/llvm/llvm-project 78e87970af888bbbd5652c31f3a8
下载项目源码,执行 npm run dev
运行的官方 demo 主要针对数据处理和 REPL,本文整理 Web 开发常见的几个代码片段:获取数据,读取本地数据库,事件绑定。
Install
只需要增加HTML标签引入文件:
但会从 cdn.jsdelivr.net 请求 pyodide.asm 相关文件。去年年底开始国内的jsdelivr访问时断时续,整个依赖有22MB,需要先设置好网络。
Usage
在HTML中使用<py-script>标签嵌入Python代码。和<script>标签一样,支持 src 属性直接引入 .py 文件。以Web开发很常用的两个场景,网络请求和访问数据库为例:
网络请求
这一版的pyscript还不能直接用Python库发起Web请求,如果调用 http.client 会报错:
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
即使用 asyncio 处理,也默认是浏览器发起 WebSocket 连接。
可以调用 pyodide.http.open_url 或使用 Javascript 的 fetch 从接口获取数据并在页面显示的代码:
Key | Value |
---|
访问数据库
pyodide支持的 Python 包列表: https://github.com/pyodide/pyodide/tree/main/packages
已经支持 Sqlalchemy 这个主要的 ORM 包。因为缺少依赖且浏览器有限制,还不能连接远程数据库,但可以使用 Sqlite 的 inmemory 模式,代码如下:
- sqlalchemy # 其他包使用 引入 from sqlalchemy import create_engine, text engine = create_engine("sqlite+pysqlite:///:memory:", future=True) # Sqlite 连接 with engine.connect() as conn: conn.execute(text("CREATE TABLE sites (name string, domain string)")) # 建表,写数据,提交 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(): # 遍历结果。之前已经写过 DOM 的处理,这里直接 print print("Site: {}, Domain: {}".format(row[0], row[1]))
事件绑定
PyScript 使用 pys-{EVENT} 属性在 HTML 标签上绑定事件,例如点击按钮获取时间戳:
import time def get_time(*args, **kwargs): Element("current-time").write(time.time())
Afterwords
WebAssembly也发展近十年了,“让浏览器运行C/C++代码”听起来如同 nodejs 一样的新颖,然而只有一些简单的游戏演示,在 Web 应用方面让人眼前一亮的项目并不多。前几年接触iodide和pyodide的时候,也只觉得和 Jupyterhub 比较像,没想到合适的用途。
这次再看到 PyScript ,似乎只是 pyodide 加了几个 HTML 标签,但用起来顺手很多。第一印象是 PHP/JSP 曾经的混合写法,实际上手就发现它已经推进了 WebAssembly 的目标:让 C(Python)/C++ 成为真正能直接被浏览器解析,简单易上手的语言。虽然受限于网速、浏览器性能等因素,还替代不了 Javascript,但对于一些特定领域尤其是 Python 擅长的数据处理/机器学习,PyScript 应该能从 Javascript 分走一些。而且 Python 工程师们,以后就是名副其实的 Web 全栈了。