Skip to content

Commit 6503128

Browse files
author
Sam Vente
authored
add first version of getting started page to the guide (#2499)
* add first version of getting started page to the guide * add more info on maturin
1 parent 97330a5 commit 6503128

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

guide/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
---
66

7+
- [Getting Started](getting_started.md)
78
- [Python Modules](module.md)
89
- [Python Functions](function.md)
910
- [Python Classes](class.md)

guide/src/getting_started.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
2+
# Instalation
3+
4+
To get started using PyO3 you will need three things: a rust toolchain, a python environment, and a way to build. We'll cover each of these below.
5+
6+
## Rust
7+
8+
First, make sure you have rust installed on your system. If you haven't already done so you can do so by following the instructions [here](https://www.rust-lang.org/tools/install). PyO3 runs on both the `stable` and `nightly` versions so you can choose whichever one fits you best. The minimum required rust version is Rust 1.48.
9+
10+
if you can run `rustc --version` and the version is high enough you're good to go!
11+
12+
## Python
13+
14+
To use PyO3 you need at least Python 3.7. While you can simply use the default Python version on your system, it is recommended to use a virtual environment.
15+
16+
17+
## Virtualenvs
18+
19+
While you can use any virtualenv manager you like, we recommend the use of `pyenv` especially if you want to develop or test for multiple different python versions, so that is what the examples in this book will use. The installation instructions for `pyenv` can be found [here](https://github.com/pyenv/pyenv#getting-pyenv).
20+
21+
Note that when using `pyenv` you should also set the following environment variable
22+
```bash
23+
PYTHON_CONFIGURE_OPTS="--enable-shared"
24+
```
25+
### Building
26+
27+
28+
There are a number of build and python package management systems such as [`setuptools-rust`](https://github.com/PyO3/setuptools-rust) or [manually](https://pyo3.rs/latest/building_and_distribution.html#manual-builds) we recommend the use of `maturin` which you can install [here](https://maturin.rs/installation.html). It is developed to work with PyO3 and is the most "batteries included" experience. `maturin` is just a python package so you can add it in any way that you install python packages.
29+
30+
System Python:
31+
```bash
32+
pip install maturin --user
33+
```
34+
35+
pipx:
36+
```bash
37+
pipx install maturin
38+
```
39+
40+
pyenv:
41+
```bash
42+
pyenv activate pyo3
43+
pip install maturin
44+
```
45+
46+
poetry:
47+
```bash
48+
poetry add -D maturin
49+
```
50+
51+
after installation, you can run `maturin --version` to check that you have correctly installed it.
52+
53+
54+
# Starting a new project
55+
56+
Firstly you should create the folder and virtual environment that are going to contain your new project. Here we will use the recommended `pyenv`:
57+
58+
```bash
59+
mkdir pyo3-example
60+
cd pyo3-example
61+
pyenv virtualenv pyo3
62+
pyenv local pyo3
63+
```
64+
after this, you should install your build manager. In this example, we will use `maturin`. After you've activated your virtualenv add `maturin` to it:
65+
66+
```bash
67+
pip install maturin
68+
```
69+
70+
After this, you can initialise the new project
71+
72+
```bash
73+
maturin init
74+
```
75+
76+
If `maturin` is already installed you can create a new project using that directly as well:
77+
78+
```bash
79+
maturin new -b pyo3 pyo3-example
80+
cd pyo3-example
81+
pyenv virtualenv pyo3
82+
pyenv local pyo3
83+
```
84+
85+
# Adding to an existing project
86+
87+
Sadly currently `maturin` cannot be run in existing projects, so if you want to use python in an existing project you basically have two options:
88+
89+
1. create a new project as above and move your existing code into that project
90+
2. Manually edit your project configuration as necessary.
91+
92+
If you are opting for the second option, here are the things you need to pay attention to:
93+
94+
## Cargo.toml
95+
96+
Make sure that the rust you want to be able to access from Python is compiled into a library. You can have a binary output as well, but the code you want to access from python has to be in the library. Also, make sure that the crate type is `cdylib` and add PyO3 as a dependency as so:
97+
98+
99+
```toml
100+
[lib]
101+
# The name of the native library. This is the name which will be used in Python to import the
102+
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
103+
# `#[pymodule]` in `src/lib.rs`.
104+
name = "pyo3_example"
105+
106+
# "cdylib" is necessary to produce a shared library for Python to import from.
107+
crate-type = ["cdylib"]
108+
109+
[dependencies]
110+
pyo3 = { version = "0.16.5", features = ["extension-module"] }
111+
```
112+
113+
## pyproject.toml
114+
You should also create a `pyproject.toml` with the following contents:
115+
116+
```toml
117+
[build-system]
118+
requires = ["maturin>=0.13,<0.14"]
119+
build-backend = "maturin"
120+
121+
[project]
122+
name = "pyo3_example"
123+
requires-python = ">=3.7"
124+
classifiers = [
125+
"Programming Language :: Rust",
126+
"Programming Language :: Python :: Implementation :: CPython",
127+
"Programming Language :: Python :: Implementation :: PyPy",
128+
]
129+
```
130+
131+
## Running code
132+
133+
After this you can setup rust code to be available in python as such:
134+
135+
```rust
136+
use pyo3::prelude::*;
137+
138+
/// Formats the sum of two numbers as string.
139+
#[pyfunction]
140+
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
141+
Ok((a + b).to_string())
142+
}
143+
144+
/// A Python module implemented in Rust. The name of this function must match
145+
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
146+
/// import the module.
147+
#[pymodule]
148+
fn string_sum(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
149+
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
150+
Ok(())
151+
}
152+
```
153+
154+
After this you can run `maturin develop` to prepare the python package after which you can use it like so:
155+
156+
```bash
157+
$ maturin develop
158+
# lots of progress output as maturin runs the compilation...
159+
$ python
160+
>>> import pyo3_example
161+
>>> pyo3_example.sum_as_string(5, 20)
162+
'25'
163+
```
164+
165+
For more instructions on how to use python code from rust see the [Python from Rust](python_from_rust.md) page.

0 commit comments

Comments
 (0)