如何从 Rust 调用 Python 异步函数?
How to call Python async function from Rust?
我已经阅读了这个答案(),我想做的是与此相反的事情。
我想调用一个 Python 异步函数并在 tokio 的运行时中等待它。可能吗?
我已经尝试了一些,但我在输出中遇到错误。
这是我的 python 文件的样子:
import rust_package
async def h():
print("message from coroutine")
print("Hello world")
s = rust_package.Server()
s.start(h)
这就是我的 lib.rs 的样子:
#[pyclass]
struct Server {}
#[pymethods]
impl Server {
#[new]
fn new() -> Self {
Self {}
}
fn start(mut self_: PyRefMut<Self>, test: &PyAny) {
let f = pyo3_asyncio::into_future(test).unwrap();
let rt = tokio::runtime::Runtime::new().unwrap();
pyo3_asyncio::tokio::init(rt);
Python::with_gil(|py| {
pyo3_asyncio::tokio::run_until_complete(py, async move {
tokio::time::sleep(Duration::from_secs(1)).await;
f.await.unwrap();
Ok(())
})
.unwrap();
});
}
#[pymodule]
pub fn roadrunner(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_class::<Server>()?;
pyo3_asyncio::try_init(py);
Ok(())
}
我收到以下错误:
Hello world
Exception in callback <builtins.PyEnsureFuture object a
t 0x10bc1bd20>()
handle: <Handle <builtins.PyEnsureFuture object at 0x10
bc1bd20>()>
Traceback (most recent call last):
File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/P
ython.framework/Versions/3.9/lib/python3.9/asyncio/even
ts.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/P
ython.framework/Versions/3.9/lib/python3.9/asyncio/task
s.py", line 679, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or
an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitab
le is required
我显然正在传递异步函数并将其转换为未来。我无法弄清楚我哪里出错了。我已经多次阅读 pyo3-async 的文档,但我仍然无法弄清楚。
非常感谢您的帮助。
提前致谢。
根据@sebpuetz 的建议,
我所需要的只是
变化
s.start(h)
到
s.start(h())
因为 h 本身只是一个函数。 h()
是协程,是必填项。
我已经阅读了这个答案(
我想调用一个 Python 异步函数并在 tokio 的运行时中等待它。可能吗?
我已经尝试了一些,但我在输出中遇到错误。
这是我的 python 文件的样子:
import rust_package
async def h():
print("message from coroutine")
print("Hello world")
s = rust_package.Server()
s.start(h)
这就是我的 lib.rs 的样子:
#[pyclass]
struct Server {}
#[pymethods]
impl Server {
#[new]
fn new() -> Self {
Self {}
}
fn start(mut self_: PyRefMut<Self>, test: &PyAny) {
let f = pyo3_asyncio::into_future(test).unwrap();
let rt = tokio::runtime::Runtime::new().unwrap();
pyo3_asyncio::tokio::init(rt);
Python::with_gil(|py| {
pyo3_asyncio::tokio::run_until_complete(py, async move {
tokio::time::sleep(Duration::from_secs(1)).await;
f.await.unwrap();
Ok(())
})
.unwrap();
});
}
#[pymodule]
pub fn roadrunner(py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_class::<Server>()?;
pyo3_asyncio::try_init(py);
Ok(())
}
我收到以下错误:
Hello world
Exception in callback <builtins.PyEnsureFuture object a
t 0x10bc1bd20>()
handle: <Handle <builtins.PyEnsureFuture object at 0x10
bc1bd20>()>
Traceback (most recent call last):
File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/P
ython.framework/Versions/3.9/lib/python3.9/asyncio/even
ts.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/Cellar/python@3.9/3.9.5/Frameworks/P
ython.framework/Versions/3.9/lib/python3.9/asyncio/task
s.py", line 679, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or
an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitab
le is required
我显然正在传递异步函数并将其转换为未来。我无法弄清楚我哪里出错了。我已经多次阅读 pyo3-async 的文档,但我仍然无法弄清楚。 非常感谢您的帮助。
提前致谢。
根据@sebpuetz 的建议,
我所需要的只是 变化
s.start(h)
到
s.start(h())
因为 h 本身只是一个函数。 h()
是协程,是必填项。