uvでライブラリをグルーピングして最小限の依存関係で起動できるようにする
始めに
Pythonに限らずアプリケーションを大規模で運用していくほどライブラリの依存関係が増えていきます。その時にAPIとバッチ等の用途に応じたアプリケーションごと分割する方法もありますが二重管理が面倒になります。JavaではGradleを使用してマルチプロジェクト構成にしておくことで、必要なライブラリだけで起動するようにできました。
今回の記事では、Pythonのuvを使用してライブラリをグルーピングすることで、必要なライブラリを最小限にする方法を記載します。
環境
- Python
- 3.13
- uv
- 0.7.2
実装
ライブラリのグルーピング
dependency-groups
に分割したい単位で集約します。今回の場合は、dependencies
で全アプリケーションに依存させたいライブラリを残し、他はapi
, auth
, worker
, dev
に分割しました。
[project]
dependencies = [
"sqlmodel>=0.0.21",
"pydantic[email]>=2.9.2",
]
[dependency-groups]
api = [
"fastapi[standard]>=0.115.12"
]
auth = [
"pyjwt>=2.8.0",
"pyotp>=2.9.0",
]
worker = [
"celery>=5.5.2",
]
dev = [
"ruff>=0.7.3"
]
なお、該当のグループにライブラリを追加するときは次のコマンドで入れられます。下手に手でpyproject.toml
をいじるより、uvに任せてグループを作ってから少しずつ移行するのがオススメです。
uv add --group dev pytest
使用方法
uv sync
時に必要なグループだけ指定してください。なお、uvの仕様でdev
は特に指定がない限りインストールされるので、明示的な除外が必要です。
# api (+dev)だけインストール
uv sync --group api
# api と auth (+dev)だけインストール
uv sync --group api --group auth
# dev を除外したい
uv sync --no-group dev
# 全部対象
uv sync --all-groups
なお、開発環境でグループを指定してインストールさせる指定をするのは面倒なので、pyproject.toml
にデフォルトインストール対象も記載しておくと便利だと思います。
[tool.uv]
# 全部指定する場合
default-groups = "all"
# インストール対象を絞りたいときに
#default-groups = ["api", "auth", "dev"]
uv sync
ソースコード
終わりに
Pythonはインストールイメージのサイズが大きくなりがちなので、こういうことでサイズを削減したいと考えています。ただ、ライブラリ管理を厳密にやったことで実行時に必要なライブラリが読み込まれていないエラーが発生する可能性もあるので、実際に本番運用に適用するかは悩んでいます。
ただ、バッチ処理ではFastAPIは不要ですし、少しでも起動が早いほうが正義だと思うので、CI/CDの管理工数も考えて本番にも取り入れていきたいです。
Discussion