Featured image of post 如何上传Python包到PyPi

如何上传Python包到PyPi

本文介绍了如何使用Python中的setuptools、twine等工具将Python项目打包成wheel文件并上传发布到PyPi。涵盖了环境配置、pyproject.toml编写、元数据配置、wheel文件编译、PyPi账户配置、以及使用twine上传发布等步骤。提供了完整的Python包发布指南。

当我们完成Python项目后,如何将该项目发布到PyPi上呢?下面将介绍如何使用setuptools等工具来实现包编译及上传。

以下教程皆参考自Packaging Python Projects — Python Packaging User Guide

项目结构

我们的项目结构如下所示:

pCIjeRs.png

其中src为我们包源码所在的位置,examples为我们示例代码所在的位置,tests为测试代码所在的位置,其他目录均为生成目录,无需手动生成。

src底下包括我们的eventbus包,注意包的定义是目录下有__init__.py文件。我们在使用时也是导入的src中的包,例如包名为eventbus则会使用import eventbus导入,导入包名和eventbus项目名eventbus-py可以不同。

使用纯净的Python环境来检查项目依赖

一般我们需创建一个全新环境来进行开发,同时为了检查我们的包所需要的依赖项,建议该环境仅用于本项目。常见的虚拟环境搭建我们可以使用condavirtualenv等来进行创建。我们可以使用pip freeze > requirements.txt来将依赖生成到requirements.txt文件中,以备使用。

编写pyproject.toml

pyproject.toml告诉编译工具你将使用什么配置进行编译,官方给的配置如下:

1
2
3
4
5
6
[build-system]
requires = [
    "setuptools>=42",
    "wheel"
]
build-backend = "setuptools.build_meta"

我们参考该配置编写本项目的pyproject.toml

配置元数据

官方推荐使用静态元数据配置文件setup.cfg来进行配置,对于一些场景可以使用动态元数据配置文件setup.py进行配置。这里为了一步到位,我们使用动态配置setup.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name="eventbus-py",
    version="0.0.1",
    author="CycleGen",
    author_email="pypi@cyclegen.cloud",
    description="An eventbus that used for FinanGen",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/cyclegen/eventbus-py",
    project_urls={
        "Bug Tracker": "https://github.com/cyclegen/eventbus-py/issues",
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
        "Natural Language :: Chinese (Simplified)",
    ],
    package_dir={"": "src"},
    packages=setuptools.find_packages(where="src"),
    python_requires=">=3.6",
)

注意我们有一个README.md文件来描述我们的项目,这里直接引入。

下面参数中,name参数比较重要,这个就是我们上传到PyPi后的项目名,我们可以通过pip install {name}来下载该包。

package_dir参数是包名和目录的映射。空包名代表“根包”——项目中包含包的所有 Python 源文件的目录——因此在这种情况下,src 目录被指定为根包。

packages参数是所有应该包含在发行包中的 Python 导入包的列表。我们可以使用 find_packages() 来自动发现package_dir下的所有包和子包,而不是手动列出每个包。在这种情况下,包的列表将是 eventbus,因为那是唯一存在的包。

python_requires 提供了你的项目所支持的 Python 版本。像 pip 这样的安装程序会回顾旧版本的软件包,直到找到一个与 Python 版本相匹配的软件包。

编译whl文件

下载build工具

pip install --upgrade build

进行编译

python -m build

此时会生成dist目录和build目录,如果不上传到PyPi的话,可以直接将dist目录下的.whl文件安装到其他环境中使用(pip install eventbus.whl)。

配置PyPI账户

首先注册Create an account · TestPyPICreate an account · PyPI。前者是测试环境,后者是生产环境。注册后我们需要创建文件来为后续上传做准备。

1
2
3
4
5
6
[pypi]
  username = __username__
  password = __password__
[testpypi]
  username = __username__
  password = __password__

可以将该文件保存为.pypirc。推荐路径为$HOME/.pypirc

上传到PyPi

安装twine

1
pip install --upgrade twine

使用twine上传到对应源

1
python -m twine upload --repository testpypi dist/*

可以看到这里我们使用testpypi源,并且没有指定.pypirc,所以如果没有$HOME/.pypirc的话,会以交互方式让你输入用户名密码后再上传。

也可以指定配置文件:

1
python -m twine upload --repository testpypi dist/* --config-file D:\Projects\test_pypi.pypirc

当上传到生产环境时,去掉repository参数。

1
python -m twine upload dist/* --config-file D:\Projects\test_pypi.pypirc