关于 python-pypi-package-builder
python-pypi-package-builder 是指导 AI Agent 设计、测试并发布 Python 包到 PyPI 的技能。内容涵盖包布局、构建后端、版本管理、质量检查与发布流程,并提供生成项目结构的脚本。
主要功能
- 01选择包类型与项目布局
- 02比较 Python 构建后端
- 03配置测试、Lint 和类型检查
- 04规划版本管理与发布流程
- 05使用脚本生成包架构
适用场景
- 01创建可通过 pip 安装的 Python 库
- 02配置 pyproject.toml 和打包工具
- 03准备 CI 与 PyPI 发布
- 04现代化现有 Python 包
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill python-pypi-package-builder安装后在 Claude Code 中输入/python-pypi-package-builder确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/architecture-patterns.mdci-publishing.mdcommunity-docs.mdlibrary-patterns.mdpyproject-toml.mdrelease-governance.mdtesting-quality.mdtooling-ruff.mdversioning-strategy.mdscripts/scaffold.py详细介绍
Python PyPI 包构建技能
一份完整且经过实战检验的指南,涵盖构建、测试、代码检查、版本管理、类型标注以及将生产级 Python 库发布到 PyPI 的全过程——从首次提交到可供社区使用的正式发布。
AI Agent 指令: 在编写任何一行代码或创建任何文件之前,请先完整阅读本文件。每一个决策——目录布局、构建后端、版本管理策略、设计模式、CI——在这里都有对应的决策规则。请按顺序遵循决策树。本技能适用于任何类型的 Python 包(工具库、SDK、命令行工具、插件、数据库)。不要跳过任何章节。
快速导航
| 本文件中的章节 | 涵盖内容 |
|---|---|
| 1. 技能触发条件 | 何时加载本技能 |
| 2. 包类型决策 | 确定你正在构建的内容 |
| 3. 文件夹结构决策 | src/ 布局 vs 扁平布局 vs monorepo |
| 4. 构建后端决策 | setuptools / hatchling / flit / poetry |
| 5. PyPA 打包流程 | 标准的发布流水线 |
| 6. 项目结构模板 | 每种选项的完整布局 |
| 7. 版本管理策略 | PEP 440、semver、动态版本 vs 静态版本 |
| 参考文件 | 涵盖内容 |
|---|---|
references/pyproject-toml.md | 四种后端的全部模板、setuptools_scm、py.typed、工具配置 |
references/library-patterns.md | OOP/SOLID、类型提示、核心类设计、工厂、协议、命令行 |
references/testing-quality.md | conftest.py、单元/后端/异步测试、ruff/mypy/pre-commit |
references/ci-publishing.md | ci.yml、publish.yml、Trusted Publishing、TestPyPI、CHANGELOG、发布检查清单 |
references/community-docs.md | README、文档字符串、CONTRIBUTING、SECURITY、反模式、总检查清单 |
references/architecture-patterns.md | 后端系统(插件/策略)、配置层、传输层、命令行、后端注入 |
references/versioning-strategy.md | PEP 440、SemVer、预发布版本、setuptools_scm 深入解析、flit 静态版本、决策引擎 |
references/release-governance.md | 分支策略、分支保护、OIDC、标签作者校验、防止无效标签 |
references/tooling-ruff.md | 仅使用 Ruff 的配置(替代 black/isort)、mypy 配置、pre-commit、asyncio_mode=auto |
脚手架脚本: 运行 python skills/python-pypi-package-builder/scripts/scaffold.py --name your-package-name
即可用一条命令生成完整的目录布局、桩文件以及 pyproject.toml。
1. 技能触发条件
当用户想要执行以下操作时,加载本技能:
- 创建、搭建或发布一个 Python 包或库到 PyPI
- 构建可通过 pip 安装的 SDK、工具库、命令行工具或框架扩展
- 为 Python 项目配置
pyproject.toml、代码检查、mypy、pre-commit 或 GitHub Actions - 理解版本管理(
setuptools_scm、PEP 440、semver、静态版本) - 理解 PyPA 规范:
py.typed、MANIFEST.in、RECORD、分类器 - 使用 Trusted Publishing(OIDC)或 API token 发布到 PyPI
- 重构现有包,使其遵循现代 Python 打包标准
- 为 Python 库添加类型提示、协议、ABC 或 dataclass
- 将 OOP/SOLID 设计模式应用于 Python 包
- 在构建后端之间进行选择(setuptools、hatchling、flit、poetry)
以下说法同样会触发本技能: “构建一个 Python SDK”、“发布我的库”、“配置 PyPI CI”、 “创建一个 pip 包”、“我该如何发布到 PyPI”、“pyproject.toml 求助”、“PEP 561 typed”、 “setuptools_scm version”、“semver Python”、“PEP 440”、“git tag release”、“Trusted Publishing”。
2. 包类型决策
在编写任何代码之前,先确定用户正在构建的内容。每种类型都有不同的模式。
决策表
| 类型 | 核心模式 | 入口点 | 关键依赖 | 示例包 |
|---|---|---|---|---|
| 工具库 | 纯函数 + 辅助函数的模块 | 仅导入 API | 极少 | arrow、humanize、boltons、more-itertools |
| API 客户端 / SDK | 带方法、认证、重试逻辑的类 | 仅导入 API | httpx 或 requests | boto3、stripe-python、openai |
| 命令行工具 | 命令函数 + 参数解析器 | [project.scripts] 或 [project.entry-points] | click 或 typer | black、ruff、httpie、rich |
| 框架插件 | 插件类、钩子注册 | [project.entry-points."framework.plugin"] | 框架依赖 | pytest-*、django-*、flask-* |
| 数据处理库 | 类 + 函数式管道 | 仅导入 API | 可选:numpy、pandas | pydantic、marshmallow、cerberus |
| 混合 / 通用 | 以上类型的组合 | 因项目而异 | 因项目而异 | 许多真实世界的包 |
决策规则: 如果不清楚,询问用户。一个包可以组合多种类型(例如,带有命令行入口点的 SDK)——结构决策时使用主要类型,并在其基础上叠加次要类型的模式。
各类型的实现模式,请参见 references/library-patterns.md。
包命名规则
- PyPI 名称:全小写、连字符 ——
my-python-library - Python 导入名:下划线 ——
my_python_library - 开始前检查可用性:https://pypi.org/search/
- 避免遮蔽热门包(先验证
pip install <name>会失败)
3. 文件夹结构决策
决策树
Does the package have 5+ internal modules OR multiple contributors OR complex sub-packages?
├── YES → Use src/ layout
│ Reason: prevents accidental import of uninstalled code during development;
│ separates source from project root files; PyPA-recommended for large projects.
│
├── NO → Is it a single-module, focused package (e.g., one file + helpers)?
│ ├── YES → Use flat layout
│ └── NO (medium complexity) → Use flat layout, migrate to src/ if it grows
│
└── Is it multiple related packages under one namespace (e.g., myorg.http, myorg.db)?
└── YES → Use namespace/monorepo layout
快速规则摘要
| 情况 | 使用 |
|---|---|
| 新项目,未来规模未知 | src/ 布局(最安全的默认选择) |
| 单一用途,1–4 个模块 | 扁平布局 |
| 大型库,众多贡献者 | src/ 布局 |
| 一个仓库中有多个包 | 命名空间 / 单仓库 |
| 迁移旧的扁平项目 | 保持扁平;在下一个主版本迁移到 src/ |
4. 构建后端决策
决策树
Does the user need version derived automatically from git tags?
├── YES → Use setuptools + setuptools_scm
│ (git tag v1.0.0 → that IS your release workflow)
│
└── NO → Does the user want an all-in-one tool (deps + build + publish)?
├── YES → Use poetry (v2+ supports standard [project] table)
│
└── NO → Is the package pure Python with no C extensions?
├── YES, minimal config preferred → Use flit
│ (zero config, auto-discovers version from __version__)
│
└── YES, modern & fast preferred → Use hatchling
(zero-config, plugin system, no setup.py needed)
Does the package have C/Cython/Fortran extensions?
└── YES → MUST use setuptools (only backend with full native extension support)
后端对比
| 后端 | 版本来源 | 配置 | C 扩展 | 最适合 |
|---|---|---|---|---|
setuptools + setuptools_scm | git 标签(自动) | pyproject.toml + 可选的 setup.py 兼容层 | 是 | 使用 git 标签发布的项目;任意复杂度 |
hatchling | 手动或插件 | 仅 pyproject.toml | 否 | 新的纯 Python 项目;快速、现代 |
flit | __init__.py 中的 __version__ | 仅 pyproject.toml | 否 | 非常简单的单模块包 |
poetry | pyproject.toml 字段 | 仅 pyproject.toml | 否 | 希望集成依赖管理的团队 |
四个完整的 pyproject.toml 模板,请参见 references/pyproject-toml.md。
5. PyPA 打包流程
这是从源代码到用户安装的规范端到端流程。 发布前必须理解每一个步骤。
1. SOURCE TREE
Your code in version control (git)
└── pyproject.toml describes metadata + build system
2. BUILD
python -m build
└── Produces two artifacts in dist/:
├── *.tar.gz → source distribution (sdist)
└── *.whl → built distribution (wheel) — preferred by pip
3. VALIDATE
twine check dist/*
└── Checks metadata, README rendering, and PyPI compatibility
4. TEST PUBLISH (first release only)
twine upload --repository testpypi dist/*
└── Verify: pip install --index-url https://test.pypi.org/simple/ your-package
5. PUBLISH
twine upload dist/* ← manual fallback
OR GitHub Actions publish.yml ← recommended (Trusted Publishing / OIDC)
6. USER INSTALL
pip install your-package
pip install "your-package[extra]"
关键 PyPA 概念
| 概念 | 含义 |
|---|---|
| sdist | 源代码分发 —— 你的源代码 + 元数据;在没有 wheel 可用时使用 |
| wheel (.whl) | 预构建的二进制文件 —— pip 直接解压到 site-packages;无需构建步骤 |
| PEP 517/518 | 通过 pyproject.toml [build-system] 表定义的标准构建系统接口 |
| PEP 621 | pyproject.toml 中的标准 [project] 表;所有现代后端都支持 |
| PEP 639 | license 键作为 SPDX 字符串(例如 "MIT"、"Apache-2.0")—— 而不是 {text = "MIT"} |
| PEP 561 | py.typed 空标记文件 —— 告诉 mypy/IDE 此包附带类型信息 |
完整的 CI 工作流和发布设置,请参见 references/ci-publishing.md。
6. 项目结构模板
A. src/ 布局(新项目的推荐默认选择)
your-package/
├── src/
│ └── your_package/
│ ├── __init__.py # Public API: __all__, __version__
│ ├── py.typed # PEP 561 marker — EMPTY FILE
│ ├── core.py # Primary implementation
│ ├── client.py # (API client type) or remove
│ ├── cli.py # (CLI type) click/typer commands, or remove
│ ├── config.py # Settings / configuration dataclass
│ ├── exceptions.py # Custom exception hierarchy
│ ├── models.py # Data classes, Pydantic models, TypedDicts
│ ├── utils.py # Internal helpers (prefix _utils if private)
│ ├── types.py # Shared type aliases and TypeVars
│ └── backends/ # (Plugin pattern) — remove if not needed
│ ├── __init__.py # Protocol / ABC interface definition
│ ├── memory.py # Default zero-dep implementation
│ └── redis.py # Optional heavy implementation
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Shared fixtures
│ ├── unit/
│ │ ├── __init__.py
│ │ ├── test_core.py
│ │ ├── test_config.py
│ │ └── test_models.py
│ ├── integration/
│ │ ├── __init__.py
│ │ └── test_backends.py
│ └── e2e/ # Optional: end-to-end tests
│ └── __init__.py
├── docs/ # Optional: mkdocs or sphinx
├── scripts/
│ └── scaffold.py
├── .github/
│ ├── workflows/
│ │ ├── ci.yml
│ │ └── publish.yml
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ └── feature_request.md
├── .pre-commit-config.yaml
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
├── README.md
└── .gitignore
B. 扁平布局(小型 / 专注的包)
your-package/
├── your_package/ # ← at root, not inside src/
│ ├── __init__.py
│ ├── py.typed
│ └── ... (same internal structure)
├── tests/
└── ... (same top-level files)
C. 命名空间 / Monorepo 布局(多个相关包)
your-org/
├── packages/
│ ├── your-org-core/
│ │ ├── src/your_org/core/
│ │ └── pyproject.toml
│ ├── your-org-http/
│ │ ├── src/your_org/http/
│ │ └── pyproject.toml
│ └── your-org-cli/
│ ├── src/your_org/cli/
│ └── pyproject.toml
├── .github/workflows/
└── README.md
每个子包都有自己的 pyproject.toml。它们通过 PEP 420 隐式命名空间包共享 your_org 命名空间(命名空间根目录中没有 __init__.py)。
内部模块指南
| 文件 | 用途 | 何时包含 |
|---|---|---|
__init__.py | 公共 API 接口;重新导出;__version__ | 始终 |
py.typed | PEP 561 类型化包标记(空文件) | 始终 |
core.py | 主类 / 主要逻辑 | 始终 |
config.py | 设置 dataclass 或 Pydantic 模型 | 需要配置时 |
exceptions.py | 异常层级(YourBaseError → 具体异常) | 始终 |
models.py | 数据模型 / DTO / TypedDict | 数据较多时 |
utils.py | 内部辅助函数(不属于公共 API) | 按需 |
types.py | 共享的 TypeVar、TypeAlias、Protocol 定义 | 类型较复杂时 |
cli.py | 命令行入口点(click/typer) | 仅命令行类型 |
backends/ | 插件 / 策略模式 | 需要可替换实现时 |
_compat.py | Python 版本兼容性垫片 | 需要兼容 3.9–3.13 时 |
7. 版本管理策略
PEP 440 —— 标准
Canonical form: N[.N]+[{a|b|rc}N][.postN][.devN]
Examples:
1.0.0 Stable release
1.0.0a1 Alpha (pre-release)
1.0.0b2 Beta
1.0.0rc1 Release candidate
1.0.0.post1 Post-release (e.g., packaging fix only)
1.0.0.dev1 Development snapshot (not for PyPI)
语义化版本(推荐)
MAJOR.MINOR.PATCH
MAJOR: Breaking API change (remove/rename public function/class/arg)
MINOR: New feature, fully backward-compatible
PATCH: Bug fix, no API change
使用 setuptools_scm 的动态版本管理(推荐用于 git 标签工作流)
# How it works:
git tag v1.0.0 → installed version = 1.0.0
git tag v1.1.0 → installed version = 1.1.0
(commits after tag) → version = 1.1.0.post1 (suffix stripped for PyPI)
# In code — NEVER hardcode when using setuptools_scm:
from importlib.metadata import version, PackageNotFoundError
try:
__version__ = version("your-package")
except PackageNotFoundError:
__version__ = "0.0.0-dev" # Fallback for uninstalled dev checkouts
必需的 pyproject.toml 配置:
[tool.setuptools_scm]
version_scheme = "post-release"
local_scheme = "no-local-version" # Prevents +g<hash> from breaking PyPI uploads
关键: 在每个 CI checkout 步骤中始终设置 fetch-depth: 0。如果没有完整的 git 历史记录,setuptools_scm 将无法找到标签,构建版本会静默回退到 0.0.0+dev。
静态版本管理(flit、hatchling 手动、poetry)
# your_package/__init__.py
__version__ = "1.0.0" # Update this before every release
依赖项的版本说明符最佳实践
# In [project] dependencies:
"httpx>=0.24" # Minimum version — PREFERRED for libraries
"httpx>=0.24,<1.0" # Upper bound only when a known breaking change exists
"httpx==0.27.0" # Pin exactly ONLY in applications, NOT libraries
# NEVER do this in a library — it breaks dependency resolution for users:
# "httpx~=0.24.0" # Too tight
# "httpx==0.27.*" # Fragile
版本递增 → 发布流程
# 1. Update CHANGELOG.md — move [Unreleased] entries to [x.y.z] - YYYY-MM-DD
# 2. Commit the changelog
git add CHANGELOG.md
git commit -m "chore: prepare release vX.Y.Z"
# 3. Tag and push — this triggers publish.yml automatically
git tag vX.Y.Z
git push origin main --tags
# 4. Monitor GitHub Actions → verify on https://pypi.org/project/your-package/
有关所有四种后端的完整 pyproject.toml 模板,请参阅 references/pyproject-toml.md。
下一步阅读
在理解了决策和结构之后:
-
设置
pyproject.toml→references/pyproject-toml.md全部四种后端模板(setuptools+scm、hatchling、flit、poetry)、完整工具配置、py.typed设置、版本管理配置。 -
编写库代码 →
references/library-patterns.mdOOP/SOLID 原则、类型提示(PEP 484/526/544/561)、核心类设计、工厂函数、__init__.py、插件 / 后端模式、命令行入口点。 -
添加测试和代码质量保障 →
references/testing-quality.mdconftest.py、单元 / 后端 / 异步测试、参数化、ruff/mypy/pre-commit 设置。 -
设置 CI/CD 并发布 →
references/ci-publishing.md使用 Trusted Publishing(OIDC,无需 API 令牌)的ci.yml、publish.yml、CHANGELOG 格式、发布检查清单。 -
为社区 / 开源项目润色 →
references/community-docs.mdREADME 章节、docstring 格式、CONTRIBUTING、SECURITY、issue 模板、反模式表格以及主发布检查清单。 -
设计后端、配置、传输、命令行 →
references/architecture-patterns.md后端系统(插件 / 策略模式)、Settings dataclass、HTTP 传输层、使用 click/typer 的命令行、后端注入规则。 -
选择并实现版本管理策略 →
references/versioning-strategy.mdPEP 440 规范形式、SemVer 规则、预发布标识符、setuptools_scm 深入解析、flit 静态版本管理、决策引擎(DEFAULT/BEGINNER/MINIMAL)。 -
治理发布并保护发布流水线 →
references/release-governance.md分支策略、分支保护规则、OIDC Trusted Publishing 设置、CI 中标签作者验证、标签格式强制、完整受治理的publish.yml。 -
使用 Ruff 简化工具链 →
references/tooling-ruff.md仅使用 Ruff 的配置替代 black/isort/flake8、mypy 配置、pre-commit 钩子、asyncio_mode=auto(移除 @pytest.mark.asyncio)、迁移指南。