当サイトは、アフィリエイト広告を利用しています

【Python】poetryの基本的な使い方をまとめてみた

作成日:2024月08月31日
更新日:2024年08月31日

dockerコンテナ上でpoetryを使ってPythonの開発環境を作りながら、
poetryの使い方をまとめていく。

dockerコンテナ上で実行するがローカル環境でも同じことができるので
ローカルで実行したい場合でも参考にできると思う。

poetryとは?

poetryはPythonのパッケージ管理をしてくれるツール。
javascriptでいうこところのnpmやyarnみたいなイメージ。

主な機能ととしては

  • 依存関係の管理
  • 仮想環境の管理
  • シンプルで一貫性のある管理方法

がある

依存関係の管理

pyproject.tomlファイルでPythonプロジェクトの依存関係を一元的に管理できる。
また。グループを作ることで依存関係を本番、開発、テストとを分けて管理することもできる。

少しややこしかったのが
Poetryでは、依存関係を「開発」「テスト」「本番」などのグループに分けて管理することができるが
それぞれが別の環境を持っているわけでなく
あくまで依存関係をグループごとに選択的にインストールできるようにするための機能であるということ。

具体的には、開発環境やテスト環境、本番環境に必要な依存関係をpyproject.tomlファイルで定義し、
poetry install --only groupコマンドで必要な依存関係をインストールすることができる
つまり特定の環境に必要なパッケージだけをインストールして環境を管理することができるが、同じ仮想環境内での話になる。

poetry.lockファイルによって
依存関係のバージョンがロックされるため、異なる環境で同じ依存関係のバージョンを再現できる
これにより、環境間の不一致による問題を防げる。

仮想環境の管理

Poetryはプロジェクトごとに自動的に仮想環境を作成し、依存関係をその仮想環境内にインストールすることで
プロジェクト間での依存関係の衝突を防ぐことができる。 また仮想環境のアクティベートやデアクティベートも自動で行うので、手動で行う必要がない。
基本的には1プロジェクト1仮想環境となる。

シンプルで一貫性のある管理方法

依存関係の追加や更新、プロジェクトのセットアップがシンプルなコマンドで統一されていて
他のツールなしで簡単に操作できる

pipとの比較

Pythonでパッケージ管理といえばpipだと思うので
pipの比べてpoetryのメリット、デメリットをまとめてみる。

poetryのメリット

全体的にpoetryの方が高機能な感じがする

依存関係の一元管理

Poetryは依存関係の管理と仮想環境の作成・管理を一元的にできる。
pipの場合はpipとvirtualenvまたはvenvを組み合わせる必要がある。
※コンテナ使う場合はあんまり関係なさそう。。。

依存関係の自動解決

Poetryは依存関係の衝突を自動で解決してくれる
複数のパッケージが同じ依存関係を異なるバージョンで要求する場合でも
最適なバージョンを選択してインストールしてくれる

またversionロック機能もついている

pyproject.tomlの利用

Poetryはpyproject.tomlを使用して依存関係を管理し、プロジェクトの設定を一箇所に集約する。
そのためプロジェクト設定が一貫して管理できる

開発用依存関係の管理

Poetryでは、開発用依存関係と本番用依存関係を簡単に分けて管理できる。
例えば、テストフレームワークなどは開発時のみインストールするように設定できる。

poetryのデメリット

デメリットは下記がある

依存関係の解決が遅い場合がある

依存関係の解決が複雑な場合、Poetryは依存関係の解決に時間がかかることがある。
大規模なプロジェクトでは問題になるかもしれない。

標準ツールではない

Pythonの標準ライブラリでないため、poetryをインストールする必要がある。
※コンテナをdocker-composeで作る場合は無視できると思う。

一部のパッケージが非互換

一部のパッケージやビルドツールとの互換性に問題が出る場合がある。
特に、古いプロジェクトや特殊な設定をしているプロジェクトでは注意する

pipのメリット

pipの方がシンプルで使いやすくはある

使いやすい

pythonの標準ツールでもあるため、広く利用されていて
学習コストが低く、使いやすい

高速なインストール

pipは依存関係の解決をシンプルに行うため、依存関係のインストールが速い。
特に小規模なプロジェクトではそのメリットが大きい。

ちょっと作るだけとかならさくっとpipを使ったほうがいいかもしれない

