All Projects → PyO3 → Pyo3

PyO3 / Pyo3

Licence: other
Rust bindings for the Python interpreter

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Pyo3

Rustler
Safe Rust bridge for creating Erlang NIF functions
Stars: ✭ 3,052 (-40.27%)
Mutual labels:  ffi, binding
Emacs Module Rs
Rust binding and tools for emacs-module (Emacs's dynamic module support)
Stars: ✭ 203 (-96.03%)
Mutual labels:  ffi, binding
phper
A library that allows us to write PHP extensions using pure Rust and using safe Rust whenever possible.
Stars: ✭ 24 (-99.53%)
Mutual labels:  binding
React Event Listener
A React component for binding events on the global scope. 💫
Stars: ✭ 359 (-92.97%)
Mutual labels:  binding
Win32
Build Win32 apps with Dart!
Stars: ✭ 256 (-94.99%)
Mutual labels:  ffi
ffi-libc
Useful Ruby FFI bindings for libc
Stars: ✭ 32 (-99.37%)
Mutual labels:  ffi
Fritz2
Easily build reactive web-apps in Kotlin based on flows and coroutines.
Stars: ✭ 308 (-93.97%)
Mutual labels:  binding
rust-lang-interop
Rust language interoperability with other languages - C, C++ etc.
Stars: ✭ 53 (-98.96%)
Mutual labels:  ffi
C Cpp Notes
Notes about modern C++, C++11, C++14 and C++17, Boost Libraries, ABI, foreign function interface and reference cards.
Stars: ✭ 363 (-92.9%)
Mutual labels:  ffi
ext-psi
PHP System Interface (aka FFI)
Stars: ✭ 24 (-99.53%)
Mutual labels:  ffi
Corbind
Kotlin Coroutines binding APIs for Android UI widgets from the platform and support libraries
Stars: ✭ 357 (-93.01%)
Mutual labels:  binding
cld3-ruby
cld3-ruby is an interface of Compact Language Detector v3 (CLD3) for Ruby.
Stars: ✭ 59 (-98.85%)
Mutual labels:  ffi
uapi
Unix API
Stars: ✭ 18 (-99.65%)
Mutual labels:  ffi
Jni.hpp
A modern, type-safe, header-only, C++14 wrapper for JNI
Stars: ✭ 313 (-93.87%)
Mutual labels:  binding
FABGen
C++ binding generator for CPython 3.x (x>=2), Lua 5.3 and Go
Stars: ✭ 26 (-99.49%)
Mutual labels:  binding
G2opy
Python binding of SLAM graph optimization framework g2o
Stars: ✭ 360 (-92.95%)
Mutual labels:  binding
croatoan
Common Lisp bindings for the ncurses terminal library.
Stars: ✭ 111 (-97.83%)
Mutual labels:  binding
gpgme
GPGme bindings for Rust
Stars: ✭ 55 (-98.92%)
Mutual labels:  ffi
Android Viewmodelbinding
A lightweight library aiming to speed up Android app development by leveraging the new Android Data Binding together with the Model-View-ViewModel design pattern.
Stars: ✭ 308 (-93.97%)
Mutual labels:  binding
Ffi Overhead
comparing the c ffi (foreign function interface) overhead on various programming languages
Stars: ✭ 387 (-92.43%)
Mutual labels:  ffi

PyO3

actions status benchmark codecov crates.io minimum rustc 1.48 dev chat contributing notes

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

PyO3 supports the following software versions:

  • Python 3.7 and up (CPython and PyPy)
  • Rust 1.48 and up

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:

# (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:

$ 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

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

[lib]
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.15.1", 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(_py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
    Ok(())
}

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:

$ 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):

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

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:

sudo apt install python3-dev

Start a new project with cargo new and add pyo3 to the Cargo.toml like this:

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

Example program displaying the value of sys.version and the current user name:

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(())
    })
}

The guide has a section with lots of examples about this topic.

Tools and libraries

  • maturin Zero configuration build tool for Rust-made Python extensions.
  • 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

Examples

  • hyperjson A hyper-fast Python module for reading/writing JSON data using Rust's serde-json
  • html-py-ever Using html5ever through kuchiki to speed up html parsing and css-selecting.
  • point-process High level API for pointprocesses as a Python library
  • autopy A simple, cross-platform GUI automation library for Python and Rust.
    • Contains an example of building wheels on TravisCI and appveyor using cibuildwheel
  • orjson Fast Python JSON library
  • inline-python Inline Python code directly in your Rust code
  • Rogue-Gym Customizable rogue-like game for AI experiments
    • Contains an example of building wheels on Azure Pipelines
  • fastuuid Python bindings to Rust's UUID library
  • wasmer-python Python library to run WebAssembly binaries
  • mocpy Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere
  • tokenizers Python bindings to the Hugging Face tokenizers (NLP) written in Rust
  • pyre Fast Python HTTP server written in Rust
  • jsonschema-rs Fast JSON Schema validation library
  • css-inline CSS inlining for Python implemented in Rust
  • cryptography Python cryptography library with some functionality in Rust
  • polaroid Hyper Fast and safe image manipulation library for Python written in Rust
  • ormsgpack Fast Python msgpack library

Articles and other media

Contributing

Everyone is welcomed to contribute to PyO3! There are many ways to support the project, such as:

  • help PyO3 users with issues on GitHub and Gitter
  • improve documentation
  • write features and bugfixes
  • publish blogs and examples of how to use PyO3

Our contributing notes and architecture guide have more resources if you wish to volunteer time for PyO3 and are searching where to start.

If you don't have time to contribute yourself but still wish to support the project's future success, some of our maintainers have GitHub sponsorship pages:

License

PyO3 is licensed under the Apache-2.0 license. Python is licensed under the Python License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].