Python CLI 打包与分发实战:基于 uv 与 Hatch 的现代工程流

在很长一段时间里,Python 命令行工具(CLI)的工程化体验被各种历史包袱所困扰:setup.py 与 requirements.txt 混乱并存、虚拟环境管理繁琐、构建 Wheel 包速度缓慢、发布到私有源经常遇到依赖冲突。
随着 pyproject.toml 标准的成熟以及以 Rust 编写的新一代超高速 Python 包管理工具 uv 的崛起,现代 Python CLI 的开发、构建与分发流程迎来了质的飞跃。
本文将以一个内部运维 CLI 工具 ops-pilot 为例,手把手演示如何使用现代标准规范构建一个兼具极速启动、多平台打包和声明式依赖分发的工业级 CLI 工程。
现代工程目录结构
一个标准的现代 Python CLI 项目推荐采用 src-layout 布局,避免测试代码意外污染包导入命名空间:
ops-pilot/
├── pyproject.toml
├── README.md
├── src/
│ └── ops_pilot/
│ ├── __init__.py
│ ├── cli.py
│ ├── commands/
│ │ ├── __init__.py
│ │ ├── deploy.py
│ │ └── health.py
│ └── utils/
│ ├── __init__.py
│ └── terminal.py
└── tests/
├── test_cli.py
└── test_deploy.py
使用 pyproject.toml 进行声明式元数据配置
不再需要繁琐的 setup.py。使用 hatchling 作为构建后端,所有的元数据、依赖项和命令行入口(Entry Points)全部在 pyproject.toml 中集中声明:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "ops-pilot"
version = "0.2.0"
description = "内部自动化运维与效能治理命令行工具"
readme = "README.md"
requires-python = ">=3.10"
license = { text = "MIT" }
authors = [
{ name = "Gu Shian", email = "author@example.com" }
]
dependencies = [
"click>=8.1.7",
"rich>=13.7.1",
"httpx>=0.27.0",
"pydantic>=2.7.0"
]
[project.scripts]
ops-pilot = "ops_pilot.cli:main"
[tool.hatch.build.targets.wheel]
packages = ["src/ops_pilot"]
在 [project.scripts] 段落中,ops-pilot = "ops_pilot.cli:main" 明确声明了安装后在操作系统中注册的全局命令名及对应的 Python 入口函数。
编写主命令入口(基于 Click 与 Rich)
结合 click 的参数解析与 rich 的现代化终端渲染:
# src/ops_pilot/cli.py
import sys
import click
from rich.console import Console
from ops_pilot.commands.deploy import deploy_cmd
from ops_pilot.commands.health import health_cmd
console = Console()
@click.group()
@click.version_option(version="0.2.0")
@click.option("–verbose", "-v", is_flag=True, help="启用详细调试日志")
@click.pass_context
def main(ctx, verbose: bool):
"""ops-pilot: 研发效能与运维治理一体化命令行工具"""
ctx.ensure_object(dict)
ctx.obj["VERBOSE"] = verbose
main.add_command(deploy_cmd)
main.add_command(health_cmd)
if __name__ == "__main__":
main()
利用 uv 实现秒级本地调试与依赖锁定
uv 的依赖解析和安装速度是传统 pip 的 10 到 100 倍。
# 1. 快速创建虚拟环境
uv venv .venv
source .venv/bin/activate
# 2. 以可编辑模式(Editable Mode)极速安装当前工程与依赖
uv pip install -e .
# 3. 运行本地开发命令
ops-pilot –help
在几百毫秒内即可完成环境准备与安装,彻底告别以往漫长的等待。
自动化构建与分发
在 CI/CD 流水线中,我们使用 uv build 一键完成源码分发包(sdist)与二进制 Wheel 包的构建:
# 极速打包
uv build
# 打包产物位于 dist/ 目录:
# dist/ops_pilot-0.2.0-py3-none-any.whl
# dist/ops_pilot-0.2.0.tar.gz
# 一键发布到内部私有 PyPI 仓库
uv publish –publish-url https://pypi.internal.domain/simple/ –token $PYPI_TOKEN
终端用户的最佳安装方式:pipx
为了避免工具的依赖与开发者的全局 Python 环境或项目环境产生冲突,推荐团队成员使用 pipx 进行隔离安装:
# 隔离安装为全局独立命令行
pipx install ops-pilot –index-url https://pypi.internal.domain/simple/
# 随时一键无缝升级
pipx upgrade ops-pilot
通过“pyproject.toml 标准化 + uv 极速构建 + pipx 隔离运行”的黄金组合,Python CLI 工具不仅拥有了接近 Go/Rust 工具的交付流畅度,更能依托 Python 丰富的生态库快速支撑起团队多样化的效能诉求。




