世界を動かす技術を、日本語で。

Uv: 依存関係を持つスクリプトの実行

2025年7月22日原文(docs.astral.sh)

概要

  • uv はPythonスクリプトの依存関係管理と実行を自動化するツール
  • 仮想環境の手動管理なしで スクリプトごとに依存関係を分離
  • インラインメタデータ やコマンドライン引数で依存関係を宣言可能
  • 依存関係のロック や再現性向上のための機能も搭載
  • Shebang やGUIスクリプト、異なるPythonバージョンにも対応

uvによるPythonスクリプトの実行と依存関係管理

  • Pythonスクリプト は、通常 python <script>.py の形式で実行

  • uv を利用することで、依存関係の管理や仮想環境の構築を自動化

  • Python環境 ごとにパッケージを分離することで、スクリプト間の干渉を防止

  • uv run コマンドで依存関係のないスクリプトを即時実行可能

    • 例:
      • example.py
        print("Hello world")
        
      • $ uv run example.py
        Hello world
        
  • 標準ライブラリのみ利用 の場合も追加作業不要

  • 引数の受け渡し標準入力からのスクリプト実行 もサポート

  • プロジェクトディレクトリpyproject.tomlが存在)では、デフォルトでプロジェクトの依存関係もインストール

    • プロジェクト依存を無視するには --no-project オプションを利用

依存関係付きスクリプトの実行

  • 追加パッケージ が必要な場合、--withオプションで依存関係を指定
    • 例:
      • $ uv run --with rich example.py
  • バージョン指定複数依存関係 も対応
  • プロジェクト依存と組み合わせ も可能だが、--no-projectで除外可能

インラインメタデータによるスクリプト管理

  • Python標準のインラインメタデータ で依存関係やPythonバージョンをスクリプト冒頭に宣言

  • uv init --scriptで雛形を作成

  • uv add --scriptで依存関係を追加・更新

    • TOML形式でスクリプト冒頭に記載される

      # /// script
      # dependencies = [
      #   "requests<3",
      #   "rich",
      # ]
      # ///
      
  • インラインメタデータ利用時 はプロジェクト依存は無視される(--no-project不要)

  • requires-python で必要なPythonバージョンも宣言可能

  • 依存関係なし の場合も空リスト必須

シェバングによる実行ファイル化

  • シェバング#!/usr/bin/env -S uv run --script)でスクリプトを直接実行可能
  • 実行権限を付与後、./greetのようにコマンドとして利用
  • インラインメタデータ と組み合わせて依存宣言も可能

代替パッケージインデックス

  • --index オプションでPyPI以外のインデックス利用可能
  • インラインメタデータにインデックス情報が追加される
  • 認証が必要な場合 は公式ドキュメント参照

依存関係のロックと再現性向上

  • uv lock --script で依存関係を.lockファイルに固定
  • ロックファイルが存在する場合、以降の操作はロック内容を再利用
  • exclude-newer フィールドでパッケージ取得日を制限し、将来の実行時の再現性を担保
    • RFC 3339形式で日時指定

Pythonバージョンの指定

  • --python オプションで任意のPythonバージョンを指定して実行
  • 未インストールの場合は自動ダウンロード
  • 詳細は公式ドキュメント参照

GUIスクリプトの対応

  • .pyw拡張子 のファイルはWindowsでpythonwを使用して実行
  • 依存関係付きGUIスクリプト--withオプションで対応

次のステップ

  • さらなる詳細は コマンドリファレンスuvのツール実行・インストール方法 のガイドを参照

Hackerたちの意見

これが僕の絶対のお気に入りのuv機能で、uvに切り替えた理由でもあるんだ。git-hooksに依存関係のあるスクリプトがいくつかあって、メインのvenvには入れたくないんだよね。#!/usr/bin/env -S uv run --script --python 3.13 この機能のおかげで、独自のvenvを作らずに依存関係を使えるようになったし、開発者には「brew install uv」って指示を出すだけで済むんだ。

正直、これはすごい(すごすぎる)機能だと思う。

完全に同意だね。UVのおかげで、たくさんのPythonをGolangに移行する予定だった大きなプロジェクトがストールしちゃった。まだたくさん移行されるけど、小さなスクリプトみたいなものはもう範囲外になったね。

ちょっとお邪魔しますが、-Sフラグが必要な理由って誰か知ってる?BSD環境で試してみたけど、/usr/bin/env -S uv run --python 3.11 python/usr/bin/env uv run --python 3.11 pythonは同じことをする(Pythonのインタラクティブシェルを起動する)んだ。envのマニュアルページはあまり明確じゃないし、最終的な結果が同じに見えるんだよね(「与えられた文字列を複数の文字列に分割し、各結果の文字列をenvユーティリティへの別々の引数として処理する...」)。

「スクリプトの依存関係を宣言する」っていうのがめちゃくちゃ便利だよね。https://docs.astral.sh/uv/guides/scripts/#declaring-script-d...

# /// script
# dependencies = [
# "requests

これをscript.pyとして保存すれば、「uv run script.py」で指定した依存関係を使って実行できるんだ。依存関係は一時的な仮想環境に自動でインストールされるから、全く考えなくていいのが魔法みたい。これはPythonのPEP 723の実装なんだよね。https://peps.python.org/pep-0723/ Claude 4はこのトリックを知ってるから、「インラインスクリプト依存関係付きのPythonスクリプトを書いて」って頼むと、ちゃんとやってくれる。例えば、https://claude.ai/share/1217b467-d273-40d0-9699-f6a38113f045 そこにあったプロンプトは、「httpxとclickを使って大きなファイルをダウンロードし、進捗バーを表示するインラインスクリプト依存関係付きのPythonスクリプトを書いて」だったんだ。Claude 4以前は、これをするための特別な指示を含むカスタムClaudeプロジェクトを持ってたけど、もう必要ないね。https://simonwillison.net/2024/Dec/19/one-shot-python-tools/

一瞬、requestsの横にハートの絵文字があるのかと思った。

PEP723はpipxやhatchでもサポートされてるけど、最近はuvが(当然ながら)注目を集めてるね。他にもpip-toolsがロードマップにサポートを持ってるよ。https://github.com/jazzband/pip-tools/issues/2027

シェバンモードもすごく便利で、実行ができるんだよね。例えば、./script.sh #!/usr/bin/env -S uv run --script # /// script # dependencies = [ # "requests

これクールだね! 同じようなことをGoでもやってみようかなって思ったけど、ちょっと怪しいアイデアだね: https://github.com/imjasonh/gos (別に推奨してるわけじゃないけど、どうなるか気になって試してみたら、まあまあうまくいったよ!)

これクールだけど、正直言うと魔法のコメントじゃなくて、組み込みの言語構文にしてほしいな。魔法のコメントってちょっとダサいし。いつかは…(組み込みの構文にするにはアーキテクチャ的な問題があるのは分かってるけど、魔法のコメントは外部ツールが解析しやすいし、Pythonのコアはパッケージや依存関係についての知識が限られてるから…でも、いつかは…)

おお、いいね!スクリプト内依存関係を持つuv専用のシェバンを使って幸せなユーザーだったけど、uv lock --script example.pyコマンドで特定のスクリプト用のロックファイルを作成できるのは、次のレベルに行った感じ!これがこんなに自然に感じるのに、Pythonのパッケージングが20年以上も経ってからようやく出てきたのはすごいよね。

単一のスクリプトで依存関係をロックする使い道は何なの? 俺の組織にとって便利なのは、ロックファイルに宣言された依存関係を例えばtrivy fs uv.lockでスキャンできること。これで既知のCVEが含まれているコードを実行していないか確認できるんだ。

Hacker Newsで議論の続きを見る