跳到主要内容
Python 项目打包发布指南:从结构创建到 PyPI 上传 | 极客日志
Python
Python 项目打包发布指南:从结构创建到 PyPI 上传 Python 项目的打包发布全流程,涵盖项目目录结构搭建、pyproject.toml 元数据配置、构建后端选择、许可证设置、生成分发档案以及通过 twine 上传至 TestPyPI 和正式 PyPI 的具体操作。内容包含虚拟环境隔离、API 令牌安全认证、依赖管理及版本控制等关键技术点,旨在帮助开发者建立规范的发布工作流。
Python 项目打包发布指南:从结构创建到 PyPI 上传
将开发完成的 Python 项目打包并发布,是与其他开发者共享代码、构建生态的重要步骤。本文将详细介绍如何创建一个标准的 Python 包,配置必要的元数据,构建分发包,并最终上传至 Python 包索引(PyPI)或测试环境 TestPyPI。
1. 环境准备
在开始之前,请确保你的开发环境已安装最新版本的 Python 和 pip。建议创建一个独立的虚拟环境以避免依赖冲突。
1.1 升级 pip
python3 -m pip install --upgrade pip
py -m pip install --upgrade pip
1.2 创建虚拟环境
推荐使用 venv 模块创建隔离环境:
python3 -m venv venv
source venv/bin/activate
venv\Scripts\activate
2. 项目结构设计
现代 Python 项目推荐采用 src 布局,这有助于避免本地导入与包导入的混淆,并简化命名空间管理。
2.1 目录结构
在根目录下创建如下结构:
packaging_tutorial/
└── src /
└── example_package_YOUR_USERNAME_HERE/
├── __init__.py
└── example.py
src/ : 存放源代码的目录,防止与测试脚本或临时文件混用。
init .py : 使目录成为包,即使为空也需存在。
example.py : 核心逻辑模块。
2.2 编写示例代码
打开 example.py 并添加基础功能:
def add_one (number ):
"""
接收一个数字并返回加一后的结果。
Args:
number (int): 输入的数字
Returns:
int: 加一后的数字
"""
return number + 1
3. 配置文件与元数据
Python 包的配置主要依赖于 pyproject.toml 文件,它定义了构建系统、项目元数据和依赖项。
3.1 选择构建后端
构建后端负责将源代码转换为分发包(如 .whl 或 .tar.gz)。目前主流的后端包括 Hatchling、Setuptools、Flit 和 PDM。
在 pyproject.toml 中指定构建后端:
[build-system]
requires = ["hatchling" ]
build-backend = "hatchling.build"
[build-system]
requires = ["setuptools>=61.0" ]
build-backend = "setuptools.build_meta"
3.2 配置项目元数据 在 pyproject.toml 中添加 [project] 部分,定义包的名称、版本、作者等关键信息。
[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
description = "A small example package demonstrating best practices"
readme = "README.md"
requires-python = ">=3.7"
license = {text = "MIT" }
authors = [
{ name="Example Author" , email="[email protected] " },
]
maintainers = [
{ name="Example Maintainer" , email="[email protected] " },
]
classifiers = [
"Programming Language :: Python :: 3" ,
"License :: OSI Approved :: MIT License" ,
"Operating System :: OS Independent" ,
"Development Status :: 4 - Beta" ,
"Intended Audience :: Developers" ,
"Topic :: Software Development :: Libraries :: Python Modules" ,
]
dependencies = []
[project.urls]
Homepage = "https://github.com/yourusername/example_package"
Documentation = "https://github.com/yourusername/example_package#readme"
Repository = "https://github.com/yourusername/example_package.git"
Changelog = "https://github.com/yourusername/example_package/blob/main/CHANGELOG.md"
BugTracker = "https://github.com/yourusername/example_package/issues"
name : 包的分发名称,必须唯一,仅包含字母、数字、.、_ 和 -。
version : 遵循语义化版本控制(SemVer),格式为 主版本号。次版本号.修订号。
classifiers : 用于分类和搜索,应至少包含 Python 版本、许可证和操作系统支持信息。
dependencies : 运行时依赖列表,可在此处直接列出包名及版本要求。
4. 辅助文件创建 为了符合开源规范并提供良好的用户体验,需要创建以下文件。
4.1 README.md 这是用户查看包详情时首先看到的内容,应包含安装方法、使用示例和贡献指南。
# Example Package
This is a simple example package.
## Installation
Install the latest version from PyPI:
```bash
pip install example-package-your-username-here
Usage from example_package_your_username_here import example
result = example.add_one(2 )
print (result)
License This project is licensed under the MIT License.
#
每个上传到 PyPI 的包都必须包含许可证文件,明确用户使用条款。常见的开源许可证有 MIT、Apache 2.0、GPL 等。
例如 MIT 许可证内容:
Copyright (c) 2024 Your Name
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
### 4.3 测试目录
创建 `tests/` 目录用于存放单元测试,虽然构建时默认不包含,但对质量保证至关重要。
packaging_tutorial/
├── src/
│ └── example_package...
├── tests/
│ └── test_example.py
├── pyproject.toml
├── README.md
└── LICENSE
构建工具会将源代码转换为分发包,主要包括源分发包(`.tar.gz` )和构建分发包(`.whl` )。
确保安装了最新的 `build` 工具:
`` `bash
python3 -m pip install --upgrade build
5.2 执行构建 构建完成后,会在 dist/ 目录下生成两个文件:
dist/
├── example_package_YOUR_USERNAME_HERE-0.0 .1 -py3-none-any.whl
└── example_package_YOUR_USERNAME_HERE-0.0 .1 .tar.gz
.whl : 预编译的二进制包,安装速度快,适用于通用平台。
.tar.gz : 源码包,包含所有源代码,便于审计和跨平台构建。
最佳实践 :始终同时上传两种格式,以确保最大兼容性。
6. 安全认证与上传 由于安全策略升级,PyPI 不再允许使用用户名和密码直接上传,必须使用 API 令牌进行身份验证。
6.1 注册 TestPyPI 账户 TestPyPI 是 PyPI 的测试实例,适合在正式发布前验证流程。
6.2 生成 API 令牌
登录 TestPyPI 控制台,进入账户设置页面。
点击「Add API Token」。
设置权限范围为「Entire account」。
复制生成的令牌并妥善保存(一旦关闭页面将无法再次查看)。
6.3 配置 Twine python3 -m pip install --upgrade twine
创建或修改 ~/.pypirc 配置文件以存储凭据:
[testpypi]
username = __token__
password = pypi-AgENdGVzdC5weXBpLm9xxxxxxxxxxxxxxx
注意:密码字段填入完整的 API 令牌,用户名固定为 __token__。
6.4 上传分发包 使用 Twine 上传 dist 目录下的所有文件:
python3 -m twine upload --repository testpypi dist/*
上传成功后,可在 TestPyPI 上查看包详情。
7. 验证安装 上传后,建议在虚拟环境中验证包是否可正常安装和使用。
7.1 从 TestPyPI 安装 python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE
--index-url: 指定 TestPyPI 源。
--no-deps: 避免安装 TestPyPI 上不存在的依赖项导致失败。
7.2 功能测试 from example_package_your_username_here import example
assert example.add_one(2 ) == 3
print ("Installation verified successfully!" )
8. 正式发布于 PyPI 当测试无误后,可发布到正式的 Python Package Index。
在 https://pypi.org 注册正式账户。
使用相同的 Twine 命令,但移除 --repository 参数,默认上传至 PyPI。
输入正式账户的 API 令牌。
python3 -m twine upload dist/*
包名一旦发布不可更改,若需改名需联系 PyPI 管理员删除旧包。
版本号必须递增,不能重复使用已发布的版本号。
生产环境上传需谨慎,建议先在 TestPyPI 充分测试。
9. 常见问题与故障排查
9.1 包名冲突 如果提示包名已被占用,请更换名称或在 PyPI 申请重命名(仅限特定情况)。建议使用带有个人标识的前缀。
9.2 构建错误
编码问题 :确保 setup.cfg 或 pyproject.toml 中的字符集为 UTF-8。
依赖缺失 :检查 requires 字段是否包含了构建所需的依赖包。
路径错误 :确保 readme 和 license 文件路径正确且存在。
9.3 上传失败
令牌无效 :检查 .pypirc 中的密码是否为完整令牌,且未过期。
网络超时 :尝试增加重试次数或使用稳定的网络连接。
10. 维护与更新
版本管理 :每次修复 Bug 或新增功能时,更新版本号(遵循 SemVer 规范)。
更新描述 :在 CHANGELOG.md 中记录变更日志。
响应 Issue :及时回复 GitHub 上的用户反馈和问题报告。
通过遵循上述步骤,您可以规范地创建、测试并发布高质量的 Python 包,使其成为您技术资产的一部分。
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online