1. Twine 是什么? #
Twine 是一个用于将 Python 包(库)安全地发布到 PyPI(Python Package Index)及其它代码仓库(如公司的私有仓库)的工具。它的核心功能是上传打包好的分发文件。
简单来说,当你用 setuptools 和 wheel 等工具将你的代码打包成 .tar.gz 或 .whl 文件后,Twine 就是那个负责“送货上门”(上传到PyPI)的快递员。
2. 为什么需要 Twine? (与 setup.py upload 的区别) #
在 Twine 出现之前,开发者通常使用 python setup.py upload 命令来上传包。那么为什么现在都推荐使用 Twine 呢?主要是因为安全和可靠性:
| 特性 | Twine | setup.py upload |
|---|---|---|
| 安全性 | 安全:总是上传预先构建好的分发文件。你可以在上传前检查文件内容。 | 不安全:在上传过程中动态构建包,可能会意外执行 setup.py 中的恶意代码(如果你的机器被黑了)。 |
| 可靠性 | 可靠:上传已存在的文件,过程简单稳定。 | 不可靠:构建和上传过程耦合,容易因构建问题导致上传失败。 |
| 验证 | 会验证:在上传前会对你提供的元数据进行强验证,提前发现错误。 | 不验证:不会对元数据进行强验证,错误可能直到用户安装时才发现。 |
因此,官方强烈推荐使用 Twine 来上传你的 Python 包。
3. 安装 Twine #
安装 Twine 非常简单,使用 pip 即可:
pip install twine通常,它会和构建工具一起被安装,如果你需要完整的打包环境,可以安装 build:
pip install build twine4. 核心用法:分步发布 Python 包 #
使用 Twine 发布包通常是一个两步(或三步)过程。
4.1 第 1 步:构建分发文件 #
在上传之前,你需要先将你的源代码打包成分发文件。现代 Python 打包推荐使用 build 工具(Python 3.10+ 官方推荐)。
在你的项目根目录(与 pyproject.toml 或 setup.py 同级)下运行:
python -m build这个命令会生成一个 dist/ 目录,里面包含两种格式的分发文件:
your_package-version.tar.gz:源代码归档文件。your_package-version-py3-none-any.whl:预构建的 Wheel 文件。
注意:你也可以使用旧的
setup.py方式:python setup.py sdist bdist_wheel,但build是更现代、更标准的选择。
4.2 第 2 步:上传到 PyPI #
现在,使用 Twine 将 dist/ 目录下的所有文件上传到 PyPI。
上传到正式的 PyPI (https://pypi.org/)
twine upload dist/*执行这个命令后,Twine 会提示你输入 PyPI 的用户名和密码。
上传到测试 PyPI (https://test.pypi.org/) 在正式发布前,强烈建议先发布到测试平台进行验证。
twine upload --repository testpypi dist/*4.3 认证方式:安全地提供用户名和密码 #
直接在命令行输入密码不安全,也不适合自动化流程。Twine 支持多种认证方式:
4.3.1 方法 1:使用 ~/.pypirc 配置文件(推荐) #
在你的用户主目录(C:\Users\用户名\ 或 ~/)下创建一个名为 .pypirc 的文件。
[pypi]
username = __token__
password = pypi-你的API令牌
[testpypi]
username = __token__
password = pypi-你的测试API令牌重要提示:
- 现在 PyPI 推荐使用 API Token 而不是密码。
- 你可以在 PyPI 官网 -> Account Settings -> API tokens 中生成 Token。
- 为不同的项目生成具有不同权限的 Token 是更安全的做法。
- 配置好后,上传时就不再需要手动输入用户名和密码了。
4.3.2 方法 2:通过环境变量 #
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-你的API令牌
# 然后运行 upload 命令
twine upload dist/*4.3.3 方法 3:直接在命令中指定(不推荐,因为密码会留在 shell 历史中) #
twine upload -u __token__ -p pypi-你的API令牌 dist/*4.4 常用命令和选项 #
twine upload dist/*:上传dist目录下所有文件。twine upload dist/your_package-0.1.0-py3-none-any.whl:只上传指定的文件。--repository-url <url>:上传到自定义的仓库(如私有仓库)。twine upload --repository-url http://company.pypi.com:8080/ dist/*--skip-existing:如果仓库中已存在相同版本的文件,则跳过上传而不是报错。--verbose:显示更详细的输出信息,便于调试。--non-interactive:在自动化脚本(如CI/CD)中使用,确保不会提示输入。
4.5 最佳实践和完整工作流示例 #
假设你有一个名为 awesome_module 的项目,版本是 0.1.0。
- 准备项目:确保
pyproject.toml或setup.py配置正确。 - 清理构建(可选):
rm -rf dist/ build/ *.egg-info/ - 构建分发包:
python -m build - 检查构建的文件(一个好习惯):
tar tzf dist/awesome_module-0.1.0.tar.gz - 上传到 TestPyPI 进行测试:
twine upload --repository testpypi dist/* - 从 TestPyPI 安装测试:
pip install --index-url https://test.pypi.org/simple/ awesome_module - 测试无误后,上传到正式的 PyPI:
twine upload dist/* - 从正式的 PyPI 安装验证:
pip install awesome_module
5. 总结 #
Twine 是 Python 打包生态中一个简单但至关重要的工具。它专注于做好一件事:安全可靠地上传包。记住它的核心工作流程:
代码 -> (Setuptools/build) -> 打包成 dist/.whl 和 .tar.gz -> (Twine) -> 上传到 PyPI