使用 PyScript 实现无后端

Python 总是能解决问题

当我在 Read the Docs 担任开发者倡导者时,与许多科学用户交流后,我们观察到的主要主题之一是在编写 reStructuredText (reST) 时遇到的摩擦。reST 是一种功能强大的标记语言,在 Python 生态系统中很常见;您可以使用它来编写文档字符串和使用 Sphinx 的叙述性文档。然而,如今 Markdown 是一种更为普遍的语言,围绕它的工具也更加完善和用户友好。Read the Docs 曾经维护一个扩展,用于在 Sphinx 内部编写 CommonMark(Markdown 的标准化版本),这为许多用户提供了良好的服务。然而,在 2021 年,我们决定弃用它,转而支持 Markedly Structured Text 或 MyST,这是一种由出色的 Executable Books Project 创建的可扩展标记语言,它结合了 reST 的强大功能和 Markdown 的通用性。

我想尽可能地推广 MyST,并帮助那些想要摆脱 reST 的人进行过渡,为此我创建了 MySTyc,这是一个小型 Web 应用程序,可以即时将 reST 转换为 MyST。真的是 一个周末的黑客项目,但非常有效!

该应用程序过去的工作方式如下:对于每次击键(带有一些节流;请继续阅读),前端将 reST 标记发送到服务器,服务器使用 rst-to-myst 将其转换为 MyST,并将结果返回到前端以显示。这工作得非常好,但有一个问题。

被抽走的垫子

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

  • Heroku 对使用免费套餐的应用程序具有“进入休眠”功能,该功能会在一段时间不活动后关闭后端。因此,应用程序将消耗更少的资源,并轻松保持在免费套餐的限制范围内。然而,对于任何必须“唤醒”应用程序的人来说,延迟非常高(大约 10 秒)。

  • 为每次击键发送请求不必要地冲击了服务器并损害了性能。我在前端通过使用额外的 JavaScript 依赖 节流 转换功能解决了这个问题。

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

问题出在后端

我的第一个想法是将应用程序迁移到仍然提供免费套餐的其他托管服务;幸运的是,Heroku 有许多替代方案,人们也急于在灾难性公告发布后分享建议。然而,在成功将应用程序迁移到不同的服务后,我发现其所有主要限制仍然存在;我仍然需要节流请求,并且架构是否能承受“Hacker News 效应”仍然不清楚。

在经过更多思考,并受到 JupyterLite 等项目的成功启发后,我考虑将所有逻辑转移到前端。这个想法非常有前景;在没有后端必须中继请求的情况下,MySTyc 本质上可以作为静态 HTML 和一些 JavaScript 提供服务,利用用户的计算机执行所有处理,并使我无需维护托管的 Python 应用程序。这有多难呢(没人说过,永远不会)?

经过一番浏览,我遗憾地 找不到任何用 JavaScript 编写的 reStructuredText 解析器。因此,我唯一的选择基本上是用 JavaScript 重写 rst-to-myst 并寄希望于最好的结果——对于一个周末项目来说,这绝对是太多的工作了。然后我突然想到:如果我可以在浏览器中运行 Python 呢

PyScript 登场

多年来,我一直关注在浏览器中运行 Python 的不同努力;大约十年前,一位亲密的同事在 Brython 上投入了大量精力,后来我成为了 Pyodide 的粉丝(最初在 Mozilla 孵化,然后 过渡到一个独立项目)。因此,当我看到 Anaconda 在 PyCon US 2022 上 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 (他/他/él) 是一位航空航天工程师,对 STEM、编程、推广和可持续性充满热情。他在 Orchest 担任数据科学家倡导者,在那里他通过构建开源、可扩展、易于使用的工作流编排器来增强数据科学家的能力。他曾在 Read the Docs 担任开发者倡导者,在航天、咨询和银行行业担任软件工程师,并为多家私营和公共实体担任 Python 培训师。

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

最后,Juan Luis 是 Python España 协会的创始人和前任主席,该协会是西班牙 Python 社区的联络点,也是 PyCon Spain 的前组织者,PyCon Spain 在 2022 年的上一届线下活动中吸引了 800 多名与会者,并且是 PyData Madrid 月度聚会的现任组织者。

关于 Maker 博客系列

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

与专家交流

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

与专家交流