feat: rc variable (#246)

* feat: rc variable

* feat: implement variable in engine

* add exports

* fix bindings and improve clone accuracy

* fix tests, fix bindings

* fix fmt

* improve code
This commit is contained in:
stefan-gorules
2024-09-30 18:34:54 +02:00
committed by GitHub
parent 06df117694
commit 91598166ce
55 changed files with 1148 additions and 1399 deletions
+5 -5
View File
@@ -5,7 +5,7 @@ use pyo3::types::PyDict;
use pyo3::{pyclass, pymethods, PyAny, PyObject, PyResult, Python, ToPyObject};
use pyo3_asyncio::tokio;
use pythonize::depythonize;
use serde_json::Value;
use zen_engine::{Decision, EvaluationOptions};
use crate::custom_node::PyCustomNode;
@@ -26,7 +26,7 @@ impl From<Decision<PyDecisionLoader, PyCustomNode>> for PyZenDecision {
#[pymethods]
impl PyZenDecision {
pub fn evaluate(&self, py: Python, ctx: &PyDict, opts: Option<&PyDict>) -> PyResult<PyObject> {
let context = depythonize(ctx).context("Failed to convert dict")?;
let context: Value = depythonize(ctx).context("Failed to convert dict")?;
let options: PyZenEvaluateOptions = if let Some(op) = opts {
depythonize(op).context("Failed to convert dict")?
} else {
@@ -35,7 +35,7 @@ impl PyZenDecision {
let decision = self.0.clone();
let result = futures::executor::block_on(decision.evaluate_with_opts(
&context,
context.into(),
EvaluationOptions {
max_depth: options.max_depth,
trace: options.trace,
@@ -55,7 +55,7 @@ impl PyZenDecision {
ctx: &PyDict,
opts: Option<&PyDict>,
) -> PyResult<&PyAny> {
let context = depythonize(ctx).context("Failed to convert dict")?;
let context: Value = depythonize(ctx).context("Failed to convert dict")?;
let options: PyZenEvaluateOptions = if let Some(op) = opts {
depythonize(op).context("Failed to convert dict")?
} else {
@@ -65,7 +65,7 @@ impl PyZenDecision {
let decision = self.0.clone();
tokio::future_into_py(py, async move {
let result = futures::executor::block_on(decision.evaluate_with_opts(
&context,
context.into(),
EvaluationOptions {
max_depth: options.max_depth,
trace: options.trace,
+6 -6
View File
@@ -6,7 +6,7 @@ use pyo3::{pyclass, pymethods, PyAny, PyObject, PyResult, Python, ToPyObject};
use pyo3_asyncio::tokio;
use pythonize::depythonize;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use zen_engine::model::DecisionContent;
use zen_engine::{DecisionEngine, EvaluationOptions};
@@ -82,7 +82,7 @@ impl PyZenEngine {
ctx: &PyDict,
opts: Option<&PyDict>,
) -> PyResult<PyObject> {
let context = depythonize(ctx).context("Failed to convert dict")?;
let context: Value = depythonize(ctx).context("Failed to convert dict")?;
let options: PyZenEvaluateOptions = if let Some(op) = opts {
depythonize(op).context("Failed to convert dict")?
} else {
@@ -92,7 +92,7 @@ impl PyZenEngine {
let graph = self.graph.clone();
let result = futures::executor::block_on(graph.evaluate_with_opts(
key,
&context,
context.into(),
EvaluationOptions {
max_depth: options.max_depth,
trace: options.trace,
@@ -113,7 +113,7 @@ impl PyZenEngine {
ctx: &PyDict,
opts: Option<&PyDict>,
) -> PyResult<&PyAny> {
let context = depythonize(ctx).context("Failed to convert dict")?;
let context: Value = depythonize(ctx).context("Failed to convert dict")?;
let options: PyZenEvaluateOptions = if let Some(op) = opts {
depythonize(op).context("Failed to convert dict")?
} else {
@@ -124,7 +124,7 @@ impl PyZenEngine {
tokio::future_into_py(py, async move {
let result = futures::executor::block_on(graph.evaluate_with_opts(
key,
&context,
context.into(),
EvaluationOptions {
max_depth: options.max_depth,
trace: options.trace,
@@ -148,7 +148,7 @@ impl PyZenEngine {
Ok(PyZenDecision::from(decision))
}
pub fn get_decision<'py>(&'py self, py: Python<'py>, key: String) -> PyResult<PyZenDecision> {
pub fn get_decision<'py>(&'py self, _py: Python<'py>, key: String) -> PyResult<PyZenDecision> {
let decision = futures::executor::block_on(self.graph.get_decision(&key))
.context("Failed to find decision with given key")?;
+5 -5
View File
@@ -18,17 +18,17 @@ pub fn evaluate_expression(
.context("Failed to convert context")?
.unwrap_or(Value::Null);
let result = zen_expression::evaluate_expression(expression.as_str(), &context)
let result = zen_expression::evaluate_expression(expression.as_str(), context.into())
.map_err(|e| anyhow!(serde_json::to_string(&e).unwrap_or_else(|_| e.to_string())))?;
Ok(PyValue(result).to_object(py))
Ok(PyValue(result.to_value()).to_object(py))
}
#[pyfunction]
pub fn evaluate_unary_expression(expression: String, ctx: &PyDict) -> PyResult<bool> {
let context: Value = depythonize(ctx).context("Failed to convert context")?;
let result = zen_expression::evaluate_unary_expression(expression.as_str(), &context)
let result = zen_expression::evaluate_unary_expression(expression.as_str(), context.into())
.map_err(|e| anyhow!(serde_json::to_string(&e).unwrap_or_else(|_| e.to_string())))?;
Ok(result)
@@ -38,8 +38,8 @@ pub fn evaluate_unary_expression(expression: String, ctx: &PyDict) -> PyResult<b
pub fn render_template(py: Python, template: String, ctx: &PyDict) -> PyResult<PyObject> {
let context: Value = depythonize(ctx).context("Failed to convert context")?;
let result = zen_tmpl::render(template.as_str(), &context)
let result = zen_tmpl::render(template.as_str(), context.into())
.map_err(|e| anyhow!(serde_json::to_string(&e).unwrap_or_else(|_| e.to_string())))?;
Ok(PyValue(result).to_object(py))
Ok(PyValue(result.to_value()).to_object(py))
}
+8 -8
View File
@@ -4,12 +4,12 @@ use pyo3::{pyclass, pymethods, PyObject, PyResult, Python, ToPyObject};
use serde::Serialize;
use serde_json::Value;
use crate::value::{value_to_object, PyValue};
use zen_engine::handler::custom_node_adapter::{
CustomDecisionNode as BaseCustomDecisionNode, CustomNodeRequest,
};
use zen_engine::handler::node::NodeResponse;
use crate::value::{value_to_object, PyValue};
use zen_expression::Variable;
#[derive(Serialize)]
struct CustomDecisionNode {
@@ -50,10 +50,10 @@ impl PyNodeRequest {
let node_val = serde_json::to_value(&inner_node).unwrap();
Ok(Self {
input: value_to_object(py, &value.input),
input: value_to_object(py, &value.input.to_value()),
node: value_to_object(py, &node_val),
inner_input: value.input.clone(),
inner_input: value.input.to_value(),
inner_node,
})
}
@@ -73,10 +73,10 @@ impl PyNodeRequest {
return Ok(PyValue(selected_value).to_object(py));
};
let template_value = zen_tmpl::render(template.as_str(), &self.inner_input)
let template_value = zen_tmpl::render(template.as_str(), Variable::from(&self.inner_input))
.map_err(|e| anyhow!(serde_json::to_string(&e).unwrap_or_else(|_| e.to_string())))?;
Ok(PyValue(template_value).to_object(py))
Ok(PyValue(template_value.to_value()).to_object(py))
}
fn get_field_raw(&self, py: Python, path: String) -> PyResult<PyObject> {
@@ -102,7 +102,7 @@ pub struct PyNodeResponse {
impl From<NodeResponse> for PyNodeResponse {
fn from(value: NodeResponse) -> Self {
Self {
output: value.output,
output: value.output.to_value(),
trace_data: value.trace_data,
}
}
@@ -111,7 +111,7 @@ impl From<NodeResponse> for PyNodeResponse {
impl From<PyNodeResponse> for NodeResponse {
fn from(value: PyNodeResponse) -> Self {
Self {
output: value.output,
output: value.output.into(),
trace_data: value.trace_data,
}
}