官方readme

官方入门教程 api文档

下面有任何有疑问的接口中的名称都直接去api文档中搜索

在Python中使用Rust

PyO3用来生成原生 Python 模块,最简单的方法是使用maturin,这是一个用最少配置发布基于 Rust 的 Python 包的工具。新建一个测试用的文件夹

# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ pip install maturin

在上述string_sum文件夹中初始化maturin

$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
  ✨ Done! New project created string_sum

可以看到生成了新包的source,最重要的文件时Cargo.tomllib.rs,大约文件中看起来是这样的

Cargo.toml

[package]
name = "string_sum"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
name = "string_sum"
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]

[dependencies]
pyo3 = "0.18.1"

src/lib.rs

#![allow(unused)]
fn main() {
use pyo3::prelude::*;

/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
    Ok((a + b).to_string())
}

/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pymodule]
fn string_sum(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}
}

最后,终端输入maturin develop。这会创建一个 package 然后安装进当前的 Python 环境,然后这个 package 就能在 Python 里用了

$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'

在Rust中使用Python

将 Python 嵌入为 Rust 二进制,你要确保你的 Python 安装包含了一个共享库(ensure that your Python installation contains a shared library?啥意思)。

cargo new 新建一个项目并像这样将 pyo3 加入到 Cargo.toml 中,

[dependencies.pyo3]
version = "0.18.1"
features = ["auto-initialize"]

下面的例子会输出 sys.version 的值以及当前用户名

use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

fn main() -> PyResult<()> {
    Python::with_gil(|py| {
        let sys = py.import("sys")?;
        let version: String = sys.getattr("version")?.extract()?;

        let locals = [("os", py.import("os")?)].into_py_dict(py);
        let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
        let user: String = py.eval(code, None, Some(&locals))?.extract()?;

        println!("Hello {}, I'm Python {}", user, version);
        Ok(())
    })
}

如果 cargo run 后出现Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding,上面信息中应该还有PYTHONHOME: not set, PYTHONPATH: not set的信息,应该将使用的 Python 解释器路径加入到系统环境中,比如 Annconda 则将 Annaconda 文件夹路径创建为 PYTHONHOME,其下的 python.exe 路径创建为 PYTHONPATH

工具和库

  • maturin Build and publish crates with pyo3, rust-cpython or cffi bindings as well as rust binaries as python packages
  • setuptools-rust Setuptools plugin for Rust support.
  • pyo3-built Simple macro to expose metadata obtained with the built crate as a PyDict
  • rust-numpy Rust binding of NumPy C-API
  • dict-derive Derive FromPyObject to automatically transform Python dicts into Rust structs
  • pyo3-log Bridge from Rust to Python logging
  • pythonize Serde serializer for converting Rust objects to JSON-compatible Python objects
  • pyo3-asyncio Utilities for working with Python's Asyncio library and async functions
  • rustimport Directly import Rust files or crates from Python, without manual compilation step. Provides pyo3 integration by default and generates pyo3 binding code automatically.

例子

  • autopy A simple, cross-platform GUI automation library for Python and Rust.
    • Contains an example of building wheels on TravisCI and appveyor using cibuildwheel
  • ballista-python A Python library that binds to Apache Arrow distributed query engine Ballista.
  • bed-reader Read and write the PLINK BED format, simply and efficiently.
    • Shows Rayon/ndarray::parallel (including capturing errors, controlling thread num), Python types to Rust generics, Github Actions
  • cryptography Python cryptography library with some functionality in Rust.
  • css-inline CSS inlining for Python implemented in Rust.
  • datafusion-python A Python library that binds to Apache Arrow in-memory query engine DataFusion.
  • deltalake-python Native Delta Lake Python binding based on delta-rs with Pandas integration.
  • fastbloom A fast bloom filter | counting bloom filter implemented by Rust for Rust and Python!
  • fastuuid Python bindings to Rust's UUID library.
  • feos Lightning fast thermodynamic modeling in Rust with fully developed Python interface.
  • forust A lightweight gradient boosted decision tree library written in Rust.
  • html-py-ever Using html5ever through kuchiki to speed up html parsing and css-selecting.
  • hyperjson A hyper-fast Python module for reading/writing JSON data using Rust's serde-json.
  • inline-python Inline Python code directly in your Rust code.
  • jsonschema-rs Fast JSON Schema validation library.
  • mocpy Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere.
  • orjson Fast Python JSON library.
  • ormsgpack Fast Python msgpack library.
  • point-process High level API for pointprocesses as a Python library.
  • polaroid Hyper Fast and safe image manipulation library for Python written in Rust.
  • polars Fast multi-threaded DataFrame library in Rust | Python | Node.js.
  • pydantic-core Core validation logic for pydantic written in Rust.
  • pyheck Fast case conversion library, built by wrapping heck.
    • Quite easy to follow as there's not much code.
  • pyre Fast Python HTTP server written in Rust.
  • ril-py A performant and high-level image processing library for Python written in Rust.
  • river Online machine learning in python, the computationally heavy statistics algorithms are implemented in Rust.
  • rust-python-coverage Example PyO3 project with automated test coverage for Rust and Python.
  • tiktoken A fast BPE tokeniser for use with OpenAI's models.
  • tokenizers Python bindings to the Hugging Face tokenizers (NLP) written in Rust.
  • wasmer-python Python library to run WebAssembly binaries.

Articles and other media