この記事は、みらい翻訳 Advent Calendar 2022 の2日目です。
こんにちは。プラットフォーム開発部のdiceです。
最近、わたしの所属チームでpipでのPythonライブラリ管理に苦労しており、Poetryというライブラリ管理ツールを使ってみたので、ご紹介します。
ライブラリ管理の苦労
pipでわずらわしく感じていたこと
- lockファイルの生成に一手間かかる
- 開発用とリリース用のrequirements.txtファイルが必要となる
Poetryとの出会い
いろいろ調べたところPoetryというツールで下記のように改善できそうということがわかりました。
- lock ファイルの生成が容易
- 依存するライブラリのバージョンも指定可能
- テストライブラリを除くビルド、含むビルドが1ファイルで設定できる
- 開発環境構築・リリース用コンテナ構築の設定ファイルが1つにまとめられる
Poetryとは
Pythonのライブラリ管理ツールです。(2019年12月にv1.0が公開されました)
プロジェクトが依存するライブラリをコマンドから管理(インストール/更新)することができます。
また、Poetry は繰り返しインストールできるようにロックファイルを提供し、配布用にプロジェクトをビルドすることができます。
システム要件
- Python3.7以降
今回は、Python3.9を使用します。
実際にプロジェクト等で使用する場合には、pyenvを併せて使用する方が便利かと思います。
インストール方法
以下のコマンドを実行してインストールします。
Poetryのバージョンを指定する場合は、POETRY_VERSIONの環境変数を設定します。
$ curl -sSL https://install.python-poetry.org \ | POETRY_VERSION=1.2.2 python3 -
プロジェクト作成方法
poetry-demo
というプロジェクトを作成します。
$ poetry new poetry-demo
以下のようにプロジェクトが作成されます。
poetry-demo ├── README.md ├── poetry_demo <-- プロジェクト名の"-"は"_"に変換されます │ └── __init__.py ├── pyproject.toml └── tests └── __init__.py
ディレクトリを移動します。
$ cd poetry-demo
今回は、poetry.lock
ファイルを生成したいため以下のコマンドを実行します。
$ poetry install
poetry.lock
ファイルが作成されます。
poetry-demo ├── README.md ├── poetry.lock ├── poetry_demo │ └── __init__.py ├── pyproject.toml └── tests └── __init__.py
ファイル内容
- pyproject.toml
tomlファイルのフォーマットは、PEP 518で定められています。
https://peps.python.org/pep-0518/
ファイル名・ファイルフォーマットは以下となります。
(こちらはPoetry独自のファイルではありません)
[tool.poetry] name = "poetry-demo" version = "0.1.0" description = "" authors = ["Jone Doe <jone.doe@miraitranslate.com>"] readme = "README.md" packages = [{include = "poetry_demo"}] [tool.poetry.dependencies] python = "^3.9" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
- poetry.lock
依存するライブラリのバージョン情報等が記録されます。
初期状態では、以下のような内容になっています。
package = [] [metadata] lock-version = "1.1" python-versions = "^3.9" content-hash = "c595a0588c25d58f3e3834ad7169126836d262b925fe6ca9b5d540dcf301d254" [metadata.files]
poetry_demo/main.py作成
試しに poetry_demo/main.py
を新規作成して動作させます
def main(): print("main!!") if __name__ == "__main__": main()
実行
poetry_demo/main.py
ができたら実行していきます。
まず、 PYTHONPATHを設定します。
(各自の環境に合わせて、"poetry-demoのパス名"を指定してください。)
$ export PYTHONPATH="/Users/jone/poetry-demo"
poetry run
をpython実行コマンドの頭につけることでPoetry仮想環境でプログラムが実行されます。
$ poetry run python poetry_demo/main.py main!!
外部ライブラリを追加してみる
先ほど作成した poetry_demo/main.py
を更新します。
外部ライブラリを使用しWEBページにアクセスするように変更します。
- poetry_demo/main.py
import requests def main(): r = requests.get("https://example.com/") print(r.text) if __name__ == "__main__": main()
外部ライブラリ(requests)追加
Poetry仮想環境に外部ライブラリを追加します。
$ poetry add requests
外部ライブラリ(requests)追加後の設定ファイル
- pyproject.toml
[tool.poetry] name = "poetry-demo" version = "0.1.0" description = "" authors = ["Jone Doe <jone.doe@miraitranslate.com>"] readme = "README.md" packages = [{include = "poetry_demo"}] [tool.poetry.dependencies] python = "^3.9" requests = "^2.28.1" <-- 追加された設定 [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
- poetry.lock(一部)
requests
に関連する情報が追加されます。
(依存するライブラリのバージョンも指定されます)
[[package]] name = "requests" version = "2.28.1" description = "Python HTTP for Humans." category = "main" optional = false python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<3" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27"
実行
追加した外部ライブラリを使用しプログラムが実行できています。
(結果は省略してあります)
$ poetry run python poetry_demo/main.py <!doctype html> <html> (省略) </html>
単体テストについて
tests/test_main.py 作成
テスト実行用の tests/test_main.py
を作成します。
from poetry_demo.main import main def test_main(): main()
pytestライブラリ追加
テスト用のライブラリ(pytest)を追加します。テスト用のライブラリは、mainプログラムで直接使用しているライブラリと分けて管理します。
下記のようにオプション --group dev
を付加します。
$ poetry add pytest --group dev
テスト用ライブラリ追加後の設定ファイル
- pyproject.toml
[tool.poetry] name = "poetry-demo" version = "0.1.0" description = "" authors = ["Jone Doe <jone.doe@miraitranslate.com>"] readme = "README.md" packages = [{include = "poetry_demo"}] [tool.poetry.dependencies] python = "^3.9" requests = "^2.28.1" [tool.poetry.group.dev.dependencies] <-- 追加された設定 pytest = "^7.2.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
poetry.lock(一部)
pytestに関連する情報が追加されます。
[[package]] name = "pytest" version = "7.2.0" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = ">=3.7"
テスト実行
追加したpytestライブラリでテストが実行できます。
$ poetry run pytest tests/test_main.py ========================================================================================== test session starts =========================================================================================== platform darwin -- Python 3.9.5, pytest-7.2.0, pluggy-1.0.0 rootdir: /Users/jone/poetry-demo collected 1 item tests/test_main.py . [100%] =========================================================================================== 1 passed in 0.30s ============================================================================================
設定ファイルから環境構築
pyproject.toml
, poetry.lock
ファイルから別の環境に同一の実行環境を構築することができます。
ここでは以下の2つの例を紹介します。
開発環境等を作成する場合
テスト用ライブラリ含め全てのライブラリを入れて環境構築します。
$ poetry install
リリース用コンテナ環境等を作成する場合
テスト用ライブラリを除いて環境構築します。
$ poetry install --only main
おわりに
今回は、Poetryについて紹介しました。
pipなどでPythonのライブラリ管理に苦労されている方は、Poetryを使ってみてはいかがでしょうか。
また、Poetryは静的解析ツールの連携も可能なようですので今後試してみたいと思います。
みらい翻訳ではエンジニアを募集しています
みらい翻訳では、エンジニアを募集しています。
ご興味のある方は、ぜひ下記リンクよりご応募・お問い合わせをお待ちしております。