关于 HMR Docs
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://pyth-on-line.promplate.dev/hmr/mcpclaude mcp add --transport http hmr https://pyth-on-line.promplate.dev/hmr/mcp{"mcpServers":{"hmr":{"type":"http","url":"https://pyth-on-line.promplate.dev/hmr/mcp"}}}在 Cursor 中打开{"servers":{"hmr":{"type":"http","url":"https://pyth-on-line.promplate.dev/hmr/mcp"}}}在 VS Code 中打开{"mcpServers":{"hmr":{"type":"http","url":"https://pyth-on-line.promplate.dev/hmr/mcp"}}}{"mcpServers":{"hmr":{"serverUrl":"https://pyth-on-line.promplate.dev/hmr/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
3此工具无需参数。
详细介绍
Python 的 HMR
HMR 提供了一种 Pythonic、灵活、渐进且直观的响应式编程 引擎 / 框架,并在此基础上提供了一个细粒度、按需热重载 工具。
在 Python 中,HMR 代表 Hot Module Reload,不过在 JavaScript 中,它通常指 Hot Module Replacement——本质上是同一个概念。它是一项功能,可在运行时更新应用的部分内容,而无需完整重新运行或重启整个进程。
与传统的 Python 重载器(例如 watchfiles CLI、uvicorn --reload 或 Flask 的调试模式)不同,HMR 的效率和可靠性要高得多。这些工具通常会在文件发生变化时重启整个进程,十分浪费。HMR 则会智能地只重新运行必要的部分,同时保留应用状态。
https://github.com/user-attachments/assets/f9ac6302-44dc-4a6d-86ae-f299fae7be80
假设你正在使用 FastAPI 开发一项机器学习服务,其中的模型需要 5 秒才能初始化。使用 uvicorn --reload 时,任何更改——即使只是更新一条简单的文档字符串——都会触发整个进程重启,让你每次都得等待 5 秒。这就像每个路口都遇到红灯一样令人沮丧。
HMR 带来更顺畅的体验。更改会即时生效,因为 HMR 具有变量级细粒度:你的代码库会像依赖关系图一样运作——修改文件时,HMR 只会从被修改的模块开始,重新运行受影响的模块,直到入口文件。如果你更新的变量没有任何依赖项,就不会发生任何事。
注意
这个包不是什么?
不要将
hmr与客户端热重载混淆,后者会在服务端代码更改时更新浏览器内容。此包实现的是服务端 HMR,只会在 Python 代码发生更改时重新加载代码。
用法
体验 HMR 最快的方式是使用 CLI:
pip install hmr
hmr path/to/your/entry-file.py
参数的用法与 python 命令完全相同,只是文件现在会在更改时热重载。尝试保存文件,即可查看即时更新,同时不会丢失状态。
如果你已安装 uv,可以直接通过以下命令试用 hmr:
uvx hmr path/to/your/entry-file.py
生态系统
HMR 为不同的 Python 开发场景提供了丰富的工具生态:
| Package | Use Case |
|---|---|
hmr | 响应式编程库和 HMR 核心实现 |
uvicorn-hmr | 支持 HMR 的 Uvicorn 服务,适用于 ASGI 应用(FastAPI、Starlette 等) |
mcp-hmr | 支持 HMR 的 MCP / FastMCP 服务 |
hmr-daemon | 后台守护进程,可在模块发生更改时刷新模块 |
fastapi-reloader | 浏览器自动刷新中间件,可自动重新加载页面 |
提示
hmr 生态系统基本已稳定,可用于大多数生产场景。它经过精心设计,能够处理许多常见边缘情况和 Python 风格的 魔法 模式,包括延迟导入、动态导入、模块级
__getattr__、装饰器等。不过,在某些边缘情况下,循环依赖仍可能导致意外行为。如果__init__.py中有大量代码,请谨慎使用。
https://github.com/user-attachments/assets/fb247649-193d-4eed-b778-05b02d47c3f6
其他演示
demo/- 带热模块重载功能的基础脚本fastapi/- 支持热重载和浏览器刷新的 FastAPI 服务flask/- 带热模块重载功能的 Flask 应用mcp/- 可实时更新代码且不会断开连接的 MCP 服务
动机
HMR 已经是前端领域的常见功能。像 Vite 这样的 Web 框架支持将更改同步到浏览器,而无需完整刷新页面。像 Vitest 这样的测试框架支持按需更新测试结果,而无需完整重新运行。
那么,为什么不把这项魔法带到 Python 中呢?
工作原理
HMR 使用运行时依赖跟踪而不是静态分析,以实现细粒度响应式:
- 信号与观察者模式:Signal 是观察者模式的一种替代方案。我实现了一个简单的信号系统,用于在数据被访问或修改时通知更改。
- 自定义模块类:我实现了一个自定义 Module 类,用于跟踪每次
__getattr__和__setattr__调用。变量发生更改时,它会通知使用该变量的模块。此通知采用递归方式,但粒度很细。 - 文件系统跟踪:使用
watchfiles来检测文件更改。如果更改的路径对应一个已导入的 Python 模块,就会触发受影响代码的重新加载。此外,HMR 会监控所有文件读取操作(通过sys.addaudithook),因此非 Python 文件(YAML、JSON 等)的更改也会触发相应的重新加载。
这种运行时方法支持变量级粒度,并且能够跟踪任意文件类型中的依赖关系,比静态分析精确得多。
贡献
这或许是 Python 生态中首批变量级细粒度 HMR 框架之一——说实话,真正的魅力在于我们围绕它构建的生态。
将 uvicorn 与 hmr 搭配使用,就能获得类似 Vite 的开发体验。将 pytest 与 hmr 结合起来,就能实现媲美 Vitest 的测试驱动开发。与其他库结合会有怎样的可能性?无穷无尽。让我们一起畅想——谁知道我们会创造出什么有趣(或有些混乱)的东西!
提示
简单介绍一下背景:hmr 的代码位于另一个仓库,因为说实话,我原本并没打算构建一个 HMR 框架。最初,这只是一次将响应式编程引入 Python 的实验。在此过程中,我意识到:为什么不让模块的全局变量也具备响应性呢?于是 HMR 就此诞生了!虽然它最初只是一个副项目,但我认为它在改善 Python 的开发体验方面潜力巨大。
目前,这个仓库是主要实现和示例的所在地。如果你觉得 HMR 有潜力,或者只是想交流想法,我很期待听到你的声音。我们相信,Python 社区值得拥有更动态、更灵敏的开发体验,也很期待看看它能带我们走向何方!
延伸阅读
关于细粒度响应性,我推荐阅读 SolidJS 对此的精彩讲解。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。