柔軟な設定

必要に応じて複数の仮想環境や依存関係を手動で管理することで柔軟な設定が可能

pipのデメリット

デメリットは下記がある

依存関係の衝突の管理

pipは依存関係の衝突を自動的に解決する機能がない。
そのため、複雑な依存関係を持つプロジェクトでは手動で解決する必要がある。

バージョンロックがデフォルトではない

pip単体では依存関係のバージョンをロックする機能がなく、
requirements.txtと組み合わせる必要がある。
しかし、requirements.txtはpipが直接管理するわけではないため、バージョンロックが統一的でない。

開発用と本番用の依存関係の分離が不便

pipでは、開発用依存関係と本番用依存関係を分けるためには手動でrequirements.txtファイルを複数作成する
などの工夫が必要。

比較まとめ

Poetryは、依存関係の自動解決や仮想環境の管理、バージョンロックなどを統合的に行いたい場合に非常に相性がいい。
一方、pipはシンプルで高速、かつPythonの標準ツールとして広く使われているため、
より柔軟に管理したい場合や、標準的な方法でプロジェクトを構築したい場合に向いている。

個人的にはPoetryの方が管理はしやすいイメージ。だが小規模な開発の時やツールを作る時は
pipの方が早くできるので使いやすい。

コマンド

実際にコンテナで実践していく前によく使うpoetryのコマンドをまとめておく

poetry new プロジェクト名

new
poetry new test

プロジェクトから作成して開始したいときに使う。
新しいプロジェクトの構成を作成し、pyproject.tomlも生成する。
新しいプロジェクトが作成されるが、この段階では仮想環境は作成されない。

poetry init

init
poetry init

既存のディレクトリをpoetryで管理するようにしたい時に使う。
既存プロジェクトにpyproject.tomlファイルを生成し、プロジェクトの初期化を行う。
この時点では仮想環境は作成されない

poetry install

install
poetry install

pyproject.tomlが既に作成済みの場合に使う pyproject.tomlに基づいて依存関係をインストールし、
プロジェクト専用の仮想環境も生成する。
依存関係をインストールしながら仮想環境をセットアップするコマンド

初期化はプロジェクトの状況に合わせて

  • poetry new
  • poetry init
  • poetry install

のどれかを使うことになる。

poetry install --sync

install_--sync
poetry install --sync

インストール時にpoetry.lockの内容を環境に同期させることができる

poetry lock

lock
poetry lock

pyproject.tomlに基づいてpoetry.lockファイルを再生成する。 ※pyproject.tomlとpoetry lockがずれているとエラーになる

poetry add <パッケージ名>

add
poetry add requests

指定したパッケージを依存関係に追加し、インストールする
同時に仮想環境も作成する。

poetry update

upgrate
poetry update

依存関係を最新のバージョンに更新する。
「poetry update <パッケージ名>」とすれば
パッケージを指定して更新できる

poetry remove <パッケージ名>

remove
poetry remove requests

パッケージを削除する

poetry run <コマンド>

run
poetry run python test_module.py

仮想環境内で指定したコマンドを実行する
※test_module.pyを実行する場合のサンプル

poetry show

show
poetry show

pyproject.tomlを含むすべてのパッケージとそのバージョンが一覧表示される。
インストール済みは緑、未インストールは赤字になる

仮想環境がない状態でpoetry showを実行すると仮想環境が作成されるが
依存関係のインストールはされない。

poetry show --tree

tree
poetry show --tree

pyproject.tomlのパッケージとその依存関係をツリー形式で表示する

poetry env list

list
poetry env list

仮想環境の一覧を表示
※poetryでは基本は1プロジェクト1仮想環境なので1つしかでないことが多い

poetry env info

info
poetry env info

仮想環境の詳細を表示する

poetry env remove 仮想環境名

remove
poetry env remove poetry-sample-project-xS3fZVNL-py3.12

仮想環境を削除する
仮想環境名は「poetry env list」で確認する

poetry self update

update
poetry self update

poetry自体のアップデート

poetry show <パッケージ名>

bash
poetry show requests

パッケージの詳細を表示する

そのほかのコマンドや詳細は下記参照

コンテナ作成

pythonのコンテナを作成する。
その中でpoetryを使ってプロジェクトを作成してみる

