Open30

poetryを使ってpythonパッケージを作成する

shotakahashotakaha

poetry new

新規にパッケージを作成する場合は poetry newする

poetry new
$ poetry new poetry-demo
$ tree poetry-demo/
poetry-demo/
├── README.rst
├── poetry_demo
│   └── __init__.py
├── pyproject.toml
└── tests
    ├── __init__.py
    └── test_poetry_demo.py
  • poetry-demoというディレクトリが作成される
  • その下にパッケージ用(poetry_demo)とテスト用(tests)のディレクトリが作成される。パッケージ名の - は自動的に _ に変換されるみたい
  • README.rstが空の状態で作成される。README.mdに変更してもよい
  • pyproject.tomlが作成される。今後いろいろ変更を追加していく設定ファイル
shotakahashotakaha

Gitを使ったファイル管理

  • 当たり前だけど poetrygit は独立したツール
  • gitを使ったファイル管理をしたい場合は、プロジェクトルートで git initする必要がある
shotakahashotakaha

poetry init

既存のディレクトリをpoetryでパッケージ化する場合は poetry init する

poetry init
$ cd ディレクトリ名
$ poetry init

This command will guide you through creating your pyproject.toml config.
  • pyproject.toml を作成するためのダイアログが表示されるので、聞かれたことに従って内容を入力する。pyproject.tomlの内容は、あとで直接編集できるので、間違えてしまっても気にしなくてよい。
  • ディレクトリの構造は poetry new した時のディレクトリ構造と同じになっているとよい
shotakahashotakaha
rye init
$ cd ディレクトリ名
$ rye init
  • 同じようにrye initできる
  • すでにpyproject.tomlが存在していると失敗するため、poetryと共存させるのは簡単ではなさそう
shotakahashotakaha

poetry add

パッケージの動作に必要な外部パッケージをインストールする場合は poetry add する

poetry add
$ poetry add pandas
$ poetry add plotly
$ poetry add kaleido==0.2.1
  • 仮想環境に外部パッケージがインストールされる
    • poetry.lockが作成される
  • pyproject.toml[tool.poetry.dependencies]セクションにパッケージ名が追加される
    • 基本的に最新のバージョンが追加される
    • バージョンを指定して追加することもできる
  • 開発時にしか使わないモジュールは poetry add -Dを使う
shotakahashotakaha

poetry add -D

個人開発の場合、開発時の依存パッケージはわざわざ追加しなくてもいいのかも?

例えば JupyterLabSphinxは、さまざまなパッケージの開発時に必要になることが多いが、それぞれのパッケージの仮想環境にインストールするよりも、pip3でシステムにインストールしておけば十分かもしれない。

このあたりの塩梅はよく分かってない。

shotakahashotakaha
  • v1.2.0以降でpoetry add -Dしたら以下のdeprecated warningが表示された
  • 欲しかったパッケージ(ipykernel)は[tool.poetry.group.dev.dependencies]に追加されていた
$ poetry add -D ipykernel
The --dev option is deprecated, use the `--group dev` notation instead.
Using version ^6.15.3 for ipykernel
shotakahashotakaha

https://python-poetry.org/docs/managing-dependencies

  • 依存パッケージをグループ別に整理できる機能が追加されていた
  • たとえばテスト用(--group test)、ドキュメント用(--group docs)などに分けて整理できるようになった
  • 追加パッケージ間の依存関係は、グループに関係なく管理される
$ poetry add --group test pytest
$ poetry add --group docs sphinx sphinx_rtd_theme myst_parser
shotakahashotakaha
rye add
$ rye add パッケージ名
$ rye add --dev パッケージ名
  • pyproject.tomlに追記されるが、パッケージはまだインストールされない
  • --devかそうじゃないかのオプションしかない
shotakahashotakaha

poetry run

作成したスクリプトを実行する場合は poetry run する

poetry run
$ poetry run python raw2csv.py
$ poetry run ./raw2csv.py
$ poetry run pytest
  • 仮想環境の外から実行する場合に poetry run をつける必要がある
  • スクリプトに実行権限が付いている場合は、直接引数に指定すればOK
  • 外部パッケージのコマンドも同様に使うことができる
  • 仮想環境内のシェルを起動する場合は poetry shell する
shotakahashotakaha
rye run
$ rye run コマンド
$ rye run python3 --version
  • poetry shellに相当するコマンドがryeには存在しない
    • 直接source .venv/bin/activate.fishする
  • rye run コマンドを実行するほうが簡単かも
