😶🌫️
uvでライブラリのinstallが必要なスクリプトを実行する方法
概要
uvだとglobalのpythonが使えない(2025/02/07)
その場合でもライブラリのinstallが必要なpythonスクリプトを手軽に実行する方法がある
参考文献
--with
を利用する
方法1 test.pyを用意する
import time
from rich.progress import track
for i in track(range(20), description="For example:"):
time.sleep(0.05)
通常のように uv run test.py
で実行すると ModuleNotFoundError: No module named 'rich'
となって怒られる
--with rich
をつけて実行
uv run --with rich example.py
結果
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:01
無事実行できた
この方法ではpythonスクリプトはそのままだが、実行時のパラメータを覚えておく必要がある
ちなみに --no-project
をつけるとプロジェクト内でも独立して実行できる
PEP 723 – Inline script metadata を利用する
Inline script metadataとは、以下のような /// script
で囲まれる部分のこと
# /// script
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
example.pyを利用して実行してみる
uv run example.py
結果
Reading inline script metadata from `example.py`
Installed 9 packages in 11ms
[
│ ('1', 'PEP Purpose and Guidelines'),
│ ('2', 'Procedure for Adding New Modules'),
│ ('3', 'Guidelines for Handling Bug Reports'),
│ ('4', 'Deprecation of Standard Modules'),
│ ('5', 'Guidelines for Language Evolution'),
│ ('6', 'Bug Fix Releases'),
│ ('7', 'Style Guide for C Code'),
│ ('8', 'Style Guide for Python Code'),
│ ('9', 'Sample Plaintext PEP Template'),
│ ('10', 'Voting Guidelines')
]
Inline script metadataの作り方
実行は楽だが、毎回 /// script
を書くのはしんどい
実はuvコマンドで自動挿入する方法もある
before.py
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
このbefore.pyに --script
を使ってみる
uv init --script before.py
実行例
❯ uv init --script before.py
Initialized script at `before.py`
❯ cat before.py
# /// script
# requires-python = ">=3.12"
# dependencies = []
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
また、ライブラリが決まっている場合はaddが便利
uv add --script example.py 'requests<3' 'rich'
出力
❯ uv add --script before.py 'requests<3' 'rich'
Updated `before.py`
❯ cat before.py
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests<3",
# "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
Discussion