How to use Rust with Python?

Zespół Sages
Calendar icon
31 lipca 2024

Rust is a modern programming language that offers high performance, memory security and concurrency. Python is a popular scripting language that facilitates rapid prototyping, data analysis and machine learning. How do you combine these two languages and take advantage of their advantages?

In this article, I'll show you how to use Rust with Python, using tools such as PyO3 and Maturin. PyO3 is a library that allows you to create native Python modules in Rust. Maturin is a tool that makes it easy to build, package and distribute Python-Rust mixed projects. We'll show you how to write a simple function in Rust that takes arguments from Python and returns the result to Python. I'll also show you how to build and install your Rust module as a Python package that you can import and use in your Python code.

How to write a function in Rust that takes arguments from Python and returns the result to Python

To write a function in Rust that can be called from Python, we need to use the #[pyfunction] macro from the PyO3 library. This macro automatically converts arguments and return values between Rust and Python types. For example, if we want to write a function that adds two integers and returns their sum, we can do it like this:

use pyo3::prelude::*;

#[pyfunction]
fn add(a: i32, b: i32) -> PyResult<i32> {
    Ok(a + b)
}

As you can see, the function takes two arguments of type i32, which is an integer type in Rust, and returns a result of type PyResult&lt;i32&gt;, which is a result type from the PyO3 library. The PyResult&lt;T&gt; type is used to handle errors that may occur when converting types or performing operations. If everything goes well, the function returns Ok(T), where T is the return value. If something goes wrong, the function returns the value Err(E), where E is the error. To make our function available to Python, we need to register it in a Rust module, which will be our native Python module. To do this, we need to use the #[pymodule] macro from the PyO3 library. This macro creates a Rust module that can be imported and used in Python. For example, if we want to call our module rusty, we can do it like this:

use pyo3::prelude::*;

#[pymodule]
fn rusty(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(add, m)?)?;
    Ok(())
}

As you can see, the function takes two arguments: py, which is a reference to the Python interpreter, and m, which is a reference to the Rust module. We then use add_function, which adds our add function to the Rust module, using the wrap_pyfunction macro, which wraps our function in a Python object. Finally, we return the value Ok(()), which means that everything went well. Now we have a ready-made function in Rust that can be called from Python. To test this, we need to build and install our Rust module as a Python package. I will show you how to do this in the next part of the article.

How to build and install a Rust module as a Python package

To build and install our Rust module as a Python package, we will need a tool called Maturin. Maturin is a tool that makes it easy to build, package and distribute Python-Rust mixed projects. Maturin supports both Windows, Linux and macOS operating systems, as well as different versions of Python. To install Maturin, we can use the Python package manager, pip. Just type the following command in the terminal:

pip install maturin

To build our Rust module as a Python package, we need to create a file named Cargo.toml in our project directory. The Cargo .toml file is a configuration file for the Cargo tool, which is a dependency and build manager for Rust projects. In the Cargo .toml file, we need to provide basic information about our project, such as name, version, authors, license, etc. We also need to add a dependency to the PyO3 library, which allows us to create native Python modules in Rust. For example, our Cargo.toml file might look like this:

[package]
name = "rusty"
version = "0.1.0"
authors = ["Bing <bing@microsoft.com>"]
edition = "2018"
license = "MIT"

[dependencies]
pyo3 = { version = "0.14", features = ["extension-module"] }

To build our Rust module as a Python package, we need to use the maturin build command in the terminal. This command will automatically compile our Rust code and create a final file named rusty-0.1.0-cp39-cp39-win_amd64.whl (the name may vary depending on your Python version and operating system). The .whl file is a binary file that contains our Rust module and all the necessary metadata. To install our Rust module as a Python package, we need to use the pip install command in the terminal. This command will automatically copy our .whl file to the appropriate directory and register it with the Python system. For example, we can install our Rust module like this:

pip install rusty-0.1.0-cp39-cp39-win_amd64.whl

Now we have a ready-made Python package that contains our Rust module. To use it, we just need to import it in our Python code and call our add function. For example, we can do it like this:

import rusty result = rusty.add(2, 3) print(result)

This should print 5 on the screen. In this way, we can use Rust with Python, using PyO3 and Maturin. We can also create more complex functions and classes in Rust that can interact with Python types and objects. We can also export our Python package to PyPI to make it available to other Python users.

Become an expert in the Rust language: sign up for comprehensive Rust Training

I hope you found this article helpful and interesting. If you want to learn more about programming in Rust or need to learn the basics of the language first, we invite you to our Rust training in an open or closed format - tailored to the needs of your projects.

Read also

Calendar icon

22 sierpień

A new era of knowledge management: Omega-PSIR at Kozminski University

Kozminski University in Warsaw, one of the leading universities in Poland, has been using the Omega-PSIR system we have implemented t...

Calendar icon

12 sierpień

What is Event-Driven Achitecture and why do you need it?

Event-Driven Architecture (EDA) is a modern approach to IT system design. Learn how EDA can impact your organization's growth!

Calendar icon

29 lipiec

Omega-PSIR re-certified ORCID Service Provider

Omega-PSIR software, developed by the Institute of Computer Science at the Warsaw University of Technology, has been accredited as an...