跳到主要内容

从0开始发布一个Python包

注意

该项目使用 GitHub 存储代码并将 Python 软件包发布至 PyPI

此处仅为我发布的经历,不代表对任何人适用。该文档还未包括测试等操作,请等待后续补充。

写代码

首先当然是写好你的代码,我这里使用 Pycharm 来创建项目。

创建项目时,项目目录名命名随意,在此笔记中,我的项目名叫SrunTool

创建虚拟环境

python -m venv venv
./venv/Scripts/active

编写代码

一个最基础的 Python 软件包的目录结构应该是这样的:

SrunTool/  # 项目根目录
├── .gitignore # 忽略文件清单,此清单包含的文件将不会被上传到 GitHub
├── README.md # 基础文档,其内容将展示在 PyPI 上
├── LICENSE # 许可协议
├── src/ # 代码目录
│ └── sruntool/ # 软件包目录
│ ├── __init__.py # 初始化文件,改文件会在导入该软件包时被运行
│ └── srun_operator.py # 主要的代码
└── setup.py # 软件包信息
注意

虽然项目可以随意命名,但软件包的命名尽量保证为**全小写且无下划线**的形式! 比如此处的 sruntool

创建.gitignore文件

用于排除部分不需要上传到GitHub的文件,务必把#以及其后的字符删除

.idea/  # IntelliJ IDEA 的项目文件夹
venv*/ # 虚拟环境文件夹
dist/ # 用于分发软件包的文件夹
build/ # 编译产生的文件夹
*.egg-info/ # Egg 包文件夹

公开接口

在 src/sruntool/__init__.py 中,导入需要公开给外部的接口

from sruntool.SrunOperator import SrunOperator

编写说明文档

在此比较简单的项目中,我只写了 README.md 一份简单的文档。 其中包含了 项目简介、安装方法、使用方法 等信息。

在一些更复杂的项目,你可能需要更丰富的文档。

选择开源许可证

为你的项目选择合适的开源许可证, 并将许可证内容写入LICENSE文件。

填写软件包信息

创建 setup.py 文件,列举软件包的相关信息

样例:https://github.com/pypa/sampleproject/blob/main/setup.py

import pathlib
from setuptools import setup, find_packages

long_description = pathlib.Path("README.md").read_text(encoding='utf-8') # 读取README.md文件内容
setup(
name='sruntool', # 包名
version='0.1.0', # 版本号
author='AkagiYui', # 作者
author_email='akagiyui@yeah.net', # 作者邮箱
description='A library that can operate srun network', # 描述
long_description=long_description, # 将 README.md 内容作为长描述
long_description_content_type='text/markdown',
url='https://github.com/AkagiYui/SrunTool', # 项目地址

packages=find_packages('src'), # 在此目录中寻找软件包
package_dir={'': 'src'},
classifiers=[ # PyPI分类
"Development Status :: 4 - Beta", # 开发进度
"Programming Language :: Python :: 3.9", # 编程语言,可以支持多种
"Intended Audience :: Developers", # 目标用户,可以有多个
"License :: OSI Approved :: MIT License", # 开源许可证
"Operating System :: OS Independent" # 支持系统,这里是不受限于操作系统的
],
python_requires=">=3.7", # Python版本限制
)

发布软件包

构建软件包

pip install twine setuptools wheel
python setup.py sdist bdist_wheel

注册 PyPI 账号

在 PyPI 上注册账号,用于发布软件包。 若看不懂英文,可在网站底部切换到中文。

上传软件包

twine upload dist/*.whl dist/*tar*

此时会要求你输入用户名和密码,输入密码时不会显示内容,直接输入即可。

或者你可以为你的用户名和密码设置环境变量:TWINE_USERNAME 和 TWINE_PASSWORD。

PS E:\AYFiles\Projects\SrunTool> twine upload dist/*.whl dist/*tar*
D:\Environment\Python39\lib\site-packages\requests\__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.9) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: AkagiYui
Enter your password:
Uploading sruntool-0.1.0-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14.7/14.7 kB • 00:01 • ?
Uploading sruntool-0.1.0.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14.0/14.0 kB • 00:00 • ?

View at:
https://pypi.org/project/sruntool/0.1.0/
PS E:\AYFiles\Projects\SrunTool>

此时在 https://pypi.org/project/sruntool/0.1.0/ 即可看到你的软件包。

试用

我们可以尝试下载并使用。

python -m venv venv_test
./venv_test/Scripts/activate
pip install -i https://pypi.org/simple sruntool

由于软件包是刚上传的,其他镜像源可能还没同步,这里用-i指定回pypi.org

(venv_test) PS E:\AYFiles\Projects\SrunTool> pip install -i https://pypi.org/simple sruntool
Collecting sruntool
Downloading sruntool-0.1.0-py3-none-any.whl (10 kB)
Installing collected packages: sruntool
Successfully installed sruntool-0.1.0
from sruntool import get_explain

get_explain(0) # '操作成功'

上传代码

我们可以上传代码到 GitHub 。

  1. GitHub 创建一个仓库。

  2. 将代码上传至 GitHub 。

git init
git add .
git commit -m 'init'
git remote add origin https://github.com/AkagiYui/SrunTool.git
git push

访问 https://github.com/AkagiYui/SrunTool 即可浏览代码。

更新代码与自动发布

自动发布

我们可以使用 GitHub Actions 来自动发布新版本的软件包。

name: Python package build and publish

on:
push:
branches:
- master

jobs:
deploy-linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install twine setuptools wheel
- name: Build source tar
run: |
python setup.py sdist bdist_wheel
- name: Publish wheels to PyPI
continue-on-error: true
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
twine upload dist/*.whl dist/*tar*

对了,你还要给你的仓库设置 secrets 。

比如我的仓库的这里:https://github.com/AkagiYui/SrunTool/settings/secrets/actions

需要设置PYPI_USERNAMEPYPI_PASSWORD两个 secret ,分别对应 PyPI 的用户名与密码。

更新内容

因为我们发布的 Python 软件包可能会被别人使用,所以我们不能直接向master分支推送新的代码,在发布前要经历审核等操作。

写完代码后我们需要发布代码到新分支然后提出 Pull Request

git checkout -b bug_fix  # 创建新分支
git add .
git commit -m '0.1.2'
git push origin bug_fix

上传完代码后就可以在 GitHub 创建 Pull Request 了。