【译】Python 发布包

《翻译-Python 发布包》,原文地址:https://packaging.python.org/tutorials/packaging-projects/

这篇指南向您介绍如何打包一个简单的 python 工程,内容包含包的目录结构以及需要添加哪些必要的文件。怎样编译包?以及怎样将包上传到 pypi 公共仓库。

一个简单的项目

现有一个叫做 example_pkg的包需要发布。如果您已经拥有一个需要打包的工程,我们建议向如下的目录结构去规整您的工程。

packaging_tutorial
└── example_pkg
    └── __init__.py

一旦按照如上的目录结构创建项目,接下来所有在命令行运行的指令只需切换到根目录下即可,即——$ cd packaging_tutorial

创建包文件

现在你需要创建一些文件,为发布包做准备。你需要将它们放在根目录下,暂时可以创建空文件,内容待会填充。

packaging_tutorial
├── LICENSE
├── README.md
├── example_pkg
│   └── __init__.py
├── setup.py
└── tests

创建测试文件夹

tests/ 目录用于单元测试,暂时先让它空着吧。

创建 setup.py 文件

setup.py是 setuptools 工具的构件脚本,它会告诉 setuptools 包的一些基础信息以及包含哪些文件。

打开 setup.py 文件然后写入如下内容。您需要替换一些信息,主要是包名,确保不会和 Pypi 公共仓库现有的包名冲突。

import setuptools

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

setuptools.setup(
    name="example-pkg-YOUR-USERNAME-HERE", # 替换成您的包名,由字母、数字、-、_组成
    version="0.0.1",
    author="Example Author",
    author_email="author@example.com",
    description="A small example package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/pypa/sampleproject",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

创建 README.md 文件

打开 README.md 文件,写入如下内容:

# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

创建 LICENSE 文件

每一个上传到 Pypi 的包都需要证书,这将告诉那些安装您包的用户,应当在什么样的情况下可以正常使用您的包。

您可以在 https://choosealicense.com/ 网站上选择合适的证书,一旦你确定了哪种证书,打开 LICENSE 文件然后写入内容。

这里假设您选择的 MIT 证书,写入如下内容:

Copyright (c) 2018 The Python Packaging Authority

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.

打包

接下来就是生成打包产物了,打包产物将会被上传到 Pypi 公共仓库,并可以通过 pip 安装到本地。

确保您已经安装了最新版本的 setuptoolswheel,如果没有,执行以下命令:

$ python3 -m pip install --user --upgrade setuptools wheel

运行命令进行打包:

$ python3 setup.py sdist bdist_wheel

这条命令会在终端输入一些内容以及在根目录下生成 dist 目录:

dist/
  example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
  example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz

上传打包产物

最后,您需要将打包产物上传到 Pypi 公共仓库。

您需要做的第一件事就是在 Test PyPI网站注册一个账号,Test PyPI 和 PyPI 是两个独立的网站,它主要用于测试和实验,并不会将包上传到正式的 Pypi 仓库。

前往 https://test.pypi.org/account/register/ 网页,注册一个账号,您需要填写一些基础信息,并验证邮箱。

当您注册完成后,前往 https://test.pypi.org/manage/account/#api-tokens 网页创建 API TOKEN ,这用于上传包时的身份校验。在上传包整个流程完成之前不要关闭创建 token 页面。

确保您已经安装了最新版本的 twine ,如果没有的话,执行以下命令:

$ python3 -m pip install --user --upgrade twine

使用 twine命令上传你的包:

$ python3 -m twine upload --repository testpypi dist/*

终端会让您输入 usernmae 和 password。username 请输入 __token__ 字符串,password 请粘贴刚才的 token 值

(您粘贴过密码后可能会发现 password 后面是空的,不用担心,这出于安全考虑,密码一般不显示,但已经粘贴上了,回车即可)。

Uploading distributions to https://test.pypi.org/legacy/
Enter your username: [your username]
Enter your password:
Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s]
Uploading example_pkg_YOUR_USERNAME_HERE-0.0.1.tar.gz
100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]

上面的步骤执行完成后,您可以访问 https://test.pypi.org/project/example-pkg-YOUR-USERNAME-HERE 查看上传到测试仓库的包。

安装上传的包

现在,使用 pip 安装刚刚上传的包,在本地测试下它是否功能正常吧。

创建虚拟环境:

$ mkdir test-pkg                                # 创建测试目录
$ cd test-pkg
$ $ python -m venv .venv        # 创建虚拟环境     
$ source .venv/bin/acticate         # 激活虚拟环境 

将下面这条命令中 example-pkg-YOUR-USERNAME-HERE 替换为你的包名。

python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg-YOUR-USERNAME-HERE

pip 会自动安装包,终端会输出如下信息:

Collecting example-pkg-YOUR-USERNAME-HERE
  Downloading https://test-files.pythonhosted.org/packages/.../example-pkg-YOUR-USERNAME-HERE-0.0.1-py3-none-any.whl
Installing collected packages: example-pkg-YOUR-USERNAME-HERE
Successfully installed example-pkg-YOUR-USERNAME-HERE-0.0.1

您可以在 python 解释器或其它方式测试包的功能是否正常。

$ python
>>> import example_pkg

上传到 PyPI 正式环境

恭喜!您已经完成了打包以及发布到仓库整个流程。

不要忘记,这份指南只是教你将包发布到了 Test PyPI 测试仓库,而不是 PyPI 公共仓库。当您测试完成,确保包的功能性无误后可以将包上传到正式仓库,可以参考本指南,仅有几点需要注意:

  • 选择一个易记且独一无二的包名。
  • https://pypi.org 网站注册用户。
  • 使用 twine upload dist/* 上传包到公共仓库时,输入 pypi.org 网站的用户名和密码,并且不需要指定 --repository 参数,包将会被上传到 PyPI 正式仓库。
  • 安装包将变得更加简单,只需要 $ pip install [your-package]