83个版本

0.22.2 2024年7月17日
0.22.0 2024年6月24日
0.21.0 2024年3月25日
0.20.1 2023年12月30日
0.1.0 2017年7月23日

#2 in FFI

Download history 529029/week @ 2024-05-03 563377/week @ 2024-05-10 589369/week @ 2024-05-17 503456/week @ 2024-05-24 483028/week @ 2024-05-31 572711/week @ 2024-06-07 540152/week @ 2024-06-14 580496/week @ 2024-06-21 452882/week @ 2024-06-28 533655/week @ 2024-07-05 594398/week @ 2024-07-12 627221/week @ 2024-07-19 628944/week @ 2024-07-26 770728/week @ 2024-08-02 895214/week @ 2024-08-09 961064/week @ 2024-08-16

3,383,436 每月下载量
用于 1,012 个包 (706 直接)

MIT/Apache

2MB
44K SLoC

PyO3

actions status benchmark codecov crates.io minimum rustc 1.63 discord server contributing notes

RustPython 的绑定,包括创建原生Python扩展模块的工具。支持在Rust二进制文件中运行和与Python代码交互。

用法

PyO3支持以下软件版本

  • Python 3.7及更高版本(CPython、PyPy和GraalPy)
  • Rust 1.63及更高版本

您可以使用PyO3在Rust中编写原生Python模块,或将Python嵌入到Rust二进制文件中。以下各节将分别解释这些用法。

从Python中使用Rust

PyO3可以用来生成原生Python模块。首次尝试的最简单方法是使用 maturinmaturin 是一个用于使用最小配置构建和发布基于Rust的Python包的工具。以下步骤安装 maturin,使用它生成和构建一个新的Python包,然后启动Python以导入和执行包中的函数。

首先,按照以下命令创建一个新目录,包含一个新的Python virtualenv,并使用Python的包管理器 pip 在虚拟环境中安装 maturin

# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin

仍然在这个 string_sum 目录中,现在运行 maturin init。这将生成新的包源。在选择要使用的绑定时,选择pyo3绑定

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

此命令生成的最重要的文件是 Cargo.tomllib.rs,它们大致如下所示

Cargo.toml

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