shotakahashotakaha

poetry install

依存するパッケージをすべてインストールする場合は poetry install する

poetry install
$ poetry install
  • poetry.lockの内容に書かれたファイルをインストールする
  • poetry.lockがない場合は、pyproject.tomlに書いてあるパッケージ(とバージョン)をインストールする
  • デフォルトでは自作パッケージもインストールされる
    • このとき、ディレクトリ構造が poetry newしたときと同じ構造でないとエラー(No file / folder found for pakage パッケージ名)がでて、正しくインストールできない
  • 自作パッケージをインストールしたくない場合は poetry install --no-rootする
shotakahashotakaha

ディレクトリ構造を変更できない場合

pyproject.toml[tool.poetry.packages]で設定することができる

pyproject.toml
[tool.poetry]
# ...
packages = [
    { include = "scripts/*.py" }
]
  • (原理的にディレクトリ構造を変更できないことはないと思うが)変更/整理するのがめんどくさいケースはあるかもしれない
  • たとえば${PROJECT}/scripts/__init__.pyのような構造で作ってしまっていた場合は、上記のように設定すればOK(なはず)
shotakahashotakaha

poetry.lock

  • poetryを使っってインストールしたパッケージ情報を管理するためのロックファイル
  • このファイルを共有することで、異なる端末にも同様の開発環境(パッケージとバージョン)を整えることができる
  • gitリポジトリにコミットしておくとよい
shotakahashotakaha

poetry update

パッケージの依存関係を更新する場合は poetry update する

poetry show
$ poetry show --outdated
  • 更新が必要なパッケージを確認できる
poetry update
$ poetry update
  • pyproject.tomlに書いてあるパッケージに該当するバージョン(の最新の版)を取得して、poetry.lockを更新する
  • ドキュメントによるとpoetry.lockを削除して、再度poetry installするのと同様のことをしているそう
shotakahashotakaha
  • poetry.lockは更新されるが、pyproject.tomlは更新されない
  • pyproject.tomlも更新する場合は poetry add パッケージ名@latest する
poetry add パッケージ名@latest
$ poetry add pandas@latest
$ poetry add plotly@latest
$ poetry add mystmd@latest --group=docs
shotakahashotakaha
rye add
$ rye add mystmd
Added mystmd>=1.1.53 as regular dependency
Reusing already existing virtualenv
Generating production lockfile: ${プロジェクトの絶対パス}/requirements.lock
Generating dev lockfile: ${プロジェクトの絶対パス}/requirements-dev.lock
Installing dependencies
   Built file:///{プロジェクトの絶対パス}
