前述
不少人应该对 Python 打包心存阴影, 不同于 Go 与 Rust 在项目打包时的快感, Python 的打包系统和依赖管理比较复杂, setup.py, requirements.txt, setup.cfg, MANIFEST.in, Pipfile and Pipfile.lock (pipenv) 等诸多文件需要我们考虑 (https://learnku.com/python/t/38708).
那么有没有 all-in-one 的项目打包工具呢? 这里我使用 poetry 满足了这个需求.
本文将介绍使用 poetry 打包项目并发布到 PyPI 的过程, 以我自用的 lk-utils 为例进行讲解.
本方法在 2020年8月8日 测试可行, 以下是本人完整的实现流程.
准备
- 我的项目结构如下:
D:\workspace\lk-utils
|- changelog # 这里存放了我的更新日志文件.
|- lk_utils # 这是我要打包的模块主体.
|- resources # 我的项目中用到了一些资源文件, 传统的打包方式会有诸多细节要注
| # 意; 不过使用 poetry 就简单得多了, 后面会讲到.
|- __init__.py
|- lk_logger.py
|- ...
|- README.md # 自述文档.
-
由于我访问 pypi 仓库速度慢 (有时候会超时), 所以我使用了清华镜像 (https://pypi.tuna.tsinghua.edu.cn/simple/).
-
poetry 模块已通过
pip install poetry
安装.
Poetry Init
在命令行终端, 输入 poetry init
:
在命令行中, poetry 会出现引导信息, 需要和你交互确认:
> This command will guide you through creating your pyproject.toml config.
> Package name [lk-utils]: lk-utils # 这里我填写项目名为 "lk-utils", 在上传到 pypi 后, 可通过 `pip install lk-utils` 安装此模块.
> Version [0.1.0]: 1.2.11 # 留空的话, 则会使用中括号里的缺省值.
> Description []: # 我没有填写项目描述, 所以回车跳过. (后期是可修改的)
> Author [Likianta <likianta@foxmail.com>, n to skip]: # 同样回车使用缺省值.
> License []: MIT
> Compatible Python versions [^3.8]: ^3.6 # 假设支持 Python 3.6 以上版本.
> Would you like to define your main dependencies interactively? (yes/no) [yes]: no # 这一步询问我们是否现在填写项目依赖, 考虑到 poetry 默认查询的是 pypi 仓库, 很容易访问不了或连接超时 (然后就会报错中断). 所以我们填 no 先跳过.
> Would you like to define your development dependencies interactively? (yes/no) [yes]: no # 这一步询问我们是否现在填写开发时依赖, 同样填 no 跳过.
> Do you confirm generation? (yes/no) [yes]: yes # 至此, 引导操作完成.
(注: 如对上述命令有不清楚的地方, 比如为什么缺省的版号是从 “0.1.0” 开始, “^3.6” 的尖角符号是什么意思等, 欢迎阅读 初次使用 python poetry 包管理模块踩坑 一文了解.)
根据 poetry 的引导完成操作后, 在项目目录下会出现一个 “pyproject.toml” 文件:
toml 文件是一个配置文件 (类似于 json, yaml). 接下来我们要在 toml 文件中配置清华镜像和项目依赖.
编辑 pyproject.toml 配置
[tool.poetry]
name = "lk-utils"
version = "0.1.0"
description = ""
authors = ["Likianta <likianta@foxmail.com>"]
license = "MIT"
# 添加清华镜像
[[tool.poetry.source]]
name = "tsinghua"
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple/"
default = true # 设置清华镜像为默认回调, 以避免 poetry 在某些缺省操作里又回调到 pypi 仓库.
# 在这里添加项目依赖.
# 1. 我没研究清楚 poetry 如何自动解析项目依赖 (听说 poetry 的解析很慢), 所以这些依赖是我人眼过了一遍项目源码后自己加的.
# 2. 只需要添加自己 `import` 时引用了哪些第三方依赖, 不需要写明依赖的依赖.
# 3. 版本号规则:
# 3.1. "^2.24.0" 表示 "2.24.0 ~ 3.0.0" 区间 (左边是大于等于, 右边是小于).
# 3.2. "~2.24.0" 表示 "2.24.0 ~ 2.25.0" 区间 (左边是大于等于, 右边是小于).
# 3.3. "*" 表示任意版本号, poetry 会优先选取最新版.
# 3.4. 更多规则请见 https://python-poetry.org/docs/dependency-specification/#version-constraints
# 4. 有些依赖虽然用到了, 但我没写进去, 一是因为这些依赖只在特定的方法中才被调用了一两次, 二是为了瘦身考虑.
[tool.poetry.dependencies]
python = "^3.6"
bs4 = "^0.0.1"
lxml = "^4.5.0"
requests = "^2.24.0"
xlrd = "^1.2.0"
xlsxwriter = "^1.2.7"
# csv = "*"
# pdfminer = "*"
# pdfplumber = "*"
# pypinyin = "*"
# 在这里添加项目开发时依赖.
[tool.poetry.dev-dependencies]
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
PS: 如果你不确定版本号具体是多少, 可以通过 poetry update
来自动检查并更新 pyproject.toml 的依赖版本到最新.
Poetry Install (非必须, 可跳过此节)
运行 poetry install
, 可生成 “poetry.lock” 文件. “poetry.lock” 对于发布到 pypi 的模块来说不是必须的, 如需了解请阅读: https://python-poetry.org/docs/basic-usage/
Poetry Build
在发布到 pypi 之前, 我们需要先运行一下 poetry build
. 此时项目目录下会生成 dist 文件夹:
D:\workspace\lk-utils
|- changelog
|- dist # 生成了 dist 文件夹
|- lk-utils-1.2.11.tar.gz
|- lk_utils-1.2.11-py3-none-any.whl
|- lk_utils
|- pyproject.toml
|- README.md
Poetry Publish
运行 poetry publish
, 输入账户密码即可上传项目到 PyPI 仓库.
登录 pypi 网站 (https://pypi.org/), 你可以在 “Your Projects” 中查看:
相关阅读
- Poetry 官方文档, 写得清晰易懂, 推荐阅读: https://python-poetry.org/docs
- 其他人写的 Poetry 打包教程: https://learnku.com/python/t/38708
- 国外有人写的 Poetry 打包教程: https://www.infoworld.com/article/3527850/how-to-manage-python-projects-with-poetry.html
- 传统的打包发布: https://www.jianshu.com/p/eb7caacf7491