繁体   English   中英

如何从 Python 调用 Rust 异步方法?

[英]How to call Rust async method from Python?

我想在 Python 中使用 Rust 异步方法。 我正在尝试使用PyO3rust-cpython

例如,对于同步 Rust 功能,我可以使用,

#[pyfunction]
fn myfunc(a: String) -> PyResult<String> {
   let mut contents = String::new();
   contents = a.to_string() + " appended";
   Ok((contents))
}

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

对于异步方法,我该怎么做? 比如我想在Python中调用如下方法,

async fn hello_world() {
    println!("hello, world!");
}

由于没有简单的方法来解决这个问题(至少,我没有找到),我将我的异步方法转换为同步方法。 并在 Python 方面将其称为,

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

已编辑

Cargo.toml文件中,我添加了以下依赖项,


[dependencies.pyo3]
git = "https://github.com/PyO3/pyo3"
features = ["extension-module"]

运行cargo build --release后,会生成target/release/libMyModule.so二进制文件。 将其重命名为MyModule.so ,现在可以从 Python 导入。

import MyModule
result = MyModule.my_sync_method("hello")

使用setuptools-rust ,我可以将其捆绑为普通的 Python package。

以上所有代码和命令都在新发布的 Linux Mint 20 上进行了测试。在 MacOS 上,二进制文件将为libMyModule.dylib

如果你想使用 Python 来控制 Rust 的异步 function,我认为它不会起作用(或者至少它很复杂,因为你需要连接两个不同future机制)。 对于异步函数,Rust 编译器将维护一个 state 机器来管理在 await 的控制下正确运行的协程。 这是 Rust 应用程序的内部 state 并且 Python 无法触摸它。 同样Python解释器也有一个state机器不能被Rust触及。

我确实找到了有关如何使用 FFI 导出异步 function 的主题 主要思想是将异步包装在BoxFuture中,并让 C 控制将其返回到 Rust 的时间。 但是,您不能在 PyO3 中使用BoxFuture ,因为它的pyfunction宏无法将 function 返回BoxFuture转换为 Python 回调。 您可以尝试使用 FFI 创建一个库并使用 python 的 cffi 模块来加载它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM