Zenn
😶‍🌫️

uvでライブラリのinstallが必要なスクリプトを実行する方法

2025/02/07に公開

概要

uvだとglobalのpythonが使えない(2025/02/07)
その場合でもライブラリのinstallが必要なpythonスクリプトを手軽に実行する方法がある

参考文献

方法1 --with を利用する

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

ログインするとコメントできます