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

UVとPEP 723の楽しみ

2025年6月25日原文(cottongeeks.com)

概要

uv は高速なPythonパッケージ・プロジェクト管理ツールで、Rust製。 PEP 723 により、スクリプト内に依存関係やPythonバージョンを記述可能。 uvxuv run を使えば、依存関係のセットアップ不要でワンオフスクリプト実行が容易。 YouTubeトランスクリプト抽出など、実用的な例も紹介。 従来よりPythonスクリプト実行のハードルが大幅に低減。

uvとPEP 723の活用

  • uv はRust製の高速Pythonパッケージ・プロジェクト管理ツール
    • Node/NPMの npx のような uvx コマンドを提供
    • 必要なPythonバージョンや依存関係を自動セットアップ
  • PEP 723 はPythonスクリプト内にメタデータ(依存関係やバージョン)を埋め込む仕様
    • スクリプト上部に requires-pythondependencies を記述
    • スクリプト単体で実行環境の再現が可能
  • uv runuvx を使うことで、事前準備不要で即座にスクリプト実行
    • 例:$ uvx ruff --versionで依存パッケージを即時インストール・実行
    • 例:$ uv run pep.pyでPEP 723メタデータ付きスクリプトをワンコマンド実行
  • スクリプト例:YouTube動画のトランスクリプト抽出
    • シェバン行:#!/usr/bin/env -S uv run --scriptでuvを明示
    • 必要なパッケージやPythonバージョンもスクリプト内メタデータで宣言
    • 実行方法:chmod +x ytt後、./ytt <YouTube URLまたは動画ID>で即実行

PEP 723メタデータ記載例

  • スクリプト冒頭に以下のように記述

    # /// script
    # requires-python = ">=3.11"
    # dependencies = [
    #   "requests<3",
    #   "rich",
    # ]
    # ///
    
    • 依存パッケージやバージョン条件を明示
    • 外部ツールやIDEがこの情報を利用可能

uv runによるワンオフスクリプト実行

  • uv run <スクリプト名>で依存関係を自動インストール後に実行
    • 例:uv run pep.py
      • 必要パッケージを24msでインストール
      • スクリプトの結果を即座に出力

YouTubeトランスクリプト抽出スクリプト例

  • シェバン行でuv run --scriptを指定
  • PEP 723メタデータでyoutube-transcript-api依存を宣言
  • コマンドライン引数でYouTube URLまたは動画IDを受け取り、トランスクリプトを取得・表示
  • 実行例:./ytt https://www.youtube.com/watch?v=zgSQr0d5EVg
    • 必要パッケージを10msでインストールし、トランスクリプトを即出力

Pythonワンオフスクリプトの新時代

  • これまでGoなどの自己完結型バイナリが一発実行に便利だった
  • uvPEP 723 の組み合わせで、Pythonスクリプトも同等の利便性を獲得
  • 例:YouTubeトランスクリプト抽出サーバーをPythonで即席実装
    • Githubリポジトリ: cottongeeks/ytt-mcp

参考リソース

まとめ

  • uvPEP 723 でPythonスクリプト実行が圧倒的に手軽
  • 依存関係やバージョン管理をスクリプト内で完結
  • ワンオフツールや小規模自動化に最適な選択肢

Hackerたちの意見

uvはちょっとしたサイドプロジェクトに使うには最高だね。uv runuv tool run、つまりuvxを組み合わせることで、GitHubからPythonスクリプトを超簡単に取得して、VM内にインストールして実行できるんだ。git cloneも、venvの作成やエントリー、pip installもいらない。そしてuvは速い — 本当に速い。pipよりも10倍速く動くから、何かおかしいのかと思っちゃうくらい。実際には、ちゃんと自分が望んでいたことをやってくれてるんだけどね。ドキュメントはちょっと荒削りだけど、それでも十分使う価値があると思ってるよ。

本当にそうだね。uvは、pyenvが自分の--help出力を表示するよりも早く依存関係を解決してインストールしてくれる。

本当に素晴らしいね。どんどん人気が出てきてるみたい。最初にsimonwのブログで見たんだ:https://simonwillison.net/2024/Dec/19/one-shot-python-tools/ それから、3月には別のブログ記事についての議論もあったよ:https://news.ycombinator.com/item?id=43500124 これがしばらくフロントページに残って、もっと広まるといいな。

ようやくPythonスクリプトが仮想環境を探し回らなくても動くようになった感じだね。今度は誰かがシェルスクリプトでも同じことをやってくれたらいいのに。シェルの世界では、パッケージング、依存関係管理、再現性がまだ石器時代に留まってる。今はまだcurl | bashでうまくいくことを祈るか、12の手動ステップと3つの欠けてる依存関係があるREADMEを頼りにするしかない。確かにNixはあるけど…時間や空間、Nixのマニュアルを超えてるなら別だけどね。Docker?素晴らしいけど、sedを動かすためにLinuxディストリビューションをダウンロードするのが合理的だと思えるならね。もっとシンプルで宣言的、人間向けに作られた中間的な解決策が必要だよ。

シェルスクリプトをPythonに移植することを考えてみたら?言語としては圧倒的に優れてるし、subprocess.check_callもそんなに悪くないよ。

Homebrewでできるかな?

新しいシェルスクリプトを書く必要があるの?依存関係をインストールできるなら、uvを使えばいいよ、あとはそれがやってくれるから。あと、https://babashka.org/にも惚れかけてるから、Clojureが好きならチェックしてみて!

シェルの世界では、パッケージ管理や依存関係の管理、再現性がまだ石器時代にいる感じだよね。個人的にはこのままでいいと思う。だって、そういうものが必要なスクリプトは、シェルを使うにはもう遅すぎるから。シェルスクリプトは小さくて、20行くらいが理想だよ。言語自体が使う価値がないくらいひどいから、大きなものには向かないよね。

シェルスクリプトの依存関係を解決する特定のケースでは、Nixは実際にすごく簡単だよ。スクリプトをパッケージするのはwriteShellApplicationコールで、実行するのはnix runだし。問題は、その特定のことをどうやってやるかが誰も文書化してないから、Nix全体を学ぼうとしないといけないことかな。だから、君が考えてることはこのNixのロジックのラッパーになるかもしれないね。

これにはresholveを使ってNixを使ってるけど、すごく気に入ってるよ。

この特定のユースケースに関しては、Nixはそんなに難しくないと思う。別のディストリビューションにNixをインストールするのは結構簡単だし、インストールしたらこんな感じで使えるよ。

#! /usr/bin/env nix-shell
#! nix-shell -i bash -p imagemagick cowsay
# 画像を50%にスケール
convert "$1" -scale 50% "$1.s50.jpg" && cowsay "done $1.q50.jpg"

確かにNixOSやNixのパッケージングは挑戦だけど、シェルスクリプトに使う分にはそんなに悪くないよ。

反応せずにはいられないんだけど、明らかに解決策はNixをDockerでシェルとして実行することだね。パッケージング、依存関係管理、再現性が理論的な最大値になるから。

Hacker Newsで議論の続きを見る