fix: python asyncio (#217)

* fix: python asyncio

* fix imports

* fix: pytho asyncio

* fix fmt

* remove println

* revert to futures executor

* remove extension module
This commit is contained in:
stefan-gorules
2024-07-17 17:52:17 +02:00
committed by GitHub
parent 0b6e43c21b
commit 9e60fdc882
10 changed files with 147 additions and 196 deletions
+16 -19
View File
@@ -1,7 +1,8 @@
use anyhow::anyhow;
use either::Either;
use pyo3::types::PyDict;
use pyo3::{PyObject, PyResult, Python};
use pyo3_asyncio::tokio::into_future;
use pyo3_asyncio::tokio;
use pythonize::depythonize;
use zen_engine::handler::custom_node_adapter::{CustomNodeAdapter, CustomNodeRequest};
@@ -24,7 +25,7 @@ impl From<Option<PyObject>> for PyCustomNode {
}
}
fn extract_custom_node_response(result: PyObject, py: Python<'_>) -> NodeResult {
fn extract_custom_node_response(py: Python<'_>, result: PyObject) -> NodeResult {
let dict = result.extract::<&PyDict>(py)?;
let response: NodeResponse = depythonize(dict)?;
Ok(response)
@@ -36,28 +37,24 @@ impl CustomNodeAdapter for PyCustomNode {
return Err(anyhow!("Custom node handler not provided"));
};
let (future, result) = Python::with_gil(|py| -> PyResult<_> {
let maybe_result: PyResult<_> = Python::with_gil(|py| {
let req = PyNodeRequest::from_request(py, request)?;
let result = callable.call1(py, (req,))?;
let is_coroutine = result.getattr(py, "__await__").is_ok();
if is_coroutine {
return Ok((Some(into_future(result.as_ref(py))), None));
if !is_coroutine {
return Ok(Either::Left(extract_custom_node_response(py, result)));
}
Ok((None, Some(extract_custom_node_response(result, py))))
})?;
if let Some(result) = result {
return result;
let result_future = tokio::into_future(result.as_ref(py))?;
return Ok(Either::Right(result_future));
});
match maybe_result? {
Either::Left(result) => result,
Either::Right(future) => {
let result = future.await?;
Python::with_gil(|py| extract_custom_node_response(py, 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)
}
}