uv — 高速なPythonパッケージ・プロジェクトマネージャー
概要
uv は Astral 社が提供する単一バイナリで、Python ワークフロー全体をカバーします。クロスプラットフォームなロックファイル (uv.lock) を備えたプロジェクト、インライン依存関係を持つ単一ファイルスクリプト、コマンドラインツール (uvx)、Python インタプリタのインストール、およびドロップイン (そのまま使える) の uv pip インターフェースを提供します。必要に応じて Python 自体もダウンロードするため、マシンに必要なものは uv だけです。
使用方法
インストール
# パッケージマネージャーを使用
pipx install uv
brew install uv
winget install --id=astral-sh.uv -e
Astral 社はパッケージマネージャーのないマシン向けにスタンドアロンインストーラーも公開しています。インストールページ https://docs.astral.sh/uv/getting-started/installation/ に現在のコマンドとチェックサムがあります。
uv --version
uv self update # スタンドアロンインストーラーのみ。それ以外はパッケージマネージャーでアップグレード
特定のリリースに固定するには、インストーラーURLにバージョンを指定します: https://astral.sh/uv/0.12.21/install.sh
プロジェクトを作成する
uv init dispatch-api # パッケージ化されたアプリ: src/dispatch_api/、uv_build バックエンド、コンソールスクリプト
uv init --no-package cron-jobs # フラットレイアウト (main.py あり、ビルドシステムなし)
uv init --lib geo-utils # py.typed マーカー付きライブラリ
uv init --bare --python 3.12 # カレントディレクトリに pyproject.toml のみ作成
uv init は .python-version、README.md、.gitignore も書き込み、git を初期化します。--bare は pyproject.toml だけを作成するため、既存のリポジトリ内で使用するのに適しています。
依存関係を管理する
uv add 'httpx>=0.27' 'pydantic>=2.7,<3' # 実行時依存関係
uv add --dev pytest ruff # dev グループ (本番環境には含めない)
uv add --group docs mkdocs # 任意の名前付き依存関係グループ
uv add --optional postgres 'psycopg[binary]' # オプション依存関係: pip install dispatch-api[postgres]
uv add -r requirements.txt # 既存の requirements ファイルをインポート
uv remove httpx
uv lock --upgrade-package pydantic # 制約内で1つのパッケージをバンプ
uv lock --upgrade # すべてをバンプ
uv tree --outdated --depth 1 # 新しいリリースがあるものを表示
最初の uv add で .venv/ と uv.lock が作成されます。変更のたびに pyproject.toml、ロックファイル、環境が同時に更新されます。
実行と同期
uv run pytest # 必要に応じてロックと同期を行い、.venv 内で実行
uv run python -m dispatch_api
uv run --with rich python -c "import rich" # このコマンドのみ追加パッケージを使用
uv sync # すべて (dev グループも含む) をインストール
uv sync --locked # CI: uv.lock が pyproject.toml と一致しない場合は失敗
uv sync --frozen --no-dev # 本番: uv.lock をそのまま使用、dev グループはスキップ
uv sync --extra postgres
uv lock --check # ロックファイルが古い場合は非ゼロで終了
アクティベーションは不要です。uv run は自動的にプロジェクト環境を見つけます。
インライン依存関係を持つスクリプト
uv init --script fetch-rates.py --python 3.12
uv add --script fetch-rates.py 'httpx<1' rich
uv run fetch-rates.py
uv lock --script fetch-rates.py # 再現可能な実行のために fetch-rates.py.lock を作成
uv add --script はファイルの先頭にメタデータブロックを維持します:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx<1",
# "rich>=15.0.0",
# ]
# ///
最初の行に #!/usr/bin/env -S uv run --script を追加し、chmod +x で直接実行可能にします。
ツール
uvx ruff check . # インストールせずに実行。uvx = uv tool run
uvx [email protected] check . # 特定のバージョン
uvx --from 'markitdown[pdf]' markitdown q3-board-report.pdf # コマンド名がパッケージ名と異なる場合
uv tool install ruff # 恒久的に、PATH 上に分離してインストール
uv tool upgrade --all
uv tool list
uv tool uninstall ruff
インストールされたツールは uv tool dir --bin で表示されるディレクトリに配置されます。そのディレクトリが PATH にない場合、uv が警告を表示します。
Python バージョン
uv python install 3.12 3.13
uv python list --only-installed
uv python pin 3.12 # .python-version に書き込み
uv run --python 3.13 pytest # 別のインタプリタで一時的に実行
uv python upgrade 3.12 # 3.12 の最新パッチリリースにアップグレード
uv venv --python 3.12 # .venv にプレーンな仮想環境を作成
指定方法: 3.12、3.12.3、>=3.11,<3.13、[email protected]、3.13t (フリースレッド) が使用可能です。uv は不足しているインタプリタを自動的にダウンロードします。--no-python-downloads を指定するとダウンロードを禁止できます。
pip 互換インターフェース
uv venv
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt --universal
uv pip sync requirements.txt # リストにないものは削除
uv pip install --python .venv/bin/python 'rich>=13'
CI と Docker
name: ci
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.21"
enable-cache: true
- run: uv python install
- run: uv sync --locked --all-extras --dev
- run: uv run pytest
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.12.21 /uv /uvx /bin/
WORKDIR /app
ENV UV_NO_DEV=1 UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
# 依存関係を先にコピー。uv.lock が変更されるまでこのレイヤーは再利用される
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv uv sync --locked
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "-m", "dispatch_api"]
.dockerignore に .venv を追加してください。ホスト環境はイメージ内では動作しません。
例
例1: requirements.txt を使用するサービスをロック付きの uv プロジェクトに移行
依頼: 「dispatch-api リポジトリに requirements.txt と requirements-dev.txt があります。uv に移行してロックファイルを作成し、テストを実行できるようにしてください。」
cd dispatch-api
uv init --bare --python 3.12
uv python pin 3.12
uv add -r requirements.txt
sed '/^-r /d' requirements-dev.txt | uv add --dev -r -
uv run python -m pytest -q
uv run ruff check .
結果: pyproject.toml に5つの実行時パッケージと dev グループがリストされ、uv.lock が30のパッケージを固定し、チェックに合格します。出力の抜粋:
Initialized project `dispatch-api`
Pinned `.python-version` to `3.12`
+ uvicorn==0.34.0
+ pytest==8.3.4
+ ruff==0.8.6
1 passed, 1 warning in 0.12s
All checks passed!
例2: 自己完結型スクリプト
依頼: 「環境を設定せずに任意のサーバーにコピーして実行できるディスク使用量レポートスクリプトを作成してください。」
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["rich>=13"]
# ///
import shutil
from rich.console import Console
from rich.table import Table
usage = shutil.disk_usage("/")
table = Table(title="Disk usage")
table.add_column("Total GB")
table.add_column("Free GB")
table.add_row(f"{usage.total / 1e9:.0f}", f"{usage.free / 1e9:.0f}")
Console().print(table)
chmod +x disk-report.py
./disk-report.py
結果: uv は初回実行時に rich を使用したキャッシュ環境を構築し、テーブルを表示します。2回目以降は即座に実行されます。
Disk usage
┏━━━━━━━━━━┳━━━━━━━━━┓
┃ Total GB ┃ Free GB ┃
┡━━━━━━━━━━╇━━━━━━━━━┩
│ 3936 │ 2211 │
└──────────┴─────────┘
ガイドライン
uv.lockと.python-versionをコミットしてください。uv.lockを手動で編集しないでください。pyproject.tomlを変更するか、uv add、uv remove、uv lockを使用してください。--lockedまたは--frozen:--lockedはロックファイルを検証し、古い場合は失敗するため CI に適しています。--frozenはチェックをスキップし、ファイルの内容をそのままインストールします。uv syncは正確で、uv runはそうではありません。uv syncはロックファイルにないパッケージ (uv pip installで追加したものを含む) を削除します。uv runは不足しているものだけを追加します。uv pipは探索によってターゲットを決定します: アクティブなVIRTUAL_ENV、次にカレントディレクトリまたは最も近い親ディレクトリの.venvを使用します。間違ったフォルダから実行すると、別の環境にインストールしてしまう可能性があります。スクリプトでは--pythonに環境パスを指定してください。- フラットプロジェクトと pytest:
--bareまたは--no-packageの場合、プロジェクト自体はインストールされないため、uv run pytestはModuleNotFoundErrorで失敗する可能性があります。uv run python -m pytestを使用するか、[tool.pytest.ini_options]にpythonpath = ["."]を設定してください。 uv initのデフォルトはパッケージ化されたsrc/レイアウトです。main.pyを使用するスクリプトスタイルのプロジェクトには--no-packageを指定してください。- 実験的なコマンド:
uv format、uv check、uv auditは変更される可能性があるという警告を表示します。これらに基づいたパイプラインはまだ構築しないでください。 - プライベートインデックス:
[[tool.uv.index]]で宣言し、インデックス名に基づいた環境変数 (例: インデックス名がinternalの場合、UV_INDEX_INTERNAL_USERNAMEとUV_INDEX_INTERNAL_PASSWORD) で認証情報を渡します。これらをコミットしないでください。デフォルトのfirst-index戦略は依存関係の混乱を防ぎます。unsafe-best-matchは避けてください。 - サプライチェーン:
uv run、uvx、およびインラインメタデータを含むスクリプトはパッケージをダウンロードして実行します。信頼できないソースからのスクリプトは、実行前に依存関係リストを確認してください。 uv self updateはスタンドアロンインストーラーでインストールした場合のみ機能します。- CI キャッシュ: キャッシュを保存する前に
uv cache prune --ciを実行して、キャッシュを小さく保ってください。 - 使用すべきでない場合: uv は Python パッケージインデックス、git、ローカルパスからインストールします。conda パッケージやシステムライブラリはインストールしないため、それらに依存するスタックには conda を引き続き使用してください。