发布自己的 python 包到 Pypi

发布自己的 python 包到 Pypi (Distributing Python Modules)

参考: section-build-and-publish

将要发布的包的目录结构如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
╰─➤  tree cocotbext-plotData
cocotbext-plotData
├── cocotbextPlotData
│   ├── __init__.py
│   ├── plotData.py
│   ├── README.org
│   └── sarasa-mono-sc-regular.ttf
└── pyproject.toml

3 directories, 8 files

真正要安装到 site-packages 的是cocotbextPlotData, 这个目录名字不能有特殊符号如 -, 否则 import 的时候会报错
可以看到不需要 setup.py 不需要 setup.cfg, 也不需要 MANIFEST.in, 只需要一个 pyproject.toml 即可

pyproject.toml

这是构建包的配置文件, 内容如下:
关于如何编写 pyproject.toml 可以参考 writing-pyproject-toml

 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
28
29
30
31
32
33
34
35
36
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "cocotbextPlotData"
version = "0.1"
description = "plot sim data by dearpygui"
authors = [{name = "skfwe", email = "wcq-062821@163.com"},]
readme = {file = "README.md", content-type = "text/markdown"}
keywords = ["cocotb", "plot"]
dependencies = [
    "dearpygui",
]
requires-python = ">= 3.8"
classifiers = [
  "Development Status :: 4 - Beta",
  "Programming Language :: Python"
]

[project.urls]
Homepage = "https://example.com"
Documentation = "https://readthedocs.org"
Repository = "https://github.com/me/spam.git"
Issues = "https://github.com/me/spam/issues"
Changelog = "https://github.com/me/spam/blob/master/CHANGELOG.md"

[tool.setuptools]
# ...
# By default, include-package-data is true in pyproject.toml, so you do
# NOT have to specify this line.
include-package-data = true

[tool.setuptools.package-data]
# "*" = ["*.org", "*.ttf"]
cocotbextPlotData = ["*.md", "*.ttf"]

build-system

这一项指定编译工具, 这里选择 setuptools, 除了这个还可以选择 Hatchling, Flit, PDM

project

这一项主要指定项目相关的内容
其中 readme 只支持三种格式(.md, .rst, .txt), 并不支持orgmode 格式

description 只支持短的, 不支持long description 即在PYPI 主页显示包的时候没有长的说明

project.urls

这一项指定链接, 这样在pypi 页面可以直接跳转到你的个人仓库

tool.setuptools

setuptools 的配置

tool.setuptools.package-data

添加资源文件
cocotbextPlotData = [".org", “.ttf”]
的意思是把cocotbextPlotData 文件夹下的所有 .org 和 所有 .ttf 加入到资源文件列表,
这样在install 的时候会把这些资源文件也一起拷贝到包内
参考: datafiles

更多配置可以参考 https://setuptools.pypa.io/en/latest/userguide/quickstart.html

包内容

__init__.py

这个文件可以是空的, 也可以加入一些信息如 version=“V0.1”

plotData.py

主程序

README.org

sarasa-mono-sc-regular.ttf

这是字体文件, 即资源文件, 如果python 包中没有用到, 可以不要

构建包

本地安装

1
2
3
4
cd cocotbext-plotData
pip3 install . --user
或者 
pip3 install . --user --break-system-packages

本地可编辑安装

1
2
3
4
cd cocotbext-plotData
pip3 install -e . --user
或者
pip3 install -e . --user --break-system-packages

这种安装方式相当于在site-packages 内建了个软链接

测试

1
2
python3
>>> from cocotbextPlotData import plotData

发布到 test Pypi

注册pypi

https://test.pypi.org/account/register/ 注册登录
注册完还要生成 recover code 和激活 2FA 才能生成 api token

  • test pypi recover code

    如果忘记密码, 可以使用上面任意一个来重新登录

  • 添加 ~/.pypirc 文件

    里面填入

    1
    2
    3
    
    [testpypi]
      username = __token__
      password = api_token
    

    password 里面填入api token, 这样使用 twine 上传包时就不需要手动输了

安装 twine

1
2
3
pip3 install twine --user
或者
pip3 install twine --user --break-system-packages

这个用于把本地编译好的包上传到 Pypi

安装 build

1
2
3
pip3 install build --user
或者
pip3 install build --user --break-system-packages

这个用于把包编译成二进制

编译二进制

1
2
cd cocotbext-plotData
python3 -m build

这会生成 dist 文件夹

发布

1
2
cd cocotbext-plotData
twine upload --repository testpypi dist/*

在testpypi 网页上可以看到

测试安装

1
2
3
pip3 install --index-url https://test.pypi.org/simple/ cocotbextPlotData
或者
pip3 install --index-url https://test.pypi.org/simple/ cocotbextPlotData --break-system-packages

发由到 PyPi

Pypi 的 Recover code 如下:

修改 ~/.pypirc

添加以下内容

1
2
3
[pypi]
  username = __token__
  password = api_token

编译二进制

1
2
cd cocotbext-plotData
python3 -m build

发布

1
2
cd cocotbext-plotData
twine upload dist/*

这时已经可以在 PyPi 看到包了, 但是还搜不到, 不清楚啥情况, 可能是延时?

  • yank release

    Yank 之后就可以通过 ==0.1 这样的方式来安装特定版本了

测试安装

其中的pip3iu 是我写的一个函数, 相当于 pip3 install xxx -user