restflow_core/node/
python.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use ts_rs::TS;
4
5#[derive(Debug, Clone, Serialize, Deserialize, TS)]
6#[ts(export)]
7pub struct PythonNode {
8    pub code: String,
9    #[serde(default)]
10    pub dependencies: Vec<String>,
11}
12
13impl PythonNode {
14    pub fn from_config(config: &serde_json::Value) -> Result<Self> {
15        let code = config["code"]
16            .as_str()
17            .ok_or_else(|| anyhow::anyhow!("Code missing in config"))?
18            .to_string();
19
20        let dependencies = config["dependencies"]
21            .as_array()
22            .map(|arr| {
23                arr.iter()
24                    .filter_map(|v| v.as_str().map(String::from))
25                    .collect()
26            })
27            .unwrap_or_default();
28
29        Ok(Self { code, dependencies })
30    }
31
32    /// Build complete Python script with PEP 723 dependency header
33    pub fn build_script(&self) -> String {
34        if self.dependencies.is_empty() {
35            return self.code.clone();
36        }
37
38        let deps = self
39            .dependencies
40            .iter()
41            .map(|d| format!("#   \"{}\",", d))
42            .collect::<Vec<_>>()
43            .join("\n");
44
45        format!(
46            "# /// script\n# dependencies = [\n{}\n# ]\n# ///\n\n{}",
47            deps, self.code
48        )
49    }
50}