Built 1 editable in 158ms
Resolved 1 package in 0.37ms
Downloaded 1 package in 157ms
Uninstalled 2 packages in 6ms
Installed 2 packages in 1ms
 - mystmd==1.1.52
 + mystmd==1.1.53
 - statistics==0.1.0 (from file:///{プロジェクトの絶対パス})
 + statistics==0.1.0 (from file:///{プロジェクトの絶対パス})
Done!
  • poetry updateに相当するコマンドはryeにはなさそう
  • rye add パッケージ名で最新版に更新できた
  • 次の3つのファイルが更新された
$ git status
pyproject.toml
requirements.lock
requirements-dev.lock
shotakahashotakaha

pyproject.toml

poetryの設定は[tool.poetry]セクションに追記する

https://python-poetry.org/docs/pyproject/

poetry.toml
[tool.poetry]
name = "パッケージ名"(必須)
version = "0.1.0"(必須)
description = ""(必須)
license = "MIT"
authors = "名前 <メールアドレス>"(必須)
maintainers = ""
readme = "README.md"
homepage = ""
repository = ""
documentation = ""
keywords = ""
classifiers = []
packages = []
include = []
exclude = []
  • (必須)と書いた項目以外はオプショナル
  • それぞれの項目の設定内容はあとで調べる
shotakahashotakaha

コマンドラインツール化

作成したパッケージをコマンドラインツールとして使いたい場合はpyproject.toml[tool.poetry.scripts]セクションに追加する

pyproject.toml
[tool.poetry.scripts]
snapsheets = "snapsheets.core:cli"
snapsheets-next = "snapsheets.next:cli"
  • パッケージにあるファイル名:関数名を設定する
  • 上記の設定だと snapsheets/core.pycli()という名前の関数が、snapsheetsというコマンドで実行できるようになる
  • コマンドは複数設定することができる。上の例では、次のリリースに向けていろいろ試している snapsheets-next を追加している
shotakahashotakaha

poetry check

pyproject.tomlの内容に書き間違いがないかpoetry checkする

poetry check
$ poetry check
All set!
shotakahashotakaha

poetry build

PyPIにアップロードするファイルをビルドするには poetry buildする

poetry build
$ poetry build
Building haniwers (0.0.5)
  - Building sdist
  - Built haniwers-0.0.5.tar.gz
  - Building wheel
  - Built haniwers-0.0.5-py3-none-any.whl
  • wheel形式とsdist形式のファイルが dist/ に作成される
    • 削除する場合は rm -r distする
  • -f [wheel/sdist] でビルド形式を指定することができる
shotakahashotakaha

poetry publish

PyPITestPyPIにパッケージを公開するには poetry publish する

poetry publish
$ poetry publish
$ poetry publish -r testpypi
  • デフォルトの公開先は PyPI になっている
  • -r リポジトリ名で公開先を指定することができる
  • リポジトリ名は以下のようにして設定する
poetry config
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
shotakahashotakaha

API Tokenの設定

PyPITestPyPIに公開するときは、API Tokenの設定をしておくとよい

poetry config
$ poetry config pypi-token.pypi "PyPIのAPI Token"
$ poetry config pypi-token.testpypi "TestPyPIのAPI Token"
  • API Tokenはそれそれのウェブサイトのアカウント設定から発行する
  • Tokenには名前をつけて、scopeは適切に設定する( all projects or 特定のパッケージ )
  • Tokenはマシンごとに発行して、設定する必要がある(はず)
shotakahashotakaha

poetry config

poetryの設定を確認したり、変更したりするには poetry config する

poetry config
$ poetry config --list
cache-dir = "/Users/shotakaha/Library/Caches/pypoetry"
experimental.new-installer = false
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/shotakaha/Library/Caches/pypoetry/virtualenvs
  • デフォルトの設定は上記のようになっている
  • 設定は ~/Library/Application Support/pypoetry/config.toml に書いてある
  • PyPI / TestPyPI の設定はここに表示されないみたい(どこにいったんだろう?)
shotakahashotakaha

poetry + vscode

virtualenvs.in-project = true にしておいたほうがいいっぽい

virtualenvs.in-project
$ poetry config virtualenvs.in-project true
  • カレントディレクトリの .venv に仮想環境が作られる
  • vscode はここにある仮想環境を勝手に読み込んでくれる(らしい)

すでに仮想環境を作ってしまっている場合は、そのディレクトリを一旦削除してから poetry install しなおせばOK

$ cd ~/Library/Caches/pypoetry/virtualenvs/
$ rm -r 該当する仮想環境
shotakahashotakaha

poetry env

現在の仮想環境で使っている Pythonのバージョンなどを確認したり、変更したりする場合は poetry env する

poetry env info
$ poetry env info

Virtualenv
Python:         3.9.13
Implementation: CPython
Path:           /Users/shotakaha/Library/Caches/pypoetry/virtualenvs/snapsheets-mU0WpA-6-py3.9
Valid:          True

System
Platform: darwin
OS:       posix
Python:   /opt/homebrew/opt/python@3.9/Frameworks/Python.framework/Versions/3.9
shotakahashotakaha

別のマシンは 3.10になっていた

poetry env info
$ poetry env info

Virtualenv
Python:         3.10.4
Implementation: CPython
Path:           /Users/shotakaha/Library/Caches/pypoetry/virtualenvs/snapsheets-mU0WpA-6-py3.10
Valid:          True

System
Platform: darwin
OS:       posix
Python:   /usr/local/opt/python@3.10/Frameworks/Python.framework/Versions/3.10
shotakahashotakaha

virtualenvsの作り方

$ poetry config virtualenvs.options.no-pip true
$ poetry config virtualenvs.options.no-setuptools true
$ poetry config virtualenvs.options.system-site-packages true
  • 仮想環境を作成するときにvirtualenvs --no-pipオプションが渡される。poetryvertualenvsに組み込まれたpipを使っているが、仮想環境に他のパッケージを追加したくない場合はtrueにするとよい。合わせてno-setuptools=trueにするとよい。
  • 仮想環境を作成するときにvirtualenvs --no-setuptoolsオプションが渡される。setuptoolsがインストールされなくなる。Poetryにとっては問題ない。
  • システムにインストールしたパッケージを使えるようにしたいのでsystem-site-packages=trueにした。