欢迎光临
我们一直在努力

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

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 丰富的生态库快速支撑起团队多样化的效能诉求。

赞(0)
未经允许不得转载:171主机测评 » Python CLI 打包与分发实战:基于 uv 与 Hatch 的现代工程流
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址