Since there was no easy way of solving this issue (at least, I hadn't found), I converted my async method to sync one. And called it on Python side as,
async fn my_method(s: &str) -> Result<String, Error> {
// do something
}
#[pyfunction]
fn my_sync_method(s: String) -> PyResult<String> {
let mut rt = tokio::runtime::Runtime::new().unwrap();
let mut contents = String::new();
rt.block_on(async {
result = format!("{}", my_sync_method(&s).await.unwrap()).to_string();
});
Ok((result))
}
#[pymodule]
fn MyModule(py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(my_sync_method))?;
Ok(())
}
Edited
In the Cargo.toml
file, I added the following dependencies,
[dependencies.pyo3]
git = "https://github.com/PyO3/pyo3"
features = ["extension-module"]
After running cargo build --release
, target/release/libMyModule.so
binary file is generated. Rename it as MyModule.so
and it now can be imported from Python.
import MyModule
result = MyModule.my_sync_method("hello")
Using setuptools-rust, I could bundle it as an ordinary Python package.
All of the above code and commands are tested on newly-released Linux Mint 20. On MacOS, the binary file will be libMyModule.dylib
.