Rustで作るPythonパッケージの例 sampleproject-rs の紹介

Rustで作るPythonパッケージの例 sampleproject-rs の紹介

Event:

Pythonの多様性 深掘りLT Night

Presented:

2025/10/22 nikkie

お前、誰よ?

../_images/uzabase-white-logo.png

宣伝(運営に関わっているもの)

Rustで書かれたPythonパッケージを 作れる ようになりたい

uv, Ruff:

RustをバイナリにしてPyPIで配布

Pydantic:

Rustで書いたコードをPythonから呼び出せる

目標に近づくために sampleproject-rs で素振り💪

https://pypi.org/project/sampleproject-rs/

sampleproject、知っている方?🙋

https://pypi.org/project/sampleproject/

☝️ uvx --from sampleproject sample

% uvx --from sampleproject sample
Call your main application code here

✌️ sample.simple.add_one()

% uv run --with sampleproject \
    python -c "from sample import simple; print(simple.add_one(1))"
2

Python パッケージのサンプル

私のsampleproject-rs

sampleprojectにインスパイアされ、爆誕させた

☝️ uvx --from sampleproject-rs sample

% uvx --from sampleproject-rs sample
Call your main application code here

✌️ sample.simple.add_one()

% uv run --with sampleproject-rs \
    python -c "from sample import simple; print(simple.add_one(1))"
2

Rust実装 で完全再現です!!

https://github.com/ftnext/sampleproject-rs

fn main() {
    println!("Call your main application code here");
}

#[pyfunction]
fn add_one(number: i32) -> i32 {
    number + 1
}

sampleproject-rs からの学び

  • maturin

  • PyO3

1️⃣ maturin build でPythonパッケージになる [1]

  • maturinは、Rustで書かれたビルドバックエンド

pyproject.toml
[build-system]
requires = ["maturin>=1.8,<2.0"]
build-backend = "maturin"

[tool.maturin]
bindings = "bin"  # バイナリの指定
strip = true

Rustによるバイナリがパッケージに

% # git checkout 0.1.0
% cargo run --quiet
Call your main application code here
% file target/debug/sample
target/debug/sample: Mach-O 64-bit executable arm64
% target/debug/sample
Call your main application code here

Python製パッケージと違って 環境ごとのビルド が必要 [2]

  • GitHub Actions(Ubuntu環境)で maturin build してPyPIに上げたら、macOSでは実行できず

% uvx --from sampleproject-rs sample
× No solution found when resolving tool dependencies:
╰─▶ Because only sampleproject-rs==0.0.1 is available and
    sampleproject-rs==0.0.1 has no wheels with a matching platform tag
    (e.g., `macosx_14_0_arm64`), we can conclude that all versions of
    sampleproject-rs cannot be used.

2️⃣ PyO3 でRustプログラムをPythonから呼び出せるようにした

use pyo3::prelude::*;

#[pyfunction]
fn add_one(number: i32) -> i32 {
    number + 1
}

#[pymodule]
mod sample {
    use super::*;

    #[pymodule]
    mod simple {
        #[pymodule_export]
        use super::add_one;
    }
}

合わせて sample コマンドはPythonスクリプトに変更 [3]

pyproject.toml
[project.scripts]
sample = "sample:main"

[tool.maturin]
bindings = "pyo3"  # "bin"から変更

まとめ🌯:Rustで作るPythonパッケージの例 sampleproject-rs の紹介

Rustで書いたプログラムは

  • maturin でバイナリとしてPyPIから配布できる

  • PyO3 でPythonプログラム中で呼び出せる

ご清聴ありがとうございました

Happy Python development🫶

Appendix:関連発表 [4]