コンテナ作成時に同時に実行することも可能だが
動きを見るためにコンテナ内で手動で実行する。

dockerfile

dockerfile
# ベースイメージとしてPythonを使用
FROM python:3.12
# 作業ディレクトリを作成
WORKDIR /workspace
# pipを更新
RUN pip install --upgrade pip
# Poetryをインストール
RUN pip install poetry

pythonにpipでpoetryをインストールしたイメージを作成する

docker-compose.yml

docker-compose.yml
version: "3"
services:
poetry:
container_name: "poetry-sample"
build:
context: .
dockerfile: Dockerfile
volumes:
# バインドマウント
- .:/workspace
tty: true

docker-composeでコンテナを作成する。

commandでコンテナ作成

コンテナ作成
docker comopse up -d

docker comopseを実行してコンテナを作成する

コンテナにログインする

コンテナに入る。

VSCodeの拡張機能である。

  • Dev Containers(ms-vscode-remote.remote-containers)
  • Docker(ms-azuretools.vscode-docker)

のどちらかを使用すれば、コンテナ内をVSCodeから操作できるので 開発しやすい。

Dev Containersの使い方については下記でまとめています。

ログインし、「/workspace」に移動すると

bash
.
|-- docker-compose.yml
`-- dockerfile

の状態になっている

poetryのインストール確認

bash
root@4afb2b283765:/workspace# pip show poetry
Name: poetry
Version: 1.8.3
Summary: Python dependency management and packaging made easy.
Home-page: https://python-poetry.org/
Author: Sébastien Eustace
Author-email: sebastien@eustace.io
License: MIT
Location: /usr/local/lib/python3.12/site-packages
Requires: build, cachecontrol, cleo, crashtest, dulwich, fastjsonschema, installer, keyring, packaging, pexpect, pkginfo, platformdirs, poetry-core, poetry-plugin-export, pyproject-hooks, requests, requests-toolbelt, shellingham, tomlkit, trove-classifiers, virtualenv
Required-by: poetry-plugin-export
root@4afb2b283765:/workspace#

pip showコマンドでコンテナにpoetryがインストールされていることを確認しておく

poetryで開発環境を整える

コマンドのところでも書いたがpoetryでプロジェクトを開始する場合

  • poetry new
  • poetry init
  • poetry install

のどれかから開始することになるので
それぞれのパターン別に実践してみる。

またサンプルとして下記のコードを実行する

test_module.py
import requests
def fetch_data(url):
try:
# 指定したURLにGETリクエストを送信
response = requests.get(url)
# レスポンスのステータスコードを表示
print(f"ステータスコード: {response.status_code}")
# レスポンスの内容を表示
if response.status_code == 200:
print("データ:")
print(response.text)
else:
print("データを取得できませんでした。")
except requests.exceptions.RequestException as e:
print(f"リクエスト中にエラーが発生しました: {e}")
if __name__ == "__main__":
# 取得したいデータのURL
url = "https://jsonplaceholder.typicode.com/todos/1"
fetch_data(url)
# 実行結果
# ステータスコード: 200
# データ:
# {
# "userId": 1,
# "id": 1,
# "title": "delectus aut autem",
# "completed": false
# }

jsonplaceholderからダミーデータを取得するpythonスクリプト
requestsのパッケージが必要になる

poetry newから開始する

新規プロジェクト作成から開始する場合のパターン。
流れとしては

  1. poetry newで新しいプロジェクト自体を作成しpyproject.tomlも生成して初期化する
  2. poetry add xxx で依存関係をインストールする。同時に仮想環境も作る
  3. poetry run で仮想環境で実行する

のようになる。

コンテナ内で実行していく

poetry new実行

コマンドで

poetry_new
poetry new poetry-sample-project

を実行する。 インタラクティブガイドに答えると
下記のようなプロジェクトを作成してくれる

プロジェクト構成
.
├── docker-compose.yml
├── dockerfile
└── poetry-sample-project
├── README.md
├── poetry.lock
├── poetry_sample_project
│ ├── __init__.py
│ └── test_module.py
├── pyproject.toml
└── tests
└── __init__.py

poetry-sample-project以下が作成される
※test_module.pyは自分で追加する。

pyproject.tomlは下記のようになっている

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

poetry add

test_module.pyを実行するために必要な「requests」パッケージを
インストールする。
インストールすると同時に仮想環境も作成される
※pyproject.tomlがあるディレクトリで実行する必要がある

poetry_add
poetry add requests

実行後のpyproject.tomlは下記のようになる

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

requestsが追加されている

poetry run python test_module.py

仮想環境でtest_module.pyを実行する

実行
root@4afb2b283765:/workspace/poetry-sample-project# poetry run python poetry_sample_project/test_module.py
ステータスコード: 200
データ:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}

poetry initから開始する

既存のディレクトリをpoetryのプロジェクトととして管理するようにする
コンテナ作成後の下記の状態から開始する

初期状態
.
|-- docker-compose.yml
|-- dockerfile
`-- test_module.py