[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 = { version = "0.22.2", features = ["extension-module"] }

src/lib.rs

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(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

最后,运行 maturin develop。这将构建包并将其安装到先前创建和激活的 Python 虚拟环境中。然后该包即可通过 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 源代码,然后重新运行 maturin develop 以重新编译

要将所有这些内容作为一个单独的复制粘贴,请使用下面的 bash 脚本(将第一个命令中的 string_sum 替换为所需的包名)

mkdir string_sum && cd "$_"
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop

如果您想运行 cargo test 或在此项目的 Cargo 工作空间中使用该项目,并且遇到链接器问题,请参阅 常见问题解答 中的解决方案。

maturin 类似,您还可以使用 setuptools-rust手动 构建。两者都比 maturin 提供更多的灵活性,但需要更多的配置才能开始。

从 Rust 使用 Python

要将 Python 嵌入到 Rust 二进制文件中,您需要确保您的 Python 安装包含一个共享库。以下步骤演示了如何确保这一点(针对 Ubuntu),然后提供了一些示例代码,该代码运行一个嵌入的 Python 解释器。

在 Ubuntu 上安装 Python 共享库

sudo apt install python3-dev

在基于 RPM 的发行版(例如 Fedora、Red Hat、SuSE)上安装 Python 共享库,请安装 python3-devel 软件包。

使用 cargo new 开始一个新的项目,并将 pyo3 添加到 Cargo.toml,如下所示

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

示例程序显示 sys.version 的值和当前用户名

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

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

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

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

本指南有一个关于此主题的示例部分。

工具和库

  • maturin 使用 pyo3、rust-cpython 或 cffi 绑定以及 rust 二进制文件作为 Python 包构建和发布 crates
  • setuptools-rust 支持 Rust 的 setuptools 插件
  • pyo3-built 简单宏,将使用 built crate 获得的元数据作为 PyDict
  • rust-numpy NumPy C-API 的 Rust 绑定
  • dict-derive 派生 FromPyObject,将 Python 字典自动转换为 Rust 结构体
  • pyo3-log Rust 到 Python 日志的桥梁
  • pythonize 将 Rust 对象转换为与 JSON 兼容的 Python 对象的 Serde 序列化器
  • pyo3-asyncio 用于与 Python 的 Asyncio 库和异步函数一起工作的实用程序
  • rustimport 直接从 Python 导入 Rust 文件或 crates,无需手动编译步骤。默认提供 pyo3 集成并自动生成 pyo3 绑定代码。
  • pyo3-arrow pyo3 的轻量级 Apache Arrow 集成

示例

  • autopy Python 和 Rust 的简单、跨平台的 GUI 自动化库。
    • 包含在 TravisCI 和 AppVeyor 上构建轮子的示例,使用 cibuildwheel
  • ballista-python 一个将 Apache Arrow 分布式查询引擎 Ballista 绑定的 Python 库。
  • bed-reader 简单高效地读写 PLINK BED 格式。
    • 展示了 Rayon/ndarray::parallel(包括错误捕获、控制线程数),Python 类型到 Rust 泛型的转换,GitHub Actions
  • cryptography 具有一些 Rust 功能的 Python 加密库。
  • css-inline 在 Rust 中实现的用于 Python 的 CSS 内联。
  • datafusion-python 一个将 Apache Arrow 内存查询引擎 DataFusion 绑定的 Python 库。
  • deltalake-python 基于 delta-rs 的原生 Delta Lake Python 绑定,具有 Pandas 集成。
  • fastbloom 由 Rust 实现,用于 Rust 和 Python 的高效 bloom 过滤器 | 计数 bloom 过滤器。
  • fastuuid Rust 的 UUID 库的 Python 绑定。
  • feos 使用完全开发的 Python 接口的 Rust 中闪电般的物理解模。
  • forust 一个用 Rust 编写的轻量级梯度提升决策树库。
  • granian 适用于 Python 应用程序的 Rust HTTP 服务器。
  • greptimedb 数据库支持 Python 脚本
  • haem 用于生物信息学问题的 Python 库。
  • html-py-ever 通过 html5everkuchiki 使用来加速 HTML 解析和 CSS 选择。
  • hyperjson 使用 Rust 的 serde-json 读取/写入 JSON 数据的 Python 模块,速度极快。
  • inline-python 直接在 Rust 代码中嵌入 Python 代码。
  • johnnycanencrypt 带有 Yubikey 支持的 OpenPGP 库。
  • jsonschema-rs 快速 JSON Schema 验证库。
  • mocpy 提供用于描述单位球上任何任意覆盖区域的数值结构的 Python 天文库。
  • opendal 数据访问层,允许用户以统一的方式轻松高效地从各种存储服务中检索数据。
  • orjson 快速的 Python JSON 库。
  • ormsgpack 快速的 Python msgpack 库。
  • point-process 作为 Python 库的高级 API 用于点过程。
  • polaroid 使用 Rust 编写的 Python 的超快速且安全的图像处理库。
  • polars Rust、Python、Node.js 中的快速多线程 DataFrame 库。
  • pydantic-core pydantic 的核心验证逻辑,用 Rust 编写。
  • pyheck 快速大小写转换库,通过封装heck构建。
    • 由于代码不多,所以很容易理解。
  • pyre 使用Rust编写的快速Python HTTP服务器。
  • pyreqwest_impersonate 最快的Python HTTP客户端,可以通过模拟头部和TLS/JA3/JA4/HTTP2指纹来模仿Web浏览器。
  • ril-py 使用Rust编写的Python高性能高级图像处理库。
  • river Python中的在线机器学习,计算量大的统计算法是用Rust实现的。
  • rust-python-coverage PyO3项目的示例,具有Rust和Python的自动化测试覆盖率。
  • tiktoken 用于与OpenAI的模型一起使用的快速BPE标记化器。
  • tokenizers Hugging Face标记化器(NLP)的Python绑定,使用Rust编写。
  • tzfpy 快速包,用于将经纬度转换为时区名称。
  • utiles 快速的Python网络地图瓦片实用工具。
  • wasmer-python 用于运行WebAssembly二进制的Python库。

文章和其他媒体

贡献

每个人都欢迎为PyO3做出贡献!有许多方式可以支持这个项目,例如

  • 在GitHub和Discord上帮助PyO3用户解决问题
  • 改进文档
  • 编写功能和错误修复
  • 发布关于如何使用PyO3的博客和示例

我们的贡献笔记架构指南提供了更多资源,如果您想为PyO3志愿服务并寻找起点。

如果您没有时间亲自贡献,但仍希望支持项目的未来成功,我们的一些维护者有GitHub赞助页面

许可协议

PyO3根据Apache-2.0许可协议或MIT许可协议进行许可,您可任选其一。

Python根据Python许可证进行许可。

除非您明确表示否则,根据Apache许可证定义,您有意提交给PyO3的任何贡献,都应按照上述方式双重许可,不附加任何额外条款或条件。

Deploys by Netlify

依赖项

~0.2–1.8MB
~32K SLoC