feat: custom node (#138)

* feat: custom node

* add zen template, expose $nodes and $root

* add custom handler to go and nodejs

* add support for python, improve bindings, add error to zen template

* fix: correct binding exports for nodejs and python

* fix benchmark

* improve rust api, trim template in zen templates

* update cargo action

* update expression version

* compile action

* fix action format
This commit is contained in:
stefan-gorules
2024-04-03 16:09:51 +02:00
committed by GitHub
parent 685a0345f5
commit daecf901e6
65 changed files with 1729 additions and 235 deletions
+42
View File
@@ -0,0 +1,42 @@
use anyhow::anyhow;
use pyo3::types::PyDict;
use pyo3::{PyObject, Python};
use pythonize::depythonize;
use zen_engine::handler::custom_node_adapter::{CustomNodeAdapter, CustomNodeRequest};
use zen_engine::handler::node::{NodeResponse, NodeResult};
use crate::types::PyNodeRequest;
#[derive(Default)]
pub(crate) struct PyCustomNode(Option<PyObject>);
impl From<PyObject> for PyCustomNode {
fn from(value: PyObject) -> Self {
Self(Some(value))
}
}
impl From<Option<PyObject>> for PyCustomNode {
fn from(value: Option<PyObject>) -> Self {
Self(value)
}
}
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 req = PyNodeRequest::from_request(py, request)?;
let result = callable.call1(py, (req,))?;
let dict = result.extract::<&PyDict>(py)?;
depythonize(dict)
})?;
Ok(content)
}
}