PyO3 Rust bindings for Python, including tools for creating native Python extension modules. Running and interacting with Python code from a Rust binary is also supported. User Guide: stable |…
PyO3

https://codspeed.io/badge.json" rel="noopener nofollow" target="_blank">





Rust bindings for Python, including tools for creating native Python extension modules. Running and interacting with Python code from a Rust binary is also supported.
Usage
Requires Rust 1.83 or greater.
PyO3 supports the following Python distributions:
- CPython 3.9 or greater
- PyPy 7.3 (Python 3.11+)
- GraalPy 25.0 or greater (Python 3.12+)
You can use PyO3 to write a native Python module in Rust, or to embed Python in a Rust binary. The following sections explain each of these in turn.
Using Rust from Python
PyO3 can be used to generate a native Python module. The easiest way to try this out for the first time is to use maturin. maturin is a tool for building and publishing Rust-based Python packages with minimal configuration. The following steps install maturin, use it to generate and build a new Python package, and then launch Python to import and execute a function from the package.
First, follow the commands below to create a new directory containing a new Python virtualenv, and install maturin into the virtualenv using Python's package manager, pip:
bash
# (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
Still inside this string_sum directory, now run maturin init. This will generate the new package source. When given the choice of bindings to use, select pyo3 bindings:
bash
$ maturin init
✔ 🤷 What kind of bindings to use? · pyo3
✨ Done! New project created string_sum
The most important files generated by this command are Cargo.toml and lib.rs, which will look roughly like the following:
Cargo.toml
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 = "0.29.0"
src/lib.rs
rust
/// A Python module implemented in Rust. The name of this module must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
#[pyo3::pymodule]
mod string_sum {
use pyo3::prelude::*;
/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult {
Ok((a + b).to_string())
}
}
Finally, run maturin develop. This will build the package and install it into the Python virtualenv previously created and activated. The package is then ready to be used from python:
bash
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
'25'
To make changes to the package, just edit the Rust source code and then re-run maturin develop to recompile.
To run this all as a single copy-and-paste, use the bash script below (replace string_sum in the first command with the desired package name):
bash
mkdir string_sum && cd "$_"
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
If you want to be able to run cargo test or use this project in a Cargo workspace and are running into linker issues, there are some workarounds in the FAQ.
As well as with maturin, it is possible to build using setuptools-rust or manually. Both offer more flexibility than maturin but require more configuration to get started.
Using Python from Rust
To embed Python into a Rust binary, you need to ensure that your Python installation contains a shared library. The following steps demonstrate how to ensure this (for Ubuntu), and then give some example code which runs an embedded Python interpreter.
To install the Python shared library on Ubuntu:
bash
sudo apt install python3-dev
To install the Python shared library on RPM based distributions (e.g. Fedora, Red Hat, SuSE), install the python3-devel package.
Start a new project with cargo new and add pyo3 to the Cargo.toml like this:
toml
[dependencies.pyo3]
version = "0.29.0"
# Enabling this cargo feature will cause PyO3 to start a Python interpreter on first call to `Python::attach`
features = ["auto-initialize"]
Example program displaying the value of sys.version and the current user name:
rust
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
fn main() -> PyResult<()> {
Python::attach(|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 = c"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(())
})
}
The guide has a section with lots of examples
about this topic.
Tools and libraries
- 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
builtcrate as aPyDict_ - 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-async-runtimes _Utilities for interoperability with Python's Asyncio library and Rust's async runtimes._
- rustimport _Directly import Rust files or crates from Python, without manual compilation step. Provides pyo3 integration by default and generates pyo3 binding code automatically._
- pyo3-arrow _Lightweight Apache Arrow integration for pyo3._
- pyo3-bytes _Integration between
bytesand pyo3._ - pyo3-object_store _Integration between
object_storeandpyo3._
Examples
- anise _A modern, high-performance toolkit for spacecraft mission design, notably used to help softly land Firefly Blue Ghost on the Moon on 02 Feb 2025._
- arro3 _A minimal Python library for Apache Arrow, connecting to the Rust arrow crate._
arro3-compute_
- arro3-core _arro3-core_
- arro3-io _arro3-io_
- bed-reader _Read and write the PLINK BED format, simply and efficiently._
- cellular_raza _A cellular agent-based simulation framework for building complex models from a clean slate._
- connector-x _Fastest library to load data from DB to DataFrames in Rust and Python._
- 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._
- fast-paseto _High-performance PASETO (Platform-Agnostic Security Tokens) implementation with Python bindings._
- feos _Lightning fast thermodynamic modeling in Rust with fully developed Python interface._
- finalytics _Investment Analysis library in Rust | Python._
- forust _A lightweight gradient boosted decision tree library written in Rust._
- geo-index _A Rust crate and Python library for packed, immutable, zero-copy spatial indexes._
- granian _A Rust HTTP server for Python applications._
- haem _A Python library for working on Bioinformatics problems._
- hifitime _A high fidelity time management library for engineering and scientific applications where general relativity and time dilation matter._
- html2text-rs _Python library for converting HTML to markup or plain text._
- html-py-ever _Using html5ever through kuchiki to speed up html parsing and css-selecting._
- hudi-rs _The native Rust implementation for Apache Hudi, with C++ & Python API bindings._
- inline-python _Inline Python code directly in your Rust code._
- johnnycanencrypt OpenPGP library with Yubikey support.
- jsonschema _A high-performance JSON Schema validator for Python._
- mocpy _Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere._
- obstore _The simplest, highest-throughput Python interface to Amazon S3, Google Cloud Storage, Azure Storage, & other S3-compliant APIs, powered by Rust._
- opendal _A data access layer that allows users to easily and efficiently retrieve data from various storage services in a unified way._
- orjson _Fast Python JSON library._
- ormsgpack _Fast Python msgpack library._
- pdfcrate _An ergonomic, high-level PDF generation library for Rust and Python — a Prawn-style layout API for composing documents, not low-level PDF plumbing._
- polars _Fast multi-threaded DataFrame library in Rust | Python | Node.js._
- pycrdt _Python bindings for the Rust CRDT implementation Yrs._
- pydantic-core _Core validation logic for pydantic written in Rust._
- primp _The fastest python HTTP client that can impersonate web browsers by mimicking their headers and TLS/JA3/JA4/HTTP2 fingerprints._
- quebec _A database-backed background job queue for Python, inspired by Rails' Solid Queue._
- radiate: _A high-performance evolution engine for genetic programming and evolutionary algorithms._
- rateslib _A fixed income library for Python using Rust extensions._
- river _Online machine learning in python, the computationally heavy statistics algorithms are implemented in Rust._
- robyn A Super Fast Async Python Web Framework with a Rust runtime.
- rust-python-coverage _Example PyO3 project with automated test coverage for Rust and Python._
- rnet Asynchronous Python HTTP Client with Black Magic
- sail _Unifying stream, batch, and AI workloads with Apache Spark compatibility._
- tibs _A sleek Python library for binary data._
- tiktoken _A fast BPE tokeniser for use with OpenAI's models._
- tokenizers _Python bindings to the Hugging Face tokenizers (NLP) written in Rust._
- tzfpy _A fast package to convert longitude/latitude to timezone nam
Members
-
pyo3 ★ PINNED
Rust bindings for the Python interpreter
Rust ★ 16k 13h agoExplain → -
maturin ★ PINNED
Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages
Rust ★ 5.7k 1d agoExplain → -
rust-numpy ★ PINNED
PyO3-based Rust bindings of the NumPy C-API
Rust ★ 1.4k 18d agoExplain → -
setuptools-rust ★ PINNED
Setuptools plugin for Rust support
Python ★ 678 8h agoExplain → -
tokio ▣
Asyncio event loop written in Rust language
Rust ★ 245 8y agoExplain → -
pyo3-async-runtimes
PyO3-based bridges between Python and Rust async runtimes
Rust ★ 190 19d agoExplain → -
maturin-action
GitHub Action to install and run a custom maturin command with built-in support for cross compilation
TypeScript ★ 187 12d agoExplain → -
pyo3-built
Expose build variables obtained with built as a PyDict
Rust ★ 36 1y agoExplain → -
pyproject-toml-rs
pyproject.toml parser in Rust
Rust ★ 35 3mo agoExplain → -
maturin-import-hook
Import hook for maturin
Python ★ 19 6mo agoExplain → -
python3-dll-a
Standalone python3.dll import library generator
Rust ★ 12 1mo agoExplain → -
python-pkginfo-rs
Parse Python package metadata from sdist and bdists and etc.
Rust ★ 8 10h agoExplain → -
pyo3-ffi-check ▣
Automated verification of PyO3 FFI definitions
Rust ★ 7 3y agoExplain → -
setuptools-rust-tomlgen
No description.
Python ★ 4 4y agoExplain → -
branding
No description.
★ 0 1y agoExplain → -
bench-archive ▣
archive of continuous benchmark data from PyO3's CI
JavaScript ★ 0 2y agoExplain → -
schemastore ⑂
A collection of JSON schema files including full API
★ 0 2y agoExplain →
No repos match these filters.