Setup:

cargo init --lib (from within a folder you created)

If you want to support OSX:

.cargo/config

[target.x86_64-apple-darwin]
rustflags = [
  "-C", "link-arg=-undefined",
  "-C", "link-arg=dynamic_lookup",
]

Dependencies:

Cargo.toml:

[package]
name = "mypackage"
version = "0.1.0"
authors = ["Me <me@domain.com>"]
edition = "2018"

[lib]
name = "pymod"
crate-type = ["cdylib"]

[dependencies]


[dependencies.pyo3]
version = "0.7.0"
features = ["extension-module"]

At this point, cargo build should already produce a pymod.dll/so/dylib in target/debug.

Now we need some actual code so we can play with it in python.

use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
use pyo3::exceptions;

// #[pyclass] tells pyo3 that this should be treated as a python class
#[pyclass]
struct Vehicle {
    #[pyo3(get, set)]
    model: String,
    #[pyo3(get, set)]
    manufacturer: String,
    #[pyo3(get, set)]
    range: f32,
    #[pyo3(get, set)]
    price: i32
}

// This macro tells pyo3 that this function is accessible from python
#[pyfunction]
fn vehicles() -> PyResult<Vec<Vehicle>> {
    // Let's keep it simple: a vec to hold our vehicles
    let mut vehicles = vec![];

    vehicles.push(Vehicle {
        model: "Model S".to_string(),
        manufacturer: "Tesla".to_string(),
        range: 520.0,
        price: 81980
    });

    vehicles.push(Vehicle {
        model: "Leaf".to_string(),
        manufacturer: "Nissan".to_string(),
        range: 172.0,
        price: 36800
    });

    vehicles.push(Vehicle {
        model: "Urban".to_string(),
        manufacturer: "Desiknio".to_string(),
        range: 100.0,
        price: 3790
    });


    Ok(vehicles) //return positive PyResult

    //If you want exceptions, use PyErr with the pyo3::exceptions already provided for you
    //Err(PyErr::new::<exceptions::IOError, _>("Can't open ffproj"))

}

//The name of this function has to match our [lib] name in Cargo.toml
#[pymodule]
fn pymod(py: Python, m: &PyModule) -> PyResult<()> {
    m.add_wrapped(wrap_pyfunction!(vehicles))?;
    Ok(())
}

now just copy pymod.dylib to pymod.so on mac, on windows pymod.dll to pymod.pyd and on linux pymod.so to pymod.so.

In python:

import pymod

for vehicle in pymod.vehicles():
    print(vehicle.manufacturer, vehicle.model, "\n\tEuro / KM:", round(vehicle.price/vehicle.range))

Here are the pyo3 docs:

https://docs.rs/pyo3/0.7.0/pyo3/index.html