如何从 Python 调用 Rust 异步方法? [英] How to call Rust async method from Python?

查看:81
本文介绍了如何从 Python 调用 Rust 异步方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如,对于同步 Rust 函数,我可以使用,

#[pyfunction]fn myfunc(a: String) ->PyResult{让 mut 内容 = String::new();内容 = a.to_string() + "附加";好的((内容))}#[pymodule]fn MyModule(py: Python, m: &PyModule) ->PyResult<()>{m.add_wrapped(wrap_pyfunction!(urlshot))?;好的(())}

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

async fn hello_world() {println!(你好,世界!");}

解决方案

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

async fn my_method(s: &str) ->结果<字符串,错误>{//做一点事}#[pyfunction]fn my_sync_method(s: String) ->PyResult{让 mut rt = tokio::runtime::Runtime::new().unwrap();让 mut 内容 = String::new();rt.block_on(异步{result = format!("{}", my_sync_method(&s).await.unwrap()).to_string();});好的((结果))}#[pymodule]fn MyModule(py: Python, m: &PyModule) ->PyResult<()>{m.add_wrapped(wrap_pyfunction!(my_sync_method))?;好的(())}

已编辑

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

<预><代码>[dependencies.pyo3]git = "https://github.com/PyO3/pyo3";特征 = [扩展模块"]

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

import MyModule结果 = MyModule.my_sync_method(你好")

使用 setuptools-rust,我可以将它捆绑为一个普通的 Python 包.

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

I want to use a Rust async method in Python. I'm trying to use PyO3 or rust-cpython.

For example, for sync Rust functions, I can use,

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

For async methods, how can I do it? For example, I want to call the following method in Python,

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

解决方案

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.

这篇关于如何从 Python 调用 Rust 异步方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