🙌

Pythonプロジェクトをpyproject.tomlとPoetryで始める方法

に公開

Pythonプロジェクトを始める際、依存関係の管理やプロジェクトの設定をどうしていますか?
従来のrequirements.txtvenvを使った方法もありますが、現代的なPython開発ではpyproject.tomlとPoetryを使うことが推奨されています。

今回は、pyproject.tomlとPoetryを使ったプロジェクトの始め方と、従来のvenvとの比較について紹介します。


🚨 問題:従来のPythonプロジェクト管理の課題

従来のPythonプロジェクト管理では、以下のような課題がありました:

  • requirements.txt では依存関係の詳細な管理が困難
  • venv の作成・管理が手動で面倒
  • プロジェクトの設定が散らばりがち
  • 依存関係の解決が複雑
  • 開発環境と本番環境の違いが分かりにくい

🆕 解決策:pyproject.toml + Poetry

現代的なPythonプロジェクトでは、pyproject.tomlとPoetryを使うことで、これらの課題を解決できます。

pyproject.tomlとは

  • Pythonプロジェクトの設定を一元管理するファイル
  • PEP 518で標準化された形式
  • 依存関係、ビルド設定、ツール設定などを含む

Poetryとは

  • Pythonの依存関係管理とパッケージングツール
  • 仮想環境の自動管理
  • 依存関係の解決を自動化

🛠 方法1:基本的なPoetryプロジェクトの作成

まずは、Poetryを使って基本的なプロジェクトを作成する方法を紹介します。

1. Poetryのインストール

# macOS/Linux
curl -sSL https://install.python-poetry.org | python3 -

# Windows (PowerShell)
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -

2. 新しいプロジェクトの作成

# 新しいプロジェクトを作成
poetry new my-project

# または既存のディレクトリで初期化
cd my-project
poetry init

3. 生成されるファイル構造

my-project/
├── pyproject.toml          # プロジェクト設定
├── README.md              # プロジェクト説明
├── my_project/            # ソースコード
│   ├── __init__.py
│   └── my_project.py
└── tests/                 # テストコード
    ├── __init__.py
    └── test_my_project.py

4. pyproject.tomlの基本構造

[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.8"

[tool.poetry.group.dev.dependencies]
pytest = "^6.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

🔄 方法2:依存関係の管理

Poetryを使った依存関係の管理方法を紹介します。

1. 依存関係の追加

# 本番用の依存関係を追加
poetry add requests

# 開発用の依存関係を追加
poetry add --group dev pytest black flake8

# 特定のバージョンを指定
poetry add "requests>=2.25.0,<3.0.0"

2. 依存関係の削除

# 依存関係を削除
poetry remove requests

# 開発用の依存関係を削除
poetry remove --group dev pytest

3. 依存関係の確認

# インストールされている依存関係を表示
poetry show

# 依存関係ツリーを表示
poetry show --tree

4. 仮想環境の管理

# 仮想環境を作成・アクティベート
poetry shell

# 仮想環境内でコマンドを実行
poetry run python main.py

# 仮想環境の場所を確認
poetry env info

📊 方法3:venvとの比較

従来のvenvとPoetryの比較を表で示します。

項目 venv + requirements.txt Poetry + pyproject.toml
仮想環境の作成 手動で作成 自動で作成・管理
依存関係の管理 requirements.txtで手動管理 pyproject.tomlで自動管理
依存関係の解決 pipが基本 高度な解決アルゴリズム
開発用依存関係 requirements-dev.txtなど グループで分離
ロックファイル なし(pip freeze) poetry.lockで固定
パッケージング setup.pyが必要 pyproject.tomlで完結
学習コスト 低い 中程度

venvのメリット

  • シンプルで理解しやすい
  • Python標準の機能
  • 学習コストが低い

venvのデメリット

  • 手動での管理が必要
  • 依存関係の解決が複雑
  • プロジェクト設定が散らばる

Poetryのメリット

  • 自動化された管理
  • 高度な依存関係解決
  • 統一された設定ファイル
  • ロックファイルによる再現性

Poetryのデメリット

  • 学習コストが中程度
  • 追加のツールが必要
  • 一部の古いプロジェクトとの互換性

✅ 完全版の実践例

実際のプロジェクトで使える、完全な設定例を紹介します。

1. プロジェクトの初期化

# プロジェクトを作成
poetry new my-web-app
cd my-web-app

# 依存関係を追加
poetry add fastapi uvicorn
poetry add --group dev pytest black flake8 mypy

2. 完全なpyproject.toml

[tool.poetry]
name = "my-web-app"
version = "0.1.0"
description = "A modern Python web application"
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"
packages = [{include = "my_web_app"}]

[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.104.0"
uvicorn = {extras = ["standard"], version = "^0.24.0"}

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
black = "^23.0.0"
flake8 = "^6.0.0"
mypy = "^1.5.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.black]
line-length = 88
target-version = ['py38']

[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
addopts = "-v --tb=short"

3. 基本的なアプリケーションコード

# my_web_app/main.py
from fastapi import FastAPI

app = FastAPI(title="My Web App")

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

4. テストコード

# tests/test_main.py
from fastapi.testclient import TestClient
from my_web_app.main import app

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"message": "Hello World"}

def test_read_item():
    response = client.get("/items/42")
    assert response.status_code == 200
    assert response.json() == {"item_id": 42}

5. 開発ワークフロー

# 開発環境の起動
poetry shell

# コードのフォーマット
poetry run black .

# リント
poetry run flake8 .

# 型チェック
poetry run mypy .

# テストの実行
poetry run pytest

# アプリケーションの起動
poetry run uvicorn my_web_app.main:app --reload

🧭 おわりに

pyproject.tomlとPoetryを使うことで、現代的なPythonプロジェクト管理が可能になります。

推奨する使い分け

  • 新しいプロジェクト: Poetry + pyproject.toml
  • 既存の小規模プロジェクト: venv + requirements.txt
  • チーム開発: Poetry + pyproject.toml
  • 学習・実験: venv + requirements.txt

次のステップ

https://zenn.dev/goshawk/articles/b9079495fb9377

Poetryは最初は少し複雑に感じるかもしれませんが、一度使い方を覚えると、プロジェクト管理が格段に楽になります。ぜひ試してみてください!

Discussion