Python Poetry: モダンで効率的なPython環境と依存関係管理

Pythonのエコシステムは伝統的に、依存関係やプロジェクト環境を管理するためにpipvirtualenvなどのツールに頼ってきました。これらのツールは役立ってきましたが、依存関係の競合、手動での環境管理、チーム間でのプロジェクトセットアップの不整合などがしばしば発生します。

Python Poetryは、これらの課題を解決するために、モダンで統一された依存関係と環境管理ツールを提供します。仮想環境からパッケージの公開まで、すべてを処理し、インテリジェントな依存関係の解決を通じて再現可能なビルドを確保します。

このガイドでは、Pythonの開発ワークフローを効率化し、一般的な依存関係の問題を回避するためにPoetryの使用方法を紹介します。

Python Poetry vs. PIP

Poetryとpipの違い

1. 依存関係の解決

  • Pip: 簡単で直線的な依存関係の解決方法で、衝突を引き起こす可能性がある
  • 詩:インストール前に競合を防止する高度な依存関係リゾルバ

2. 仮想環境の管理

  • Pip:別々のツール(virtualenv、venv)と手動でのアクティベーションが必要
  • Poetry:プロジェクトごとに仮想環境を自動的に作成および管理

3. プロジェクト構成

  • Pip:依存関係にはrequirements.txt、プロジェクトメタデータにはsetup.pyを使用
  • 詩: すべての構成ニーズに対する単一のpyproject.tomlファイル

4. ロックファイル

  • Pip: 組み込みのロックファイルサポートなし
  • Poetry: 環境全体で再現可能なビルドのためのpoetry.lockを生成

5. パッケージの公開

  • Pip: 公開のために追加のツール(twine、setuptools)が必要
  • Poetry: パッケージのビルドと公開のための組み込みコマンド

詩を使用するタイミング:

詩を使用する理由:

  • 再現可能な環境が必要なチームプロジェクトに取り組む場合
  • PyPIに公開されるパッケージを作成する場合
  • 潜在的な競合を持つ複雑な依存関係ツリーを管理する場合
  • 自動化された仮想環境管理が必要な場合
  • 開発ワークフロー全体に単一のツールが必要な場合

pipを使用するタイミング:

  • 最小限の依存関係を持つシンプルなスクリプトを作成しています
  • Pythonを初めて学んでいます
  • 1つのパッケージを素早くインストールする必要があります
  • Poetryのインストールができない環境で作業しています
  • pipで既に設定されているレガシープロジェクトをメンテナンスしています

一般的な原則は次のとおりです: プロジェクトを共有したり、展開したり、長期間メンテナンスする場合はPoetryを使用します。クイックな実験や学習演習にはpipを使用してください。

それを踏まえて、Poetryの使用方法について詳しく見ていきましょう。

Python Poetryの設定

Poetryとは、主にコマンドライン(CLI)ツールとして操作しますので、マシン全体にシステム全体でインストールするのが理にかなっています。このセクションでは、この重要な最初のステップと、Poetryを必要に応じていくつかのデフォルト構成を設定する方法について説明します。

Poetryのインストール

公式のインストーラースクリプトを使用してPoetryをインストールすることができます。これは、単一のコマンドでダウンロードして実行できます。

macOS、Linux、およびWSL2向け:

$ curl -sSL https://install.python-poetry.org | sudo python3 -

Windows Powershell(管理者権限で実行)向け:

$ (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -

Windowsを使用しており、何らかの理由でMicrosoft StoreからPythonをインストールしている場合は、上記のコマンドの中のpypythonに置き換えてください。

インストールスクリプトが完了したら、PoetryをPATHに追加するようにメッセージが表示され、poetryコマンドがいつでも利用できるようになります。

macOS、Linux、およびWSL2の場合、次の行をシェルスクリプトに追加します.bashrcまたは.zshrc

$ export PATH="/Users/bexgboost/.local/bin:$PATH"

Windowsの場合は、出力手順に従ってください。

その後、次のコマンドを実行してインストールを確認してくださいpoetry --version

ポエトリの設定

ポエトリの設定のほとんどは、仮想環境の作成方法やパッケージのインストール方法に関するものです。次のコマンドを使用して、(ほぼ)すべてのポエトリ設定のリストを表示できます:

$ poetry config --list

出力は以下のようになります:

cache-dir = "/Users/bexgboost/Library/Caches/pypoetry" experimental.system-git-client = false installer.max-workers = null installer.modern-installation = true installer.no-binary = null installer.parallel = true keyring.enabled = true solver.lazy-wheel = true virtualenvs.create = true virtualenvs.in-project = null virtualenvs.options.always-copy = false virtualenvs.options.no-pip = false virtualenvs.options.no-setuptools = false virtualenvs.options.system-site-packages = false virtualenvs.path = "{cache-dir}/virtualenvs" # /Users/bexgboost/Library/Caches/pypoetry/virtualenvs virtualenvs.prefer-active-python = false virtualenvs.prompt = "{project_name}-py{python_version}" warnings.export = true

最初の行で、Poetryキャッシュへのパスが表示されます。これは主にダウンロードしたパッケージ配布や仮想環境を保存するために使用されます。作成した仮想環境はデフォルトでここに保存されます。変更したい場合は、次のコマンドを実行できます:

$ poetry config virtualenvs.path path/to/new/virtualenv/dir

もう1つ重要な構成は、インストール中に使用するコア数です。デフォルトでは4に設定されていますが、すべてのCPUコアを利用して速くすることができます。まず、Pythonインタープリタで os.cpu_count() を実行してマシンのコア数を調べます。その後、出力を設定します:

$ poetry config installer.max-workers = 10

オプションの1つは、作業ディレクトリまたはキャッシュ内で仮想環境を作成するかどうかです。これは、virtualenvs.in-project オプションによって制御されます。Trueに設定すると、.venv ディレクトリが常に作業ディレクトリに作成されます:

$ poetry config virtualenvs.in-project true

ポエトリで新しいプロジェクトを作成する

新しいPoetryプロジェクトを作成し、そのコア構成ファイルを理解するための主要な手順に入りましょう。

新しいPoetryプロジェクトを初期化

ポエトリの使用法は通常、新しいプロジェクトを作成して開始します。poetry newコマンドで:

$ poetry new explore-poetry $ cd explore-poetry

このコマンドは、次のファイルとディレクトリが事前に設定されたexplore-poetryディレクトリを作成します:

explore-poetry ├── pyproject.toml ├── README.md ├── explore-poetry │ └── __init__.py └── tests └── __init__.py

このディレクトリ構造はPythonのベストプラクティスに従います:

  • pyproject.toml: プロジェクトのメタデータと依存関係を定義するメインの設定ファイル
  • README.md: プロジェクトを説明するドキュメントファイル
  • explore-poetry/: メインのパッケージコードを含むソースコードディレクトリで、__init__.py を含めてパッケージ化する
  • tests/: テストファイル用のディレクトリ、__init__.pyはパッケージ(インポート可能)にするためのもの

pyproject.tomlの理解

ここでは、pyproject.tomlファイルはPoetryによって生成される唯一の空でないファイルなので、注意が必要です:

[tool.poetry] name = "explore-poetry" version = "0.1.0" description = "" authors = ["BexTuychiev <[email protected]>"] readme = "README.md" [tool.poetry.dependencies] python = "^3.8" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"

このファイルは、プロジェクトとその依存関係を管理します。それは、 Tom’s Obvious、Minimal Languageを使用しており、これは PEP 518でPythonパッケージの標準構成言語として合意されました。

すべてのpyproject.toml ファイルは、tables と呼ばれるセクションに分割され、tool.poetrybuild-system のような角かっこを使用しています。Poetry はこれらの表を使用して依存関係、プロジェクトのビルド要件を管理したり、その他のタスクを実行します。

次のセクションで概説されているPoetryコマンドを実行すると、pyproject.toml ファイルが自動的に更新されます。

Poetryでの仮想環境の操作

このセクションでは、Poetryで仮想環境を管理する方法の詳細を把握します。セットアップした後のPoetryが仮想環境をどのように自動的に処理するか、作成、有効化、切り替えなどの操作の基本的なコマンド、およびPoetryでPythonバージョンを管理する方法について学びます。

仮想環境の作成と有効化

最初にPoetryをインストールすると、組み込み環境が一つもない状態であり、poetry env listを実行すると出力が空白になります。

$ poetry env list # no output

しかし、後で詳しく説明する依存関係を追加し始めると、poetry add パッケージ名、自動的にプロジェクトのためのキャッシュディレクトリ内に環境を作成します。たとえば、依存関係としてrequestsを追加しようとしてみましょう:

$ poetry add requests

次のような出力が表示されるはずです:

Creating virtualenv explore-poetry--I9GJYUn-py3.8 in /Users/bexgboost/Library/Caches/pypoetry/virtualenvs Using version ^2.32.3 for requests Updating dependencies Resolving dependencies... (2.5s) Package operations: 5 installs, 0 updates, 0 removals - Installing certifi (2024.8.30) - Installing charset-normalizer (3.4.0) - Installing idna (3.10) - Installing urllib3 (2.2.3) - Installing requests (2.32.3) Writing lock file

最初の行は、Poetryがキャッシュ内に環境を作成したことを示しています。次の行は、requestsの依存関係が正常に解決され、ロックファイルが生成されたことを知らせています(これについては後述します)。

環境名に注目してください:explore-poetry--I9GJYUn-py3.8。この名前には、プロジェクトディレクトリ名、ユニークID、そして環境が使用しているPythonのバージョンが含まれています。

次に依存関係を追加すると、Poetryは自動的にこの環境を使用してパッケージをインストールします:

$ poetry add beautifulsoup4 Using version ^4.12.3 for beautifulsoup4 Updating dependencies Resolving dependencies... (1.1s) Package operations: 2 installs, 0 updates, 0 removals - Installing soupsieve (2.6) - Installing beautifulsoup4 (4.12.3) Writing lock file

Poetryを使用している場合、ターミナルにはアクティブなPoetry仮想環境が表示されません。この情報を表示するには、poetry env listを実行する必要があります:

$ poetry env list explore-poetry--I9GJYUn-py3.8 (Activated)

アクティブなPoetry環境とやり取りするには、poetry shellを実行できます:

$ poetry shell

コマンドは現在のシェルセッション内で新しいシェルセッションを開き、次のようなコマンドを実行できます。pythonまたはpytest

たとえば、Pythonスクリプトを実行するには:

$ poetry shell $ python script.py

Streamlitなどの開発フレームワークを実行するには:

# シェル内部で $ streamlit run app.py

その後、exitを呼び出してシェルを終了できます。

または、シェルに入らずにpoetry runを使用してコマンドを実行できます。

$ poetry run python script.py $ poetry run streamlit run app.py

Pythonバージョンの設定

実行すると、poetry addまたはpoetry installを実行すると、Poetryは自動的にpyproject.tomlファイルで指定されたPythonバージョンを使用します。異なるPythonバージョンを指定するには、env useコマンドを実行できます:

$ poetry env use python3.11

Python 3.11 をコマンドを実行するためにマシン全体にインストールする必要があります。

Poetry が新しい Python バージョンを使用している環境を確認してください。

$ poetry env list explore-poetry--I9GJYUn-py3.11 (Activated) explore-poetry--I9GJYUn-py3.8

新しい環境が自動的にプロジェクトにアタッチされることに注意してください(ID は同じです)。 Python バージョンを構成したら、他のバージョンの環境を削除してディスク容量を解放できます。

$ poetry env remove python3.8

環境を削除する際は、Python バージョンを指定するだけで十分です。すべての環境を削除して最初からやり直すこともできます。

$ poetry env remove --all

現在のプロジェクトに関連付けられているすべての環境を削除する --all タグは、他のプロジェクトの環境を削除しません。

チームプロジェクトで作業している場合は、プロジェクトディレクトリに仮想環境を保持する方が良いことが多いです。

$ poetry config virtualenvs.in-project true

このコマンドは、すでにキャッシュ内にプロジェクトの環境がある場合には影響しません。ローカル環境を作成するには、まずキャッシュ内のすべての既存の環境を削除してください。

これにより、作業ディレクトリに.venvフォルダが作成され、これを.gitignoreファイルに追加する必要があります。

ポエトリーを使った依存関係の管理

依存関係の管理はPoetryの得意とするところです。依存関係を指定、インストール、管理するための包括的な機能を提供し、厄介な依存関係の競合に陥ることがないようにします。

このセクションでは、依存関係の追加とインストール、依存関係グループの作成、pyproject.toml内の依存関係の指定構文、ロックファイルについて学びます。

Poetry での依存関係の追加

Poetryを使用する際は、poetry add パッケージ名コマンドを使用して、PyPIからパッケージをインストールします。pip installの代わりに使用します。これにはいくつかの利点があります:

  1. 正しいバージョンの制約とともにパッケージを自動的にpyproject.tomlに追加
  2. 再現性のあるビルドを確保するためにロックファイルを更新
  3. 依存関係を解決して競合を避けます
  4. パッケージとそのすべての依存関係を仮想環境にインストールします

たとえば、最初にNumpyを依存関係として追加しましょう:

$ poetry add numpy

すぐに、インストールされているNumpyバージョンがPythonバージョンと互換性がないという依存関係解決の競合が発生します。その理由は、Python 3.11環境に切り替えた際に、pyproject.tomlファイルを更新しなかったためです。現在、ファイルは次のようになっています:

[tool.poetry.dependencies] python = "^3.8" requests = "^2.32.3" beautifulsoup4 = "^4.12.3"

キャレット記号 ^ は、 explore-poetry プロジェクトが Python 4 までの任意のバージョンと互換性があることを示すために使用されますが、Numpy のバージョン範囲は Python 3.8 から 3.12 の間のみサポートしており、これはより狭い範囲です。この衝突エラーはその事実から生じています。

したがって、エラーを修正するには、Python のバージョン範囲を次のように更新する必要があります:

python = ">=3.8, <3.12"

この変更を行うと、poetry add numpyコマンドが期待どおりに動作するはずです。

これは、Poetryの最高の機能の一つを観察したことになります。パッケージのインストール前にバージョンの競合をキャッチすることで、後でバージョンの非互換性について通知するのではなく、pipのように。

依存関係のバージョンを指定する構文

詩は強力な構文を使用して、依存関係の最良の同期のための幅広いバージョンを指定します。ここでは、最もよく使用される記号があります:

  1. キャレット (^): パッチおよびマイナーアップデートを許可しますが、メジャーアップデートは許可しません。例: ^1.2.3 は、1.2.3から1.9.9への更新を許可しますが、2.0.0は許可しません。
  2. チルダ (~): パッチアップデートのみを許可します。例: ~1.2.3 は、1.2.3から1.2.9への更新を許可しますが、1.3.0は許可しません。
  3. 正確なバージョン: 正確なバージョン番号を指定します。例: 1.2.3 はバージョン1.2.3のみを許可します
  4. より大きい (>): 指定されたバージョンよりも上の任意のバージョンを許可します。例: >1.2.3 は1.2.4、1.3.0、2.0.0などを許可します。
  5. 未満(<):指定されたバージョンよりも下の任意のバージョンを許可します。例: <2.0.0 は2.0.0未満を許可します。
  6. 以上(>=):指定されたバージョンとそれ以上を許可します。例: >=1.2.3 は1.2.3以上のバージョンを許可します。
  7. 等しいかそれ以下 (<=): 指定されたバージョンとそれ以下を許可します。例: <=2.0.0は2.0.0およびそれ以下のバージョンを許可します。
  8. バージョン範囲: 制約をカンマで組み合わせます。例: >=1.2.3,<2.0.0は1.2.3から1.9.9までのバージョンを許可します。
  9. ワイルドカード(*):任意のバージョンに一致します。例:1.2.* 1.2 で始まる任意のバージョンに一致します

もちろん、必要に応じてこれらを組み合わせることができます。

Poetry で依存関係グループを作成する

多くの移動部品を持つ複雑なプロジェクトでは、さまざまなカテゴリの依存関係を扱うことがよくあります。

例えば、機械学習プロジェクトでは、データの取り込み、データのクリーニング、特徴量エンジニアリング、モデルのトレーニング、デプロイメント、モニタリングのために異なるパイプラインやコンポーネントを作成することがよくあります。さらに、ドキュメントの作成やテストの実行も行わなければなりません。これらのすべてのステップにはそれぞれのツールエコシステムがあり、依存関係を混在させると最終的な配布パッケージが膨らんでしまいます。

Poetryを使用すると、任意の名前の依存関係グループを作成して、必要な時にのみインストールできます。さらに、パッケージのユーザーは必要なパーツのみをインストールすることもできます。

$ poetry add --group ui streamlit plotly dash $ poetry add --group dev black flake8 isort mypy pylint

上記のコマンドは2つの依存関係グループ、uidev(存在しない場合)、およびpyproject.toml内の2つのサブテーブルを作成します:

[tool.poetry.dependencies] python = "^3.11" requests = "^2.32.3" beautifulsoup4 = "^4.12.3" numpy = "^2.1.3" [tool.poetry.group.ui.dependencies] streamlit = "^1.39.0" plotly = "^5.24.1" dash = "^2.18.2" [tool.poetry.group.dev.dependencies] black = "^24.10.0" flake8 = "^7.1.1" isort = "^5.13.2" mypy = "^1.13.0" pylint = "^3.3.1"

依存関係グループが分離されていても、それらは依然として互いに解決されます。つまり、dev依存関係がuiパッケージと競合している場合、Poetryはインストールを実行しません。

場合によっては、オプションの依存関係グループを作成したり、既存のグループをオプションにして、ユーザーがプロジェクト環境を再作成する際にデフォルトでインストールされないようにすることがあります。これを行うには、pyproject.tomlファイル内に新しいサブテーブルを作成する必要があります。以下は、uiグループをオプションにする例です:

[tool.poetry.group.ui] optional = true [tool.poetry.group.ui.dependencies] streamlit = "^1.39.0" plotly = "^5.24.1" dash = "^2.18.2"

オプションをtrueに設定することで、パラメータを指定した後にグループの依存関係を宣言します。

poetry.lockファイルを使用してPoetryプロジェクトを再現

GitHubリポジトリをクローンしてPoetryプロジェクトを含む場合、1つのコマンドを実行することでプロジェクトの仮想環境の完璧なコピーを再作成できます:poetry install

インストールコマンドは、より包括的なpoetry.lockファイルを使用します。 ロックファイルには、

  • メインの依存関係の正確なバージョンは、pyproject.toml
  • メインの依存関係の依存関係(推移的依存関係)の正確なバージョン

例えば、requestsは、urllib3certificharset-normalizerおよびidnaに依存しています。ロックファイルがないと、これらのサブ依存関係は異なるバージョンで解決される可能性があります。

ロックファイルは、チーム全員が同じ依存関係のバージョンを取得することを保証し、”私のマシンでは動作します” の問題を防ぎます。

poetry add と poetry install の違い

addinstall の Poetry コマンドの違いを、ユースケースを交えて説明します。

たとえば、あなたが詐欺検出プロジェクトに取り組んでいるとします。初期の依存関係を追加します:

$ poetry add pandas scikit-learn

これにパッケージをロックおよびpyproject.tomlファイルに追加します。その後、同僚がリポジトリをクローンします:

$ git clone fraud-detection-repo-link $ cd fraud-detection $ poetry install

彼らはinstallコマンドを実行して、ロックファイルにリストされているすべてをインストールします。

後で新しいパッケージを追加する必要があります:

$ poetry add xgboost

同僚が変更を取得します:

$ git pull $ poetry install

彼らは新しいパッケージをインストールするために install コマンドを実行します。したがって、

  • 新しい依存関係を追加するときは poetry add を使用してください
  • プロジェクトをセットアップする必要がある場合は、poetry installを使用します
  • 常にpyproject.tomlpoetry.lockをバージョン管理にコミットしてください

poetry installコマンドで依存関係グループをインストール

以前、Poetryで依存関係をグループ化する方法を学びました。 poetry installを実行すると、デフォルトですべてのオプション以外のグループがインストールされますが、すべてのケースで望ましい結果とは限りません。

たとえば、リポジトリをドキュメントの作業にのみクローンしたい場合があります。または、ドキュメントやテストの側面を除いてリポジトリのメインコードで作業したい場合もあります。 installコマンドは、これらすべてのケースをカバーする柔軟性があります:

特定のグループを除外する:

$ poetry install --without ui,dev

オプションのグループをインストールする:

# オプションのドキュメントグループをインストール $ poetry install --with docs

特定のグループのみをインストール:

$ poetry install --only ui

プロジェクトのランタイム依存関係のみをインストールする(グループ外で言及された依存関係、単純なpoetry add package コマンドで追加されます):

$ poetry install --only main

Poetryでの依存関係の削除

依存関係を削除するのは簡単です。removeコマンドを使用します:

$ poetry remove requests

これにより、requestsがメインプロジェクトの依存関係から削除されます。グループ依存関係からパッケージを削除するには、--groupタグを再度使用できます:

$ poetry remove streamlit --group ui

removeコマンドは、パッケージとその推移的な依存関係をきれいにアンインストールします。

Publishing a Project with Poetry to PyPI

プロジェクトが配布の準備ができている場合、PyPI(Python Package Index)に公開すると、他の開発者が簡単にコードをインストールして使用できます。pipを介して。Poetryは、たった2つのコマンドでこのプロセスを完全に簡単にします:

$ poetry build # ディストリビューションのビルド $ poetry publish # PyPIに公開

ただし、これらのコマンドを実行する前に、PyPIの資格情報を正しく設定する必要があります。まず、以下でアカウントを作成してください:

  1. PyPI
  2. TestPyPI

詩を資格情報と共に構成します:

$ poetry config pypi-token.pypi your-pypi-token $ poetry config pypi-token.testpypi your-test-pypi-token

今、まずパッケージをテストしてください:

# TestPyPIリポジトリを構成 $ poetry config repositories.testpypi https://test.pypi.org/legacy/ # TestPyPIに公開 $ poetry build $ poetry publish -r testpypi

TestPyPI に公開した後、パッケージをインストールして、すべてが正常に動作するかをテストできます:

$ pip install --index-url https://test.pypi.org/simple/ your-package-name

すべてが正常であれば、PyPI 自体に公開できます:

$ poetry publish

Poetry との作業時のベストプラクティス

Poetry を使用する際には、多くの落とし穴やベストプラクティスがあります。もちろん、1つの記事ですべてを網羅することはできませんが、すぐに適用できる一般的なものをいくつかご紹介します:

  1. 常に仮想環境を使用する — Poetry は各プロジェクトに自動的にそれらを作成します
  2. pyproject.tomlファイルをバージョン管理下に保持しますが、ライブラリ用のpoetry.lockを除外します。
  3. 再現性のあるビルドを確保するために、アプリケーション用のpoetry.lockをバージョン管理に含めます
  4. パッケージのバージョンにはセマンティックバージョニング(major.minor.patch)を使用してください。 poetry version patch/minor/major コマンドを使用してパッケージのバージョンを1つ増やすことができます。 たとえば、poetry version major0.2.01.0.0に変更します。 pyproject.toml ファイル内で行ってください。
  5. 依存関係のバージョン制約を注意深く指定して、競合を回避します
  6. 定期的に poetry update を使用して依存関係を更新しますが、更新後は十分にテストしてください
  7. 開発用の依存関係を別々に保つために、poetry add --group dev を使用します
  8. コメントを使用して、pyproject.toml内のすべての依存関係の目的を文書化します
  9. 実行 poetry check コミット前に pyproject.toml 構文を検証します。また、 pre-commit フック も検討できます。
  10. 必要に応じてpoetry export を使用して requirements.txt を生成します。
  11. 本番依存関係を最小限に抑えましょう — オプション機能はextrasに移動させます
  12. 公開前にクリーンな環境でパッケージのインストールをテストしてください
  13. メインのPyPIリポジトリに公開する前にTestPyPIを使用してください
  14. バージョンの変更履歴を追跡するために明確なCHANGELOG.mdを維持してください
  15. 正しい環境の使用を確実にするためにスクリプトの実行にpoetry runを使用してください

結論と次のステップ

ポエトリーは、一般的なパッケージ管理の課題に対する堅牢で直感的な解決策を提供することで、Pythonの依存関係管理を革新しました。依存関係の解決、仮想環境の管理、プロジェクトの公開に関する強力な機能は、現代のPython開発にとって貴重なツールです。

Python開発の旅を続けるために、これらの包括的な学習パスを探索することを検討してください。

プロのPython開発の1つの側面として効果的な依存関係管理を忘れないでください。開発者として成長するにつれて、Poetryなどのツールがより保守性の高い信頼性のあるPythonプロジェクトの構築に役立ちます。

Source:
https://www.datacamp.com/tutorial/python-poetry