使用 Hatch 打包发布 Textual 应用:从 `pip install` 到命令行启动的完整指南

📅 发布时间:2026/9/19 16:37:53
使用 Hatch 打包发布 Textual 应用:从 `pip install` 到命令行启动的完整指南
使用 Hatch 打包发布 Textual 应用从pip install到命令行启动的完整指南【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textual导读Textual 应用本质上是一个 Python 程序因此可以像任何 Python 库一样通过 PyPI 发布让用户用一条pip install安装、用一条命令启动。本指南以 Textual 仓库中的计算器示例examples/calculator.py为实战对象完整演示如何使用 Hatch 这一构建工具完成项目的初始化、依赖声明、入口点entry point配置、构建与发布最终让用户通过calculator命令在终端直接启动你的 TUI 应用。为什么需要打包 Textual 应用Python 应用可以通过 PyPI 分发用户使用pip即可安装这个过程被称为packaging打包。Textual 应用的打包流程与普通 Python 库基本一致唯一额外要求是应用需要能够从命令行直接启动而不是要求用户手动编写python -m ...或进入 Python REPL 调用。提示如果你不想打包成桌面/终端应用另一个选择是借助 textual-serve 将应用转换为 Web 应用。Hatch 是一个构建工具帮助完成打包的命令行应用。任何构建工具例如 Poetry都能完成 Textual 应用的打包但 Hatch 功能丰富、易于上手因此是本文的选择。事实上Textual 项目自身在早期版本中也使用过 Poetry 管理依赖见仓库根目录的 pyproject.toml其中包含[tool.poetry]段落这从侧面印证了“构建工具可自由选择”这一观点——无论选哪种工具核心机制都是统一的。打包前的心理准备Python 打包对于初次接触者可能有些吓人但它并不复杂。把完整流程走上一两遍之后你会发现它相当直白项目初始化 → 写代码 → 声明依赖 → 配置入口点 → 构建 → 发布。每一步都有标准做法可循。实战目标把计算器示例发布到 PyPI为了演示打包我们将把 Textual 仓库examples目录下的计算器示例发布到 PyPI。最终目标是让用户执行pip install textual-calculator然后在命令行直接启动应用calculator计算器示例的源码位于 examples/calculator.py它定义了一个名为CalculatorApp的App子类并通过CSS_PATH calculator.tcss关联同目录下的样式文件 examples/calculator.tcss。这两个文件一个 Python 模块 一个 Textual CSS 样式文件正是本指南中需要一起打包进项目的“代码资产”。安装 HatchHatch 的安装方式有多种请参考官方安装文档选择最适合你操作系统的方法。安装完成后命令行中应该出现hatch命令运行以下命令验证安装是否成功hatch若命令正常输出帮助信息说明 Hatch 已就绪。用hatch new初始化项目Hatch 通过new子命令自动生成初始目录结构和文件。运行hatch new并跟上项目名称。对计算器示例来说项目名称是 textual calculatorhatch new textual calculator该命令会生成如下目录结构textual-calculator ├── LICENSE.txt ├── README.md ├── pyproject.toml ├── src │ └── textual_calculator │ ├── __about__.py │ └── __init__.py └── tests └── __init__.py这一结构遵循 Python 打包领域公认的约定各文件作用如下LICENSE.txt包含你要以之分发代码的许可证。README.md包含项目信息的 Markdown 文件会展示在 PyPI 和 GitHub如果你使用 GitHub上。你可以编辑它写入应用介绍和使用方法。pyproject.toml一个 TOML 文件包含项目的元数据附加信息与打包配置。这是 Python 生态的标准文件既可以手动编辑也可以由构建工具如 Hatch维护。src/textual_calculator/__about__.py存放应用版本号。每次发布新版本时都应更新它。src/textual_calculator/__init__.py和tests/__init__py标记所在目录包含 Python 代码这两个文件通常为空。顶层目录名为src其中应包含一个以项目命名的子目录这个子目录就是代码可以被导入的名字。在本例中该目录为textual_calculator因此代码中可以执行import textual_calculator。此外还有一个tests目录你可以把测试代码放进去——Textual 官方提供了完整的测试指南测试指南。关于命名的更多细节注意 Hatch 如何把项目名中的空格替换为连字符即textual-calculator而src中的目录却用下划线即textual_calculator。原因是src下的目录就是 Python 模块而 Python 的 import 语法不允许出现连字符顶层目录没有这个限制使用连字符作为目录名则更常见。如果你的项目名包含空格请牢记这一点。已有代码怎么办hatch new假定你从零开始。如果你已有现成代码需要打包请进入你的项目目录并运行将YOUR PROJECT NAME替换为你的项目名hatch new --init YOUR PROJECT NAME这会在当前目录生成一个pyproject.toml。注意如果你的代码能遵循上述目录结构约定后续会简单很多。这可能要求你移动文件——只需一次性完成即可。添加应用代码你的代码应放在src/PROJECT NAME内。对计算器示例我们把calculator.py和calculator.tcss复制进src/textual_calculator目录目录将变为textual-calculator ├── LICENSE.txt ├── README.md ├── pyproject.toml ├── src │ └── textual_calculator │ ├── __about__.py │ ├── __init__.py │ ├── calculator.py │ └── calculator.tcss └── tests └── __init__.py声明依赖你的 Textual 应用大概率依赖其他 Python 库至少依赖 Textual 本身。必须把这些依赖列进pyproject.toml确保它们随应用一同安装。pyproject.toml中有一个以[project]开头的段落大致如下[project] name textual-calculator dynamic [version] description A example app readme README.md requires-python 3.8 license MIT keywords [] authors [ { name Will McGugan, email redactedtextualize.io }, ] classifiers [ Development Status :: 4 - Beta, Programming Language :: Python, Programming Language :: Python :: 3.8, Programming Language :: Python :: 3.9, Programming Language :: Python :: 3.10, Programming Language :: Python :: 3.11, Programming Language :: Python :: 3.12, Programming Language :: Python :: Implementation :: CPython, Programming Language :: Python :: Implementation :: PyPy, ] dependencies []我们关心的是dependencies值它应列出应用的全部依赖。如果你需要特定版本可以用跟上版本号。对计算器来说唯一依赖是 Textual。修改如下一行即可dependencies [textual0.47.1]写这篇文章时 Textual 的最新版是0.47.1。dependencies中的条目会确保即使以后发布更新版本也能安装到这个指定版本。关于如何更精细地指定依赖版本范围、可选依赖等请参阅 Hatch 文档中的依赖配置说明。依赖管理的补充说明requires-python字段同样值得关注——它声明了应用支持的 Python 版本范围pip 会在安装时据此判断当前解释器是否兼容。classifiers则帮助 PyPI 对项目进行分类展示。作为对照Textual 项目自身在 pyproject.toml 中通过[tool.poetry.dependencies]声明了python ^3.9与markdown-it-py、rich、platformdirs等运行时依赖并通过[tool.poetry.extras]定义可选依赖组如syntax一组 tree-sitter 相关库——如果你的 TUI 应用包含 Markdown 渲染、语法高亮等进阶功能这些依赖同样会以类似方式进入dependencies列表。使用 Hatch 管理虚拟环境处理 Python 代码时一个常见难题是多个项目依赖不同版本。例如另一个应用使用 Textual0.40.0如果安装0.47.1版本可能会让它崩溃。标准的解决方案是虚拟环境venv让每个项目拥有自己独立的依赖集合。Hatch 可以为你创建虚拟环境且使用起来非常简单。进入包含pyproject.toml的目录运行以下命令创建新的虚拟环境只需执行一次虚拟环境会持久保存hatch env create然后运行以下命令激活虚拟环境hatch shell现在运行python你的应用及其依赖已可用于导入$ python Python 3.11.1 (main, Jan 1 2023, 10:28:48) [Clang 14.0.0 (clang-1400.0.29.202)] on darwin Type help, copyright, credits or license for more information. from textual_calculator import calculator运行应用你可以在命令行用以下命令启动计算器python -m textual_calculator.calculator-m开关告诉 Python 导入该模块并执行它模块末尾的if __name__ __main__:分支会调用CalculatorApp().run()。虽然这种运行方式可行适合开发调试但对分享来说并不理想。更可取的做法是提供一个专用命令来启动应用让用户轻松从命令行运行。为此我们需要在pyproject.toml中添加入口点entry point。配置入口点Entry Points入口点entry point是项目中可以从命令行运行的一个函数。对计算器示例我们首先需要创建一个运行应用的函数。在src/textual_calculator文件夹中新建文件entry_points.pyfrom textual_calculator.calculator import CalculatorApp def calculator(): app CalculatorApp() app.run()提示如果你已经有运行应用的函数可能就不需要entry_points.py文件了。在 examples/calculator.py 中if __name__ __main__:分支做的就是类似的事但入口点要求一个可被导入的具名函数因此独立文件更清晰。然后编辑pyproject.toml添加如下段落[project.scripts] calculator textual_calculator.entry_points:calculator[project.scripts]段落中的每一项可以有多个把一条命令映射到一个导入路径和函数名。在上面第二行中之前的是命令名calculator之后的字符串包含导入名textual_calculator.entry_points、冒号:和函数名也叫calculator。指定这样一个入口点等价于在 Python REPL 中执行 import textual_calculator.entry_points textual_calculator.entry_points.calculator()编辑完pyproject.toml后运行以下命令注册calculator命令pip install -e .说明你肯定用过pip但可能没用过-e .。-e以可编辑editable模式安装项目意味着 pip 不会复制.py文件而是直接引用当前目录的代码点号.表示安装当前目录中的项目。这样每次修改源码无需重装即可生效。现在可以从命令行直接启动计算器calculator构建发行包构建会生成包含你代码的归档文件。用户通过 pip 或其它工具安装包时下载的就是这些归档。用 Hatch 构建项目时切换到包含pyproject.toml的目录并运行hatch build子命令cd textual-calculator hatch build片刻之后Hatch 会创建distdistribution发行目录内含项目归档文件。你通常不需要直接使用这些文件但可以查看目录内容了解产物形态。注意 TCSS 与其他文件的打包Hatch 通常会包含项目所需的全部文件即.py文件也会包含项目目录中的 Textual CSS.tcss文件。并非所有构建工具都会包含除.py以外的文件如果你使用其他构建工具可能需要查阅文档了解如何把 Textual CSS 文件一并打入包中。这正是calculator.tcss需要与calculator.py放在同一包目录下src/textual_calculator/的原因——Textual 通过CSS_PATH相对路径定位样式文件包内保持相对结构即可正确加载。发布到 PyPI项目构建成功后就可以发布到 PyPI 了。如果你还没有 PyPI 账号请先注册一个并务必按照指引验证邮箱、开启 2FA双因素认证。有了账号后登录 PyPI 进入 Account Settings账户设置标签页。向下滚动点击 Add API token添加 API token按钮。在 Create API Token创建 API token表单中创建名为 Uploads、范围为 Entire project整个项目的 token然后点击 Create token创建 token按钮。复制这个 API token一串随机字符并妥善保存。这个 API token 是 PyPI 验证上传归属你的账号的凭证绝不要分享它或上传到互联网。运行以下命令发布将YOUR API TOKEN替换为上一步生成的文本hatch publish -u __token__ -a YOUR API TOKENHatch 会上传发行文件终端中应显示一个 PyPI URL。管理 API Token首次上传时需要创建具有 all projects全部项目权限的 API token。当你发布应用的新版本时建议生成一个仅允许上传单个项目的新 token并删除旧 token。这样即使 token 泄露也只会影响那一个项目将损失控制在最小范围。发布新版本如果你修改了应用并想发布更新需要先更新__about__.py中的version值然后重复执行构建和发布步骤。提示关于版本号管理可以参考 Semver 这套流行的版本规范——Textual 项目自身就采用语义化版本号当前版本信息见 pyproject.toml 中的version 8.2.8。用户视角安装并运行从用户的角度看只需运行以下命令即可安装计算器pip install textual_calculator然后使用以下命令启动calculator推荐搭配 Pipx 安装以这种方式安装应用的一个缺点是除非用户创建了虚拟环境否则可能因依赖冲突破坏其他包。这个问题的一个优秀解决方案是 pipx它会自动创建互不冲突的虚拟环境。安装 PipX 后你可以建议用户用以下命令安装你的应用pipx install textual_calculator这同样会安装计算器及其textual依赖但消除了依赖冲突的隐患。验证打包结果仓库内的测试佐证Textual 仓库自身就是“TUI 应用可被自动化验证”的绝佳例证。在 tests/snapshot_tests/test_snapshots.py 中计算器示例通过快照测试得到验证def test_example_calculator(snap_compare): Test the calculator example. assert snap_compare(EXAMPLES_DIR / calculator.py)这提示你在打包自己的 Textual 应用时可以在tests目录中编写类似的测试并在hatch build前确保测试全部通过。Textual 的完整测试方法论见 测试指南其中涵盖了 Pilot 驱动的交互测试、快照测试等与 TUI 特性紧密结合的验证手段。总结使用一个构建系统例如 Hatch。用hatch new或等价命令初始化项目。编写一个运行应用的函数如果还没有。在pyproject.toml中添加依赖和入口点。用hatch build构建应用。用hatch publish发布应用。如果在打包 Textual 应用时遇到任何问题可以查阅仓库中的 帮助文档。【免费下载链接】textualThe lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.项目地址: https://gitcode.com/gh_mirrors/te/textual创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考