※test_module.pyは自分で作る

poetry init

既存のディレクトリ内にpyproject.tomlを作成し
poetryのプロジェクトとして初期化する 流れとしては

  1. 任意の既存ディレクトリ内でpoetry initを実行し、pyproject.tomlを生成して初期化する
  2. poetry add xxx で依存関係をインストールする。同時に仮想環境も作る
  3. poetry run で仮想環境で実行する

のようになる。

同様にコンテナ内で実行していく

初期化
poetry init

poetry newと同様に
インタラクティブガイドに答えると
pyproject.tomlが生成される

init実行後
.
|-- docker-compose.yml
|-- dockerfile
|-- pyproject.toml
`-- test_module.py

pyproject.tomlは下記のようになっている

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

2と3の手順はpoetry newした場合と同じなので割愛する。

pyproject.tomlありで開始する

pyproject.tomlに基づいて依存関係をインストールし、
プロジェクト専用の仮想環境も生成する。
手順は

  1. poetry installで依存関係をインストールし、同時に仮想環境も生成する
  2. poetry runで仮想環境で実行する

のようになる

またpoetry install実行する場合、poetry.lockがあるかないかで
挙動が変わる

poetry.lockない場合、pyproject.tomlでは具体的にどのバージョンがインストールされるかは未定
のためpoetry installを実行すると、その時点で利用可能な最新のバージョンがバージョン範囲に基づいて選ばれる

poetry.lockがある場合は
poetry.lockには、特定のバージョンの依存関係が記録されているので異なる環境や他の開発者が
同じプロジェクトをセットアップするときに、全く同じバージョンの依存関係をインストールできる

要は他の環境を完全に再現するためにはpoetry.lockが必須となる。

poetry install

pyproject.tomlを任意のディレクトリに格納後、そのディレクトリに
移動し、poetry installを実行する

bash
poetry install

pyproject.tomlに従って依存関係がインストールされる
※poetry.lockがある場合は特定のバージョンで依存関係の解決が行われる。

2はpoery new、poetry initと同じなので割愛する。

pyproject.tomlを手動変更した場合

poetry.lock作成後にpyproject.tomlを手動で変更した場合
poetry.lockとpyproject.tomlの間に乖離が発生するので
poetry installを実行すると

エラー
$ poetry install
Installing dependencies from lock file
pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock [--no-update]` to fix the lock file.

という感じでズレていることを怒られるので
下記コマンドでpoetry.lockを更新する

更新
poetry lock

依存関係のグルーピング

Poetryでは依存関係を「開発」「テスト」「本番」などのグループに分けて 選択的にインストールできるようにすることができる。
※「開発」「テスト」「本番」のそれぞれが別の環境を持っているわけではない。

poetryのグループ

devグループとtestグループはデフォルトで存在するが
その他のグループは使う場合は自分で作成する必要がある。

グループ別に依存関係を追加する

グループ別に依存関係を追加するコマンドをまとめる

下記のpyproject.tomlに対して実行していく

pyproject.toml(初期状態)
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

本番環境への追加

本番環境への追加
poetry add requests

実行後のpyproject.toml

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

開発グループへの追加

本番環境への追加
poetry add black flake8 --group dev

実行後のpyproject.toml

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxxxxxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
flake8 = "^7.1.1"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

テストグループへの追加

本番環境への追加
poetry add pytest pytest-cov --group test

実行後のpyproject.toml

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxxxxxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
flake8 = "^7.1.1"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.2"
pytest-cov = "^5.0.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

任意のグループへの追加

sample
poetry add pydantic --group sample

実行後のpyproject.toml

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxxxxxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
flake8 = "^7.1.1"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.2"
pytest-cov = "^5.0.0"
[tool.poetry.group.sample.dependencies]
pydantic = "^2.8.2"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

任意のグループが作成されている

addはインストールする時にグループを設定しているだけであり
コマンドを実行した仮想環境には上記のパッケージはすべてインストールされている

追加済みの依存関係を見てみる

bash
root@aa632dfa840c:/workspace# poetry show
black 24.8.0 The uncompromising code formatter.
certifi 2024.8.30 Python package for providing Mozilla's CA Bundle.
charset-normalizer 3.3.2 The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet.
click 8.1.7 Composable command line interface toolkit
coverage 7.6.1 Code coverage measurement for Python
flake8 7.1.1 the modular source code checker: pep8 pyflakes and co
idna 3.8 Internationalized Domain Names in Applications (IDNA)
iniconfig 2.0.0 brain-dead simple config-ini parsing
mccabe 0.7.0 McCabe checker, plugin for flake8
mypy-extensions 1.0.0 Type system extensions for programs checked with the mypy type checker.
packaging 24.1 Core utilities for Python packages
pathspec 0.12.1 Utility library for gitignore style pattern matching of file paths.
platformdirs 4.2.2 A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`.
pluggy 1.5.0 plugin and hook calling mechanisms for python
pycodestyle 2.12.1 Python style guide checker
pyflakes 3.2.0 passive checker of Python programs
pytest 8.3.2 pytest: simple powerful testing with Python
pytest-cov 5.0.0 Pytest plugin for measuring coverage.
requests 2.32.3 Python HTTP for Humans.
urllib3 2.2.2 HTTP library with thread-safe connection pooling, file post, and more.

別の環境に上記のpyproject.tomlを持って行って
installコマンをオプション付きで実行することで
グループ別のインストールが可能になる。

グループ別に依存関係をインストールする

グループ別に依存関係を追加したpyproject.tomlを元に
グループ別に依存関係をインストールしてみる

pyproject.toml
[tool.poetry]
name = "poetry-sample-project"
version = "0.1.0"
description = ""
authors = ["xxxxxxxxxxxxxxxxxxxxx"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.32.3"
[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
flake8 = "^7.1.1"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.2"
pytest-cov = "^5.0.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

を別の環境に持って行ってインストールを実行して試す。

下記のような構成で試す

別の環境の構成
.
|-- docker-compose.yml
|-- dockerfile
|-- poetry.lock
|-- pyproject.toml
`-- test_module.py

pyproject.tomlとpoetry.lockを残した状態で
コンテナを再作成する※下記コマンド

  • docker compose down
  • docker compose up -d

コンテナを再作成し、ログイン後、仮想環境を削除する

仮想環境削除
# 仮想環境一覧表示
root@16cfe12632ec:/workspace# poetry env list
poetry-sample-project-xS3fZVNL-py3.12 (Activated)
# 仮想環境削除
root@16cfe12632ec:/workspace# poetry env remove poetry-sample-project-xS3fZVNL-py3.12
Deleted virtualenv: /root/.cache/pypoetry/virtualenvs/poetry-sample-project-xS3fZVNL-py3.12
# 削除後確認
root@16cfe12632ec:/workspace# poetry env list

最後に依存関係がないことを確認する
2024-08-31-17-22-11 赤字のものはインストールされていない

次からグループごとのインストールを試してみる

すべてインストール

デフォルトではすべてのグループインストールされる

all
poetry install

実行後
2024-08-31-18-17-18 すべて緑なのでインストールされている

本番環境の依存環境をインストール

本番グループのみインストール

honban
poetry install --without dev,test

実行後
2024-08-31-18-26-37

開発環境の依存環境をインストール

開発グループのみインストール

dev
poetry install --only dev

実行後
2024-08-31-18-27-27

テスト環境の依存環境をインストール

テストグループのみインストール

test
poetry install --only test

実行後
2024-08-31-18-28-01

まとめ

poetryを使ってpythonの実行環境をコンテナ内で
作成してみた。

javascriptのフレームワークであるReactやAngularで
npmやyarnを使っていた人は感覚的に理解しやすいと思う。

またpipに比べて管理能力は高いのでプロジェクトで使うには
良いと思う。

参考

関連記事

新着記事

目次
タグ別一覧
top