如何在 PyPI 发布自己的 Python 包

前置条件

  • 拥有 PyPI 账号,若没有,可点击注册

  • 开发机「自己的电脑」安装 Twine

pip install twine

正式开始

代码目录结构

my_pkg 是一个正常编写的 Python 包

.
├── my_pkg
│   ├── __init__.py
│   └── my_function.py
├── setup.py
└── README.md

有些包在安装之后会自动生成一个可执行命令,如 pip install twine 之后,就可以直接在命令行使用 twine 命令,想要达到这种效果可以在 Python 包中增加一个 py

.
├── my_pkg
│   ├── __init__.py
│   ├── my_cmd.py            # 若想在安装的时候自动生成一个可执行命令,则可增加一个方法
│   └── my_function.py
├── setup.py
└── README.md

编写 setup.py

setup.py 是关键,附上我自用的样本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from setuptools import find_packages, setup
import os

# 提供一些有用的信息
URL = 'https://github.com/seoktaehyeon/api-test-framework'    # 通常会附上 GitHub 地址
NAME = 'ApiTestFramework'                                     # Python 包的名称,即在 pip install 时后面跟的包名
VERSION = '0.1.1'                                             # 包的版本,每次上传到 PyPI 都需要改变这个版本号,否则只会往存储空间增加新内容,无法达到预期
DESCRIPTION = 'Api test framework in Linux'                   # 关于该包的剪短描述
if os.path.exists('README.md'):                               # 如果需要,可以加入一段较长的描述,比如读取 README.md,该段长描述会直接显示在 PyPI 的页面上
    with open('README.md', encoding='utf-8') as f:
        LONG_DESCRIPTION = f.read()
else:
    LONG_DESCRIPTION = DESCRIPTION
AUTHOR = 'Will'                                               # 留下大名
AUTHOR_EMAIL = '[email protected]'                              # 留下邮箱
LICENSE = 'MIT'                                               # 定义合适自己的许可证,实在不知道,那就 MIT 吧
PLATFORMS = [                                                 # 支持的平台,如果所有平台都支持,可以填 all
    'linux',
]
REQUIRES = [                                                  # 很多时候,我自己写的包都要依赖第三方,所以可以把依赖包定义在这里,这样的 pip install 自己包的时候,顺便把这些依赖包都装上了
    'PyYAML>=5.2',
    'requests>=2.22.0',
    'pytest>=5.3.2',
    'pytest-html>=2.0.1',
]
CONSOLE_SCRIPT = 'my-cmd=my_pkg.my_cmd:main'                  # 如果想在 pip install 之后自动生成一个可执行命令,就靠它了: 
                                                              # =.:
                                                              # 值得注意的是:
                                                              # python_file_name 是不能用"-"的,需要用"_",但 command 可以用"-"
                                                              # my_cmd.py 也很简单,正常写即可,方法名也不一定是 main

# 需要的信息就在 setup() 中加上,不需要的可以不加
setup(
    name=NAME,
    version=VERSION,
    description=(
        DESCRIPTION
    ),
    long_description=LONG_DESCRIPTION,
    long_description_content_type='text/markdown',
    author=AUTHOR,
    author_email=AUTHOR_EMAIL,
    maintainer=AUTHOR,
    maintainer_email=AUTHOR_EMAIL,
    license=LICENSE,
    packages=find_packages(),
    platforms=PLATFORMS,
    url=URL,
    install_requires=REQUIRES,
    entry_points={
        'console_scripts': [CONSOLE_SCRIPT],
    }
)

打包

利用 setuptools 打包

  • sdist —— Source Distribution
  • bdist_wheel —— Wheel Binary Distribution
python setup.py sdist bdist_wheel

上传

利用 twine 上传打包的好的文件,使用 twine 时候,会提示要求输入 PyPI 的帐密

twine upload dist/*
#Uploading distributions to https://upload.pypi.org/legacy/
#Enter your username: 
#Enter your password: 

成果展示

我的第一个 PyPI 包,安装完 ApiTestFramework 之后,会生成一个 atf-exec 命令

/ # pip install ApiTestFramework
Collecting ApiTestFramework
  Downloading https://files.pythonhosted.org/packages/96/e5/110573cf2652e852a9cd513623ddbf1c710ddd55442831d824b0f27820ae/ApiTestFramework-0.1.1-py3-none-any.whl
Collecting PyYAML>=5.2 (from ApiTestFramework)
  Downloading https://files.pythonhosted.org/packages/8d/c9/e5be955a117a1ac548cdd31e37e8fd7b02ce987f9655f5c7563c656d5dcb/PyYAML-5.2.tar.gz (265kB)
     |████████████████████████████████| 266kB 8.0kB/s
Collecting requests>=2.22.0 (from ApiTestFramework)
  Downloading https://files.pythonhosted.org/packages/51/bd/23c926cd341ea6b7dd0b2a00aba99ae0f828be89d72b2190f27c11d4b7fb/requests-2.22.0-py2.py3-none-any.whl (57kB)
     |████████████████████████████████| 61kB 18kB/s
Collecting pytest-html>=2.0.1 (from ApiTestFramework)
  Downloading https://files.pythonhosted.org/packages/f9/8d/c79a92919ada2986f6dab1bc7cf7ba86160c513cb8aa254ad0e2f940f96a/pytest_html-2.0.1-py2.py3-none-any.whl
Collecting pytest>=5.3.2 (from ApiTestFramework)
......
Installing collected packages: PyYAML, idna, certifi, chardet, urllib3, requests, six, pyparsing, packaging, py, wcwidth, more-itertools, zipp, importlib-metadata, attrs, pluggy, pytest, pytest-metadata, pytest-html, ApiTestFramework
Successfully installed ApiTestFramework-0.1.2 PyYAML-5.2 attrs-19.3.0 certifi-2019.11.28 chardet-3.0.4 idna-2.8 importlib-metadata-1.3.0 more-itertools-8.0.2 packaging-19.2 pluggy-0.13.1 py-1.8.0 pyparsing-2.4.5 pytest-5.3.2 pytest-html-2.0.1 pytest-metadata-1.8.0 requests-2.22.0 six-1.13.0 urllib3-1.25.7 wcwidth-0.1.7 zipp-0.6.0
/ # atf-exec
Usage: atf-exec option
option:
    init    Init framework
    prepare Generate test case in test_case dir and data template in data_template dir
    run     Run test case
    clean   Clean up workspace
/ #

你可能感兴趣的:(如何在 PyPI 发布自己的 Python 包)