如何打包 Python package 并发布到 PyPi

前段时间为了方便预定学校的羽毛球场,写了一个简单的脚本来自动提交请求。为了方便分发给别人使用,同时保证相对匿名,想了许多方法。最开始专门新建了一个 GitHub 账号,使用匿名 Gist 发布代码。后来发现国内连通性太差,同时更新也不是怎么方便,于是研究了一下如何打包发布到 PyPi,可以更简单地安装和使用。

注册 PyPi 账号

首先前往官网注册一个自己的账号,并生成一个 API Token,记录下来。之后前往 $HOME 目录,新建一个 .pypirc 配置文件,只需要将 password 改为上面 Token 即可。

[pypi]
  username = __token__
  password = <YOUR_TOKEN>

配置包文件

主文件

下面给出一个简单的例子,假定包名(文件夹名)为 example,其中主要文件为 example.py

# example.py
class Example()

    def __init__(self, name):
        print(f'hello {name}!')

def main():
    example = Example('world')

if __name__ == '__main__':
    main()

__init__.py

要想被 python 识别成包,根目录下必须包含 __init__.py 文件。如果之前没有的话,新建一个文件,并导入包即可。

from example import Example, main

__main__.py

如果想要自己的包可以用 python -m your_package 的方式执行,需要添加 __main.py__,即给自己的包增加一个 main 函数。

from example import main

main()

配置 setup.py

下面进入上一层目录,配置打包所需要的 setup.py

from setuptools import setup

setup(
    name='example',
    version='0.0.1',
    python_requires='>=3.6.0',
    author='Editst',
    author_email='editst@example.com',
    url='https://editst.com',
    description='Example Python Package',
    long_description=r'**Example Python Package**',
    long_description_content_type='text/markdown',
    packages=['example'],
    entry_points={
    'console_scripts': ['example=example:main'],
    },
    install_requires=[],
    classifiers=[
    'License :: OSI Approved :: MIT License',

    'Programming Language :: Python :: 3.6',
    'Programming Language :: Python :: 3.7',
    'Programming Language :: Python :: 3.8',
    'Programming Language :: Python :: 3.9',
    ],
)

需要注意的是其中的 entry_points,这个是用来在命令行中执行脚本的,这里我们只需要添加一个 example 即可。安装之后就可以直接在命令行运行 example,就是执行 example.main() 函数。

其中的 classifiers 可以设置包的类别,可以参考这里,比较常用的是指定开源协议和适用的 python 版本。

打包上传

首先需要安装打包和上传所需的工具。

python -m pip install twine wheel setuptools

之后打包上传即可。

python setup.py sdist bdist_wheel
python -m twine upload dist/*

之后就可以在 PyPi 上搜索到我们的包了。