$ ls ~yifei/notes/

如何发布 Python 代码到 PyPI 上(2018)

Posted on:

Last modified:

PyPI 是 Python 的集中仓库。代码上传到 PyPI 之后,其他人就可以 pip install xxx 你的库了。

Python 的安装工具一直在不断演变,PyPI 的地址也从 pypi.python.org 变到了 pypi.org, 甚至于 setup.py 都不鼓励使用了,因此网上的教程大多数都过时了。官方文档虽然更新及时, 却略过繁琐,这里写一篇简要的教程以飨读者。

本文以作者的库 aioify 为例

文件结构

.
├── LICENSE
├── MANIFEST.in
├── README.md
├── aioify
│   └── __init__.py
├── setup.cfg
├── pyproject.toml
└── setup.py

LICENSE

库的开源协议,建议使用 Apache、MIT 等开放性协议。

MANIFEST.in

打包要包含的文件,Python 文件会自动包括在内,但是 README.md 等可能不包含在内,所以需要 特别注明:

include *.md
include LICENSE

具体语法参见:packaging.python.org/en/latest/guides/using-manifest-in/

aioify

这个是具体的代码的仓库

setup.py

这个文件是整个打包过程的关键所在了。请参考下面的注释

import os
from setuptools import setup

# 可选,读取 README 作为下面的 long_description
here = os.path.abspath(os.path.dirname(__file__))

with open(os.path.join(here, "README.md")) as f:
    long_description = f.read()


setup(
    name = "aioify",   # 包的名字
    packages = ["aioify"],   # 同上
    version = "0.1.3",    # 当前版本
    description = "Make every python function async/await",  # 描述
    long_description = long_description,  # 长描述,会显示在 PyPI 主页上
    long_description_content_type = "text/markdown",  # 长描述的格式,不过好像 markdown 支持还不是很好
    author = "Yifei Kong",  # 作者
    author_email = "kongyifei@gmail.com",  # 作者邮件
    url = "https://github.com/yifeikong/aioify",  # 项目地址
    download_url = "https://github.com/yifeikong/aioify/archive/0.1.3.tar.gz",  # 下载链接,可选
    keywords = ["async", "await", "wrap"],  # 关键词
    # 分类器,可以认为是 PyPI 的一些栏目,建议参考文档填写,可选
    classifiers = [
        "Development Status :: 3 - Alpha",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
    ],
    python_requires=">=3.5"  # 最低 Python 版本
)

本地测试

在项目的根目录,可以使用 pip 安装测试一下,看 setup.py 等文件是否有问题

pip install -e .

-e 的意思是 editable,也就是直接依赖当前文件,编辑后直接生效,而不是另外复制一份到 site-packages 中。

注册账户

在 pypi.org 注册一个账户。另外,在 test.pypi.org 再注册一个测试账户,因为两个站之间是 独立的,所以得注册两次。

配置 .pypirc 文件

打开 ~/.pypirc 输入以下内容:

[distutils]
index-servers =
  pypi
  testpypi

[pypi]
username: 你的用户名
password: 密码

[testpypi]
repository:https://test.pypi.org/legacy/
username: 同上
password: 同上

test.pypi.org 是专门用来在正式上传前测试的服务器,以免操作失误。

打包

打包分为两种,一种是源码包,使用 sdist 命令,一种是二进制包,使用 bdist 命令。

python setup.py sdist/bdist

然后可以看到多出了 dist/ 目录

二机制包与源码包

https://stackoverflow.com/questions/65954466/how-to-release-different-versions-binary-to-pypi-org

上传

pip install twine  # 现在官方推荐使用 twine 工具
twine upload dist/* --repository testpypi

然后到 test.pypi.org/projects/xxx 就可以看到你的代码了~

上传到 pypi 正式服

一切验证无误之后,就可以上传到 PyPI 了:

twine upload dist/*

参考

  1. https://packaging.python.org/tutorials/distributing-packages/
  2. https://packaging.python.org/guides/using-testpypi/
  3. https://bernat.tech/posts/pep-517-and-python-packaging/
  4. A practical guide to setup.py
  5. https://stackoverflow.com/questions/65954466/how-to-release-different-versions-binary-to-pypi-org

© 2016-2022 Yifei Kong. Powered by ynotes

All contents are under the CC-BY-NC-SA license, if not otherwise specified.

Opinions expressed here are solely my own and do not express the views or opinions of my employer.