poetryでPyPIにPublishする
はじめに
2023年のPython環境構築: pyenv + poetryを書いた当時はPyPIにライブラリを公開することがほとんどなかったので、publishについては意図的に省いていた。 最近やってみると予想外に簡単だったので小物をどんどん公開するようにしている。この記事では私のいつものフローについて解説する。
プロジェクト作成
ライブラリなので、他のプロジェクトにimportして便利に使えるような機能を考える。 今回はClojureの ->>(thread-last) をPythonで実装して公開するライブラリを作ってみることにした。
mkdir python-thread-lastcd python-thread-lastpoetry init
poetry init
のプロンプトは以下の通り。
もし私の様にフォルダ名に python-
という接頭辞を付けたなら Package name
のところで python-
という接頭辞を削ること。
This command will guide you through creating your pyproject.toml config.
Package name [python-thread-last]: thread-lastVersion [0.1.0]:Description []: thread-last for PythonAuthor [Naoya Yamashita <conao3@gmail.com>, n to skip]:License []: Apache-2.0Compatible Python versions [^3.11]: ^3.12
Would you like to define your main dependencies interactively? (yes/no) [yes]You can specify a package in the following forms: - A single name (requests): this will search for matches on PyPI - A name and a constraint (requests@^2.23.0) - A git url (git+https://github.com/python-poetry/poetry.git) - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop) - A file path (../my-package/my-package.whl) - A directory (../my-package/) - A url (https://example.com/packages/my-package-0.1.0.tar.gz)
Package to add or search for (leave blank to skip):
Would you like to define your development dependencies interactively? (yes/no) [yes]Package to add or search for (leave blank to skip):
Generated file
[tool.poetry]name = "thread-last"version = "0.1.0"description = "thread-last for Python"authors = ["Naoya Yamashita <conao3@gmail.com>"]license = "Apache-2.0"readme = "README.md"packages = [{include = "thread_last"}]
[tool.poetry.dependencies]python = "^3.12"
[build-system]requires = ["poetry-core"]build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes]
おまじないファイル作成
おまじない的に必要なファイル群を作成する。
もし私の様に -
が含まれるパッケージ名にした場合は _
に置換してフォルダを作成する。
mkdir -p src/thread_lasttouch src/thread_last/__init__.pytouch src/thread_last/lib.pyecho '# python-thread-last' >> README.mdcurl https://www.apache.org/licenses/LICENSE-2.0.txt > LICENSEecho '.venv' >> .gitignoreecho '__pycache__' >> .gitignoreecho 'dist' >> .gitignore
pyproject.tomlの編集
これで poetry install
ができる。。はずなのだが、 src
というフォルダを掘っているせいでpyproject.tomlと整合性が合わなくなっているので修正する。
diff --git a/pyproject.toml b/pyproject.tomlindex f70b45c..a1e31ba 100644--- a/pyproject.toml+++ b/pyproject.toml@@ -5,7 +5,7 @@ description = "thread-last for Python" authors = ["Naoya Yamashita <conao3@gmail.com>"] license = "Apache-2.0" readme = "README.md"-packages = [{include = "thread_last"}]+packages = [{include = "src/thread_last"}]
[tool.poetry.dependencies] python = "^3.12
poetry install
poetry install
でvenvの作成、インストールを一発でやってくれる。
プロジェクトに問題がなければ成功するはず。
$ poetry installThe currently activated Python version 3.11.2 is not supported by the project (^3.12).Trying to find and use a compatible version.Using python3 (3.12.0)Creating virtualenv thread-last in /home/conao/dev/repos/python-thread-last/.venvInstalling dependencies from lock file
Installing the current project: thread-last (0.1.0)
実装
以下の内容を src/thread_last/lib.py
に保存する。
(型は諦めました。誰か強い人教えて下さい)
import functoolsfrom typing import Any, Callable
def thread_last(x: Any, *fns: Callable[[Any], Any]) -> Any: return functools.reduce(lambda v, f: f(v), fns, x)
publish
いよいよpublishです。
(--build
は poetry build
をpublishの直前に実行してくれるオプション)
poetry publish --build
表示は以下の通り。
Building thread-last (0.1.0) - Building sdist - Built thread_last-0.1.0.tar.gz - Building wheel - Built thread_last-0.1.0-py3-none-any.whl
Publishing thread-last (0.1.0) to PyPI - Uploading thread_last-0.1.0-py3-none-any.whl 100% - Uploading thread_last-0.1.0.tar.gz 100%
公開できた。thread-last - PyPI
使ってみる
時間切れ。また後で追記します。
Appendix
- なぜ
src
というフォルダを掘るのか: Good Integration Practices