簡體   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