uvとPEP 723でPythonスクリプトを活用する
(cottongeeks.com)- uvパッケージマネージャーとPEP 723により、依存関係の問題なしでPythonスクリプトを実行できるようになった
- uvx機能は使い捨ての仮想環境を自動生成し、環境設定の煩わしさを解消する
- PEP 723メタデータをPythonファイルに含めると、スクリプトの自動実行とパッケージ管理が便利になる
- 実行スクリプト例として、YouTube字幕抽出プログラムをすばやく実装・配布できる
- これにより、Pythonでも簡潔な単一実行ファイル的スクリプト作成が可能になり、スクリプト活用性が大きく向上した
概要
- Pythonで「一回限りの(one-off)スクリプト」を実行するたびに、毎回環境設定やパッケージインストールが必要だった不便さが、uvとPEP 723の導入によって解消された
- uvはRustで開発された高速なPythonパッケージおよびプロジェクトマネージャーであり、新機能のuvxを含め、使い捨て仮想環境の設定、パッケージの自動インストール、Pythonバージョンの連携を非常に高速かつ簡単に処理する
uvとuvxの利点
- uvx機能はNode.jsエコシステムのnpxのように動作し、指定したPythonパッケージ(例: ruff)の実行環境をすばやく生成する
- 使い捨てのvirtual environmentをキャッシュとして活用し、オーバーヘッドなしで高速な実行を提供する
- 環境セットアップと依存関係のインストールが1行のコマンドで完結し、開発者は別途環境設定を管理する必要がない
PEP 723の紹介と活用
- PEP 723は、Pythonスクリプトの先頭に依存関係と環境メタデータを含められるようにする標準を定義している
- 例: コード先頭にrequires-python、dependenciesなどを記述できる
- これを認識する外部ツール(uvなど)は、スクリプトファイル内に書かれた情報をもとに、自動インストール、環境設定、実行を処理する
uvとPEP 723の組み合わせ
- 実際のPythonサンプルファイルの先頭にこのメタデータを記述し、uvのrunコマンドで実行すると、必要なすべてのパッケージが即座に自動インストールされ、指定したPythonバージョンの設定後にコードが実行される
- サンプルコードはインターネットAPI(PEP一覧)を呼び出して結果を出力する。追加のパッケージインストールや環境設定なしに1行で実行できる
実用例: YouTube字幕スクリプト
- shebang(
#!/usr/bin/env -S uv run --script)とPEP 723メタデータを追加したPythonスクリプト例を提示 - youtube-transcript-apiなどの外部パッケージの自動インストールと、仮想環境の自動セットアップを処理する
- ユーザーは実行ファイル(
ytt)にYouTube動画のURLまたはIDを引数として渡すだけで、字幕を抽出して結果を即座に得られる - chmodで実行権限を付与すれば、ターミナルから簡単に実行できる
開発者体験の改善と可能性の拡張
- 以前は単純なスクリプト実行でもGoなどの単一実行ファイルバイナリ言語が好まれがちだったが、今ではPythonも同等レベルの手軽さを提供できる
- uvとPEP 723の組み合わせにより、Pythonスクリプトの共有・配布・実行自動化が大幅に容易になった
- GitHubのサンプル(cottongeeks/ytt-mcp)を通じて、より複雑なユースケースも開発可能
2件のコメント
uv はものすごく速くて気に入っています。最近は、使えるところではできるだけどこでも uv を使っています。
Hacker Newsの意見
投稿者と同じく、最近はGoの代わりにクロスプラットフォームなPythonのワンオフ(one-off)や個人用スクリプトに手が伸びがちだが、Pythonの型チェックシステムがまさに混沌そのもので不満がある。tyやpyreflyのようなツールが少しでも改善してくれることを期待している
今ではPythonスクリプトがvirtualenvで苦労せず、そのまますんなり動く感じになってきた シェルスクリプトでもこういう体験が得られたらいいのにと思う パッケージング、依存関係管理、再現性は相変わらず石器時代のまま 今でも現実は、curl | bashで運任せにするか、欠けた依存関係3つと手動手順12個入りのREADMEしかないかのどちらか Nix? すでに時間と空間、そしてNixマニュアルを超越した人にだけ実用的な選択肢という感じ Docker? sedコマンドを1回使うためにLinuxディストリビューションをダウンロードするのが合理的に見えるなら悪くない選択 誰でも簡単に使える、シンプルで宣言的な中間地点がぜひ必要だと思う
本当にすばらしいトレンドで、ますます普及している感じ 最初はsimonwのブログで知り、simonwillisonのブログ記事で関連内容を確認した 今年3月には別のブログ投稿でも Hacker Newsの議論 があった こうしたトレンドがメインページに長く残って、もっと多くの人に認知されてほしい
uvを小さなプロジェクトで使ってみたが、本当にすばらしい体験 uv runとuv tool run(uvx)の組み合わせで、GitHub上のPythonスクリプトをvmでそのままインストールして実行するまでが超簡単 git cloneも、venvの作成や移動、pip installも不要 何よりuvが速すぎて、最初は何かおかしいのかと思うほどで、実際にはpipより10倍速い ただしツールとドキュメントはまだ少し未完成。それでもあれだけ革新的で実用的なら十分使う価値があるという立場
--help出力より依存関係のインストールのほうが速いことに感心したRustもこれに似た、単一ファイル型のシェルスクリプト的なアイデアを発展させている もともとRustでこういう方式(依存関係管理を含む単一ファイル実行サポート)を初めて見た このパターンがもっと多くの言語に定着してほしい。gistでやり取りしたり、素早く小さなツールを書いたりするのに非常に便利 cargo-script RFC文書 も参照
uv run --scriptを使うとき、メタデータをスクリプトに含めると、スクリプトからそのままPython REPLを立ち上げて修正を試すのが少し不便 たとえば次のようにする必要があるが、もう少し簡潔な方法があればいいのにと思う たとえば
のようにできればベストだが、実際には次のように実行するとスクリプトに合ったPythonおよびvenv環境にすぐ入れる
ただし一度はスクリプトを実行して環境を作る必要がある
--interactiveのようなフラグを入れてCLIオプション化できる Typerベースの小さなCLIはたいていこういう形でよく書いている devスクリプトでは--sqlフラグでDuckDBのSQL REPLに入ったこともあるcondaを使うなら、Pythonスクリプト用のshellラッパーで直接環境を有効化するやり方も可能 次のように書く
ただし、PEP 723スタイルのように独立したアプローチではない
昨日と今日のHNスレッドを見て、初めてuvを試すことにしたが、その速さと簡単な依存関係管理に深く感心した 公式ドキュメントが改善されればなおよさそう。特にrequirements.txtワークフローからuvへ移行するガイドがあると便利そう プロジェクトごとのPythonバージョン指定がやや混乱する部分でもある(
.python-versionとpyproject.tomlの2か所で定義)pyproject.tomlのrequires-versionフィールドは互換性を保証するバージョン範囲を意味し、.python-versionは開発に使う特定のバージョンを指定する uv initで作ると最初は同じに見えるが、時間がたつとrequires-versionは.python-versionより低い最小サポートバージョンを指定するようになる requires-versionはパッケージメタデータにも入り、配布したパッケージを使う他人の依存関係解決にも影響する たとえばv1は古いPython 3もサポートするが、v2ではしない場合など.python-versionはuvに対してだけ、自分の開発環境をセットアップするときにだけ参照させる用途 すでに作ってある環境があるなら、わざわざ新しく設定しなくても構わない uvはまだ公式ビルドバックエンドではないが、その機能を準備中(issue #3957).python-versionファイルの役割は、TOMLパーサーを持たない他ツール向けの互換性のため程度だと推測している以前、Pythonスクリプトが自力で依存関係をインストールするようにするツールを作ってみたいと思ったことがある (uvxのように動くツールを目標にしていたが、Pythonさえあれば動く方式) ただしスクリプトの先頭に、見た目に妙な行を何行も付けなければならないのが欠点 興味があれば、pypiでpysolateという名前で公開中
COBOLに着想を得たGrace Hopper流のメッセージ すべてのPythonプログラムにはENVIRONMENT divisionを定義し、コンパイルおよび実行環境(ハードウェア、ソフトウェア要件を含む)を明確に記す文化が必要だという主張 こうした構造は、さまざまなシステム間でのプログラム移植性向上に決定的な影響を与える