使用 PyScript 告别后端

Python 总是能解决问题

当我还在 Read the Docs 担任开发者倡导者时,我们在与许多科学用户交谈后发现,使用 reStructuredText (reST) 编写时存在摩擦。reST 是一种功能强大的标记语言,通常出现在 Python 生态系统中;它是用于使用 Sphinx 编写文档字符串和叙述性文档的语言。但是,如今 Markdown 语言更加普及,围绕它的工具也更加发达,更方便用户使用。Read the Docs 曾经维护过一个扩展,可以在 Sphinx 中编写 CommonMark(Markdown 的标准化版本),这为许多用户提供了很好的服务。然而,在 2021 年,我们决定弃用它,转而使用 Markedly Structured Text 或 MyST,这是一种由优秀的 Executable Books 项目 创建的可扩展标记语言,它结合了 reST 的强大功能和 Markdown 的通用性。

我想尽可能多地推广 MyST,并帮助那些想要从 reST 转移的人完成过渡。为了做到这一点,我创建了 MySTyc,这是一个小型 Web 应用程序,可以实时将 reST 转换为 MyST。从字面上说,一个周末的 Hack,但非常有效!

该应用程序过去是这样工作的:对于每个按键(有一些节流;继续阅读),前端将 reST 标记发送到服务器,服务器使用 rst-to-myst 将其转换为 MyST,并将结果返回给前端以显示。这运行得很好,但有一个问题。

被撤回的垫子

MySTyc 托管在 Heroku 上,当时这是一个非常方便的选择;它提供 Python 运行时、从 GitHub 自动部署以及慷慨的免费层。但是,它也施加了一些限制。

  • Heroku 针对使用免费层的应用程序提供“进入休眠”功能,该功能会在一段时间不活动后关闭后端。因此,应用程序将消耗更少的资源,并且可以轻松地保持在免费层的限制范围内。但是,对于任何需要“唤醒”应用程序的人来说,延迟都很高(大约 10 秒)。

  • 对于每个按键都发送一个请求,这会不必要地给服务器带来压力,并影响性能。我通过在前端添加额外的 JavaScript 依赖项来 节流 转换函数来解决这个问题。

即使有了这些保障措施,也不清楚 MySTyc 是否能够在突然的流量高峰或每日使用量大幅增加的情况下保持响应或免费。但是,在我有机会弄清楚之前,Heroku 宣布结束他们的免费产品计划。这是一个信号,我需要寻找替代方案。

问题出在后端

我的第一个想法是将应用程序迁移到其他仍然提供免费层的托管服务;幸运的是,有很多 Heroku 的替代方案,并且在那个命运多舛的公告发布后,人们热切地分享推荐。但是,在将应用程序成功迁移到不同的服务后,我发现它所有主要限制仍然存在;我仍然需要节流请求,而且架构是否能够经受住“Hacker News 效应”仍然不清楚。

经过一番思考,并受到像 JupyterLite 这样的项目的成功的启发,我考虑将所有逻辑移到前端。这个想法非常有前景;无需后端来中继请求,MySTyc 本质上可以作为包含一些 JavaScript 的静态 HTML 提供服务,利用用户的计算机执行所有处理,让我无需维护托管的 Python 应用程序。这能有多难(没有人会这么问,永远不会)?

经过一番搜索,我遗憾地发现 找不到任何用 JavaScript 编写的 reStructuredText 解析器。因此,我唯一的选择是基本上用 JavaScript 重新编写 rst-to-myst,并希望一切顺利——对于一个周末的项目来说,这绝对是太大的工作量。然后我突然意识到:如果我能在浏览器中运行 Python 会怎么样?

PyScript 登场

多年来,我一直关注在浏览器中运行 Python 的各种努力;大约十年前,一位亲密的同事在 Brython 上投入了大量精力,后来我成为了 Pyodide 的粉丝(它最初是在 Mozilla 孵化,后来 转变为一个独立项目)。因此,当我看到 Anaconda 在 2022 年 PyCon US 上的 PyScript 公告 时,我感到非常兴奋!

由于该项目还很年轻,我不确定我是否能够在浏览器中运行所有必要的依赖项。但是经过一番实验,我发现 rst-to-myst 及其所有依赖项都能成功地在 Pyodide 中运行,因此可以在 PyScript 中使用!

设置过程非常简单;首先,我按照安装说明操作,并将这两行添加到我的 HTML 中

然后,我声明了 Python 依赖项和我自定义脚本的路径

最后,我将 PyScript 的文档对象模型 (DOM) 功能与我的转换代码结合起来

结果:不再需要后端,Python 逻辑在浏览器中成功运行,我可以轻松地将结果部署到 GitHub Pages。太棒了!

一些注意事项

尽管 pip 具有非常复杂的依赖项解析算法,但 micropip 却简单得多,可能会无法解决一些复杂的情况。例如,在撰写本文时,micropip 无法单独安装 rst-to-myst

在这种情况下,解决方案很简单;通过固定 ruamel-yaml 的旧版本来避免安装有问题的依赖项

最后,当前版本不正确地转换了一些保留的 HTML 字符,例如“<”、“>”等等,这会在转换后的文本中添加一些额外的反斜杠。这是一个 已知问题,希望在下一个 PyScript 版本中解决。

结论

Python 生态系统非常庞大,但仍然很大程度上局限于后端。对于某些应用程序来说,拥有后端可能会太有限制——尤其是在不需要用户身份验证或后台任务等复杂功能的情况下。Pyodide 和 PyScript 将使用 Python 进行前端编程的乐趣带给了我们,即使这些项目还处于起步阶段,它们已经为具有少量依赖项的小型应用程序提供了完美的解决方案。期待在浏览器中运行更多 Python 代码!


关于作者

Juan Luis (他/他/他) 是一位航空航天工程师,对 STEM、编程、外联和可持续发展充满热情。他在 Orchest 担任数据科学倡导者,通过构建一个开源、可扩展、易于使用的工作流编排器来赋能数据科学家。他曾在 Read the Docs 担任开发者倡导者,在航天、咨询和银行行业担任软件工程师,并为多个私人和公共实体担任 Python 培训师。

除了是科学 Python 堆栈(NumPy、SciPy、Astropy)中许多项目的长期用户和贡献者外,Juan Luis 还发布了多个开源包,其中最重要的一个是 poliastro,这是一个用于轨道力学且被学术界和工业界使用的开源 Python 库。

最后,胡安·路易斯是Python España协会的创始人兼前主席,该协会是西班牙 Python 社区的联络点,也是 PyCon Spain 的前组织者,该会议于 2022 年的最后一次线下活动吸引了 800 多名参与者,以及 PyData Madrid 每月聚会的现任组织者。

关于 Maker 博客系列

Anaconda 在每月博客系列中放大了一些最活跃和最受尊敬的社区成员的声音。如果您是一位 Maker,一直在寻找一个机会讲述您的故事、详细阐述您最喜欢的项目、教育您的同行并打造个人品牌,请考虑提交摘要。有关更多详细信息以及访问丰富的教育数据科学资源和讨论主题,请访问Anaconda Nucleus

与专家交谈

与我们的专家交谈,为您的 AI 之旅找到解决方案。

与专家交谈