mirror of
https://github.com/gorules/zen.git
synced 2026-10-05 16:02:40 +00:00
feat: add async support to python binding (#185)
* feat: Add async support to pythong binding * fix: return NodeResult instead of panic when future missing
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use anyhow::anyhow;
|
||||
use pyo3::types::PyDict;
|
||||
use pyo3::{PyObject, Python};
|
||||
use pyo3::{PyObject, PyResult, Python};
|
||||
use pyo3_asyncio::tokio::into_future;
|
||||
use pythonize::depythonize;
|
||||
|
||||
use zen_engine::handler::custom_node_adapter::{CustomNodeAdapter, CustomNodeRequest};
|
||||
@@ -23,20 +24,40 @@ impl From<Option<PyObject>> for PyCustomNode {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_custom_node_response(result: PyObject, py: Python<'_>) -> NodeResult {
|
||||
let dict = result.extract::<&PyDict>(py)?;
|
||||
let response: NodeResponse = depythonize(dict)?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
impl CustomNodeAdapter for PyCustomNode {
|
||||
async fn handle(&self, request: CustomNodeRequest<'_>) -> NodeResult {
|
||||
let Some(callable) = &self.0 else {
|
||||
return Err(anyhow!("Custom node handler not provided"));
|
||||
};
|
||||
|
||||
let content: NodeResponse = Python::with_gil(|py| {
|
||||
let (future, result) = Python::with_gil(|py| -> PyResult<_> {
|
||||
let req = PyNodeRequest::from_request(py, request)?;
|
||||
let result = callable.call1(py, (req,))?;
|
||||
|
||||
let dict = result.extract::<&PyDict>(py)?;
|
||||
depythonize(dict)
|
||||
let is_coroutine = result.getattr(py, "__await__").is_ok();
|
||||
if is_coroutine {
|
||||
return Ok((Some(into_future(result.as_ref(py))), None));
|
||||
}
|
||||
Ok((None, Some(extract_custom_node_response(result, py))))
|
||||
})?;
|
||||
|
||||
if let Some(result) = result {
|
||||
return result;
|
||||
}
|
||||
|
||||
let result = future
|
||||
.ok_or_else(|| anyhow!("Future or result must be present"))??
|
||||
.await?;
|
||||
|
||||
let content = Python::with_gil(|py| -> PyResult<_> {
|
||||
Ok(extract_custom_node_response(result, py))
|
||||
})??;
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user