学会如何制作 python 包后,如果你觉得自己开发的模块需要共享给其他人,可以把 Python 包发布到 Pypi(
Python Package Index)。Pypi 类似于 Java 的 maven 仓库。
注册账号
到下面两个地址注册账户:
配置
分别获取 PyPI token 参考 https://pypi.org/help/#apitoken。
创建 ~/.pypirc 文件,此文件中配置 PyPI 访问地址和账号。配置示例:
[server-login]
username = xiexianbin
password = password
[pypi]
username = __token__ # 必须配置为 __token__,参考 https://pypi.org/help/#invalid-auth
password = <user password> # 官方说要使用 token,实际使用密码成功通过 setup.py 上传
以 Pecan 使用介绍 为例,修改 setup.py
setup(
...
author='xiexianbin',
author_email='me@xiexianbin.cn',
url='https://www.xiexianbin.cn',
...注册项目
到项目根目录下,执行如下命令进行项目信息注册:
$ python3 setup.py check
$ python3 setup.py register
running register
running check
We need to know who you are, so please choose either:
1. use your existing login,
2. register as a new user,
3. have the server generate a new password for you (and email it to you), or
4. quit
Your selection [default 1]:
1
Username: xiexianbin
Password:
Registering test_pecan to https://upload.pypi.org/legacy/
Server response (410): Project pre-registration is no longer required or supported, upload your files instead.上传源码
$ python3 setup.py sdist upload通过 twine 上传
twine 是一个专门用于与 pypi 进行交互的工具。
安装
pip3 install twine注册项目
到项目根目录下,执行如下命令进行项目信息注册:
twine register dist/xxx.whl检查
twine check dist/*上传源码
twine upload dist/*
twine upload -r devpi dist/*
# 用户名密码在命令行,或者使用 TWINE_USERNAME、TWINE_PASSWORD
twine upload --repository-url http://10.10.10.10:3141/xianbin/dev/ -u xianbin -p your_password dist/*至此,源码包已经上传完毕。
devpi 上传
配置 ~/.pypirc
[distutils]
index-servers =
devpi
[devpi]
# 注意:URL 结尾最好加上斜杠 /
repository = http://10.10.10.10:3141/xianbin/dev/
# 必须提供对 xianbin/dev 有上传权限的用户名(通常是 xianbin 本身)
username = xianbin
# 对应的密码
password = your_password_here示例
- source code: https://github.com/x-actions/python3-cisctl
- pypi: https://pypi.org/project/python3-cisctl/
python 包命令总结 python3-cisctl==1.1.0 vs python3_cisctl-1.1.0-py3-none-any.whl
| 应用场景 | 具体名称示例 | 包名中的分隔符 | 原因与底层规范说明 |
|---|---|---|---|
| 项目注册名 ( setup.py / pyproject.toml) |
name="python3-cisctl" |
中划线 (-) |
开发者定义项目的官方名称。社区约定俗成多采用中划线,方便人类阅读。 |
| 依赖声明与安装 ( requirements.txt / pip install) |
pip install python3-cisctl==1.1.0 |
中划线 (-)(推荐) |
遵循官方名称。根据 PEP 503 规范,pip 在检索时会进行标准化,视 - 和 _ 为等价。所以写下划线也能装,但推荐中划线。 |
| 二进制安装包文件名 (Wheel 文件) |
python3_cisctl-1.1.0-py3-none-any.whl |
下划线 (_) |
根据 PEP 427 规范,.whl 文件名强制用中划线 - 来切割包名、版本号等 5 个部分。为了防止解析器混淆,包名和版本号内部原有的中划线必须替换为下划线。 |
| 代码导入模块名 (Python 代码文件内) |
import python3_cisctl |
下划线 (_) |
Python 语法限制。在 Python 中,中划线 - 是减号(数学运算符),不能用于变量名或模块名。因此文件夹名(模块名)必须使用下划线。 |
根据 Python 官方规范(PEP 503),pip 在解析包名时会进行**名称标准化(Normalization)。它会把包名转换为小写,并且把所有的中划线 (-)、下划线 (_) 和点 (.) 都视为等价的**。
所以,即使你在 requirements.txt 里写:
python3-cisctl==1.1.0python3_cisctl==1.1.0python3.cisctl==1.1.0PYTHON3_CISCTL==1.1.0
pip install -r requirements.txt 时,pip 都会去寻找名为 python3-cisctl 的包,结果完全一样。
深度解析 .whl 文件名中的-与_
仔细观察你的 Wheel 文件名:
python3_cisctl-1.1.0-py3-none-any.whl
- 包名内部必须是
_:开头的python3_cisctl是包名,原来的-变成了_。 - 各个部分之间必须是
-:包名(python3_cisctl) 和 版本号(1.1.0) 之间,必须用-隔开。如果包名自身保留了-(变成python3-cisctl-1.1.0...),安装工具就不知道哪里是包名结束,哪里是版本号开始了。
极简记忆法则
- 对外(给人看、用工具装) 用 中划线
-(pip install python3-cisctl) - 对内(给机器看、写代码用) 用 下划线
_(import python3_cisctl,打出的.whl包名)
FAQ
Invalid or non-existent authentication
$ python3 setup.py sdist upload
...
running upload
Submitting dist/xxx-0.1.tar.gz to https://upload.pypi.org/legacy/
Upload failed (403): Invalid or non-existent authentication information. See https://pypi.org/help/#invalid-auth for more information.
error: Upload failed (403): Invalid or non-existent authentication information. See https://pypi.org/help/#invalid-auth for more information.修复方式:
在 ~/.pypirc 文件,添加如下配置:
[server-login]
username = xiexianbin
password = passwordInvalid value for blake2_256_digest
$ python3 setup.py sdist upload
...
running upload
Submitting dist/test_pecan-0.1.tar.gz to https://upload.pypi.org/legacy/
Upload failed (400): Invalid value for blake2_256_digest. Error: Use a valid, hex-encoded, BLAKE2 message digest.
error: Upload failed (400): Invalid value for blake2_256_digest. Error: Use a valid, hex-encoded, BLAKE2 message digest.