こんにちは!開発現場の裏側を支えるアーキテクトの先輩です。
今回は、Pythonの大規模開発において避けて通れない「複数パッケージ(モノレポ)の管理」についてお話しします。
「アプリを作っているうちに機能が肥大化し、共通ロジックを別のフォルダに切り出したら、依存関係の管理がぐちゃぐちゃになった……」
そんな地獄のような経験、ありませんか?
「毎回 `pip install -e .` なんてやってられない!」
「共通ライブラリを更新したのに、アプリ側で反映されているのか分からない!」
そんな悩みを一発で解決し、毎日のコーディングを劇的に楽にしてくれるのが、今回解説する Poetryの「ワークスペース(Workspace)」機能 です。これをマスターすれば、複数のPythonパッケージを美しく、かつ強固に同じ仮想環境下で統御できるようになります。
初心者の方でも迷わないよう、基礎の基礎から実際のモノレポ構築まで、優しくロジカルに手を取って解説していきますね。
—
1. Poetryとは何か?なぜ大規模開発で選ばれるのか
まずは、私たちが普段使っているPythonのパッケージ管理を少し振り返ってみましょう。
昔ながらの `requirements.txt` は、バージョン固定が甘くなりがちで、依存関係の衝突(依存地獄)を頻繁に引き起こしました。その救世主として現れたのが Poetry です。
Poetryが提供する3つの圧倒的メリット
1. 厳密な依存関係の解決 (`poetry.lock`):
裏側で高度なリゾルバが働き、パッケージ同士の依存矛盾を検知してくれます。Node.jsの `npm` や Rustの `Cargo` に近い、極めてモダンな体験です。
2. 仮想環境の自動管理:
プロジェクトごとに仮想環境を自動生成・紐付けするため、「今どのPython環境にいるんだっけ?」という混乱がなくなります。
3. ワークスペース(複数パッケージ管理)への対応:
今回の本丸です。1つのリポジトリ(モノレポ)の中に複数の独立したPythonパッケージを同居させ、お互いをローカル参照させながら、統一された仮想環境でテストやビルドを行えます。
—
2. 開発環境のセットアップと基礎知識
まずはPoetryが手元にない、あるいはバージョンが古いという方向けに、確実なインストール方法から押さえましょう。
Poetryのインストール
公式推奨のインストーラーを使います。ターミナル(Mac/Linux/Git Bash等)を開き、以下を実行してください。
公式インストーラーのダウンロードと実行(独立した環境に安全にインストールされます)
curl -sSL https://install.python-poetry.org | python3 –
パスを通す設定(お使いのシェルに合わせて ~/.zshrc や ~/.bashrc に追記されます)
export PATH=”$HOME/.local/bin:$PATH”
インストールができたら、`poetry –version` でバージョンが表示されることを確認してください。
—
3. 実践!モノレポ構成のワークスペースを作る
ここからが本題です。
今回は、「共通ライブラリ(core-lib)」 と 「Web APIアプリケーション(api-app)」 の2つを1つのリポジトリ(モノレポ)で管理する構成を作ってみましょう。
ディレクトリ構造としては、以下のようなイメージを目指します。
my-monorepo/
├── pyproject.toml # 全体を束ねるルート設定(Poetry 2.0+のワークスペース機能を使用)
├── packages/
│ ├── core-lib/ # 共通処理パッケージ
│ │ ├── pyproject.toml
│ │ └── core_lib/
│ │ └── __init__.py
│ └── api-app/ # アプリケーションパッケージ
│ ├── pyproject.toml
│ └── api_app/
│ └── main.py
ステップ1: ルートディレクトリの作成とワークスペースの設定
まずはルートディレクトリを作り、Poetryのワークスペース機能を有効にします。Poetry(バージョン1.8.3以降や、まもなく主流になるPoetry 2.0系)では、ルートの `pyproject.toml` で複数のメンバーパッケージを定義できます。
ルートディレクトリに移動し、`pyproject.toml` を作成します。
my-monorepo/pyproject.toml
[tool.poetry]
ルート自体はパッケージとしてビルドしないため、falseに設定します
package-mode = false
[tool.poetry.workspace]
このモノレポに含まれるサブパッケージのパスを指定します
members = [
“packages/”
]
- ここがポイント: `package-mode = false` にすることで、このルートディレクトリは「純粋な管理用コンテナ」として振る舞い、個別のパッケージを束ねる司令塔になります。
ステップ2: 共通ライブラリ (`core-lib`) の作成
次に、共通ライブラリを作ります。`packages` フォルダの中に移動して、新規パッケージを初期化しましょう。
mkdir -p packages
cd packages
poetry new core-lib
生成された `packages/core-lib/pyproject.toml` を開き、名前を確認・調整します。
packages/core-lib/pyproject.toml
[tool.poetry]
name = “core-lib”
version = “0.1.0”
description = “大規模開発向けの共通ロジックパッケージ”
authors = [“Your Name
readme = “README.md”
[tool.poetry.dependencies]
python = “^3.10”
必要に応じて、このライブラリ特有の依存関係(例: pydanticなど)をここに書きます
pydantic = “^2.0.0”
[build-system]
requires = [“poetry-core>=2.0.0”]
build-backend = “poetry.core.masonry.api”
中身のコードとして、`packages/core-lib/core_lib/__init__.py` に簡単な関数を書いておきます。
packages/core-lib/core_lib/__init__.py
def get_app_banner() -> str:
“””モノレポ全体で共有されるバナー文字列を返す”””
return “=== Enterprise Microservice Architecture v1.0 ===”
ステップ3: アプリケーション (`api-app`) の作成と内部依存の解決
次に、同じ `packages` ディレクトリにAPIアプリケーションを作ります。
cd packages
poetry new api-app
ここで重要なのが、「`api-app` から `core-lib` をどうやって参照するか?」です。
従来のやり方だと、相対パス指定や `pip install -e ../core-lib` などを駆使していましたが、Poetryのワークスペース環境下では、驚くほどシンプルに記述できます。
`packages/api-app/pyproject.toml` を以下のように編集してください。
packages/api-app/pyproject.toml
[tool.poetry]
name = “api-app”
version = “0.1.0”
description = “Core-libを利用するメインAPI”
authors = [“Your Name
readme = “README.md”
[tool.poetry.dependencies]
python = “^3.10”
★ここでローカルの core-lib を直接指名します!
core-lib = { path = “../core-lib”, develop = true }
fastapi = “^0.110.0”
uvicorn = “^0.28.0”
[build-system]
requires = [“poetry-core>=2.0.0”]
build-backend = “poetry.core.masonry.api”
- 解説 (`develop = true`): `develop = true`(または `editable = true`)を指定することで、`core-lib` のソースコードを書き換えた際、再インストールを挟むことなく、瞬時に `api-app` 側へ変更が反映されます(開発効率が劇的に上がる瞬間です!)。
動作確認用のコードを `packages/api-app/api_app/main.py` に書きましょう。
packages/api-app/api_app/main.py
from fastapi import FastAPI
from core_lib import get_app_banner # 共通ライブラリからインポート!
app = FastAPI()
@app.get(“/”)
def read_root():
return {
“banner”: get_app_banner(),
“message”: “Hello from API App inside Monorepo!”
}
—
4. 精度高い動作確認:魔法のコマンド群
環境が整いました。それでは、モノレポ全体で依存関係を解決し、アプリケーションを動かしてみましょう。
1. 依存関係の一括ロックとインストール
驚くべきことに、Poetryのワークスペースでは、ルートディレクトリ(一番大元の階層)で一度コマンドを叩くだけで、配下のすべてのパッケージの依存関係を解析し、一つの強固な仮想環境を構築してくれます。
一番最初の `my-monorepo/` ディレクトリに戻り、以下のコマンドを実行してください。
ルートに戻る
cd ../..
依存関係の解決と仮想環境へのインストールを一撃で行う
poetry install
【内部で何が起きているか?】
Poetryはワークスペースの定義を読み込み、`core-lib` と `api-app` の依存関係を同時に解決します。そして、ルート直下に単一の `poetry.lock` を生成し、すべてのパッケージが整合性の取れた同じ仮想環境を共有できるようにセットアップします。
2. アプリケーションの起動と動作確認
共通ライブラリの関数が、正しくAPIアプリから呼び出せるか確認してみましょう。仮想環境を有効にするか、`poetry run` を使ってUvicornを起動します。
api-appの文脈で uvicorn を実行する
poetry run uvicorn api_app.main:app –reload –app-dir packages/api-app
ブラウザで `http://127.0.0.1:8000/` にアクセスするか、別タブで以下のようにcurlを叩いてみてください。
curl http://127.0.0.1:8000/
【期待される出力】
{
“banner”: “=== Enterprise Microservice Architecture v1.0 ===”,
“message”: “Hello from API App inside Monorepo!”
}
おめでとうございます!`core-lib` の関数が `api-app` にシームレスに組み込まれ、完璧に動作していることが確認できました。
—
5. CI/CDパイプラインでの個別テスト戦略
大規模開発において、モノレポの最大の懸念点は「CI(継続的インテグレーション)が重くなる・複雑になる」という点です。
「一部のコードを変えただけなのに、全パッケージのテストを走らせるのは時間がもったいない」ですよね。
Poetryを使えば、各サブパッケージのディレクトリに移動して、個別にテストやビルドを実行することが非常に容易です。GitHub ActionsなどのCI/CD環境では、以下のようにパスごとのステップを組むのがベストプラクティスです。
CI設定(GitHub Actionsのイメージ抜粋)
.github/workflows/ci.yml のイメージ
name: CI
on: [push]
jobs:
test-core-lib:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python & Poetry
uses: actions/setup-python@v5
with:
python-version: ‘3.10’
- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python3 –
# core-lib だけのテストを効率よく走らせる
- name: Test core-lib
run: |
cd packages/core-lib
poetry install
poetry run pytest
test-api-app:
runs-on: ubuntu-latest
needs: test-core-lib
steps:
- uses: actions/checkout@v4
- name: Set up Python & Poetry
uses: actions/setup-python@v5
with:
python-version: ‘3.10’
- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python3 –
# ワークスペース全体をルートでインストールして api-app のテストを走らせる
- name: Test api-app
run: |
poetry install
cd packages/api-app
poetry run pytest
このように、ワークスペースの恩恵を受けてルートで一括インストールしつつ、実行時は各パッケージのコンテキストに絞ってテストを回すことで、CIの速度と保守性を極限まで高めることができます。
—
6. おわりに:毎日のコーディングを劇的に楽にするために
今回は、Poetryのワークスペース機能を用いた大規模マルチパッケージ管理の極意を解説しました。
- 複数のパッケージを1つのリポジトリで安全に同居させる方法
- `develop = true` によるシームレスなローカル依存解決
- ルートでの一括ロックと、現場で役立つテスト戦略
これらを身につければ、コードの重複とはおさらばし、美しくモジュール化されたスケーラブルなPythonアーキテクチャを手に入れることができます。
「ファイルを書き換えた瞬間にテストが通る」「依存関係のコンフリクトに怯えなくていい」――この快適な開発体験を、ぜひ今日のあなたのプロジェクトから導入してみてください。毎日のコーディングが、きっと劇的に変わりますよ。