2 min read

Rust 製ツールを PyPI 経由で使えるようにする

時雨堂では複数の MP4 ファイルを合成して一つのファイルにする CLI ツールを Rust で開発し、OSS (Apache-2.0) として公開しています。

映像と音声を扱うこともあり、LLM との相性もいいのですが、いかんせん CLI ということでインストールもめんどくさいし、 Python から使うのもめんどくさいです。

これを解決するため、uv 経由でインストールして、Python からサクサクっと使えるようにしました。

当たり前ですが uv はインストールされている前提です。

uv tool install hisui

まずはすぐに使えるようにと uv tool install というグローバルにうまいことインストールしてくれる仕組みで使えるようにしました。

これは Maturin という Rust 製ツールを PyPI に登録するツールを使えばすぐです。

pyproject.toml を設定してuv run maturin build --release --compatibility pypiこれで終わりです。

色々省略してますが build-backend を maturin にしてあとは uv sync や uv run 時にビルドが走らないように tool.uv.package は false にします。

Rust でビルドしたバイナリをそのままうまく使うために tool.maturin.bindings を "bin" してください。

pyproject.toml

[build-system]
build-backend = "maturin"
requires = ["maturin>=1.9,<2.0"]

[tool.uv]
package = false

[tool.maturin]
bindings = "bin"
strip = true
python-source = "python"

[tool.maturin.target.aarch64-apple-darwin]
macos-deployment-target = "14.0"

ほとんど設定がいらないのも良い

maturin build

$ uv run maturin build --release --compatibility pypi --no-default-features
🍹 Building a mixed python/rust project
🔗 Found bin bindings
📡 Using build options bindings from pyproject.toml
💻 Using `MACOSX_DEPLOYMENT_TARGET=14.0` for aarch64-apple-darwin by configuration
   Compiling proc-macro2 v1.0.103
   Compiling unicode-ident v1.0.22
   Compiling indicatif v0.18.2
   Compiling quote v1.0.41
   Compiling syn v2.0.109
   Compiling prettyplease v0.2.37
   Compiling bindgen v0.72.1
   Compiling hisui v2025.4.0 (/Users/voluntas/shiguredo/hisui)
    Finished `release` profile [optimized] target(s) in 1m 01s
📦 Built wheel to /hisui/target/wheels/hisui-2025.4.0-py3-none-macosx_14_0_arm64.whl

開発中に使う maturin develop も便利

あとはさくさくっと whl ファイルができます、これを GitHub Actions 経由で PyPI に登録すれば終わりです。

$ uv tool install hisui
Resolved 1 package in 969ms
Prepared 1 package in 2.78s
Installed 1 package in 4ms
 + hisui==2025.4.0.dev0
$ hisui --version
hisui 2025.4.0-dev.0

さくさくっとインストールできる

uv add hisui

これだけだとただツールが使えるだけですが、Maturin は Python と Rust のハイブリッドもうまいことやってくれます。pyproject.toml の python-source = "python" がまさにそれです。ルートディレクトリに python ディレクトリを作成し、その下に普通に Python プロジェクトを作成できます。

その状態で PyPI に登録してしまいます。

$ uv init spam
Initialized project `spam` at `/spam`
$ cd spam
$ uv add hisui
Using CPython 3.13.7
Creating virtual environment at: .venv
Resolved 2 packages in 7ms
Prepared 1 package in 761ms
Installed 1 package in 2ms
 + hisui==2025.4.0.dev0

さくっと uv add できる

$ uv run python3
Python 3.13.7 (main, Sep  2 2025, 14:05:52) [Clang 20.1.4 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hisui
>>> h = hisui.Hisui()
>>> h.list_codecs()
{'codecs': [{'name': 'OPUS', 'type': 'audio', 'decoders': ['opus'], 'encoders': ['opus']}, {'name': 'AAC', 'type': 'audio', 'decoders': [], 'encoders': ['audio_toolbox']}, {'name': 'VP8', 'type': 'video', 'decoders': ['libvpx'], 'encoders': ['libvpx']}, {'name': 'VP9', 'type': 'video', 'decoders': ['libvpx'], 'encoders': ['libvpx']}, {'name': 'H264', 'type': 'video', 'decoders': ['video_toolbox'], 'encoders': ['video_toolbox']}, {'name': 'H265', 'type': 'video', 'decoders': ['video_toolbox'], 'encoders': ['video_toolbox']}, {'name': 'AV1', 'type': 'video', 'decoders': ['dav1d'], 'encoders': ['svt_av1']}], 'engines': [{'name': 'audio_toolbox'}, {'name': 'dav1d', 'repository': 'https://github.com/videolan/dav1d.git', 'build_version': '1.5.1'}, {'name': 'libvpx', 'repository': 'https://github.com/webmproject/libvpx.git', 'build_version': 'v1.15.2'}, {'name': 'opus', 'repository': 'https://github.com/xiph/opus.git', 'build_version': 'v1.5.2'}, {'name': 'svt_av1', 'repository': 'https://gitlab.com/AOMediaCodec/SVT-AV1.git', 'build_version': 'v3.1.2'}, {'name': 'video_toolbox'}]}

あとはコマンドラインツールのラッパーを呼び出せば Python から使える

雑感

Maturin 本当によくできています。情報がほとんどありませんが、コマンド自体がシンプルなので困ることはないと思います。PyPI 経由で利用できることで「使うまでの距離」を一気に縮められることができました。

LLM での利用を想定する場合、ほぼ Python 一択になるため、uv 経由で色いろいろできるのは便利です。

おまけ

uv tool install でインストールした場合に便利なところはアンインストールが uv tool uninstall でできるのも便利です。

さらに uv tool install hisui --upgrade でバージョンアップも簡単に出来てしまいます。最新がなりをダウンロードして置き換えて貰う必要すらありません。