nautilus_trading/python/
algorithm.rs1use std::collections::HashMap;
19
20use nautilus_core::python::to_pyvalue_err;
21use pyo3::{prelude::*, types::PyDict};
22
23use crate::algorithm::ImportableExecAlgorithmConfig;
24
25#[pyo3::pymethods]
26#[pyo3_stub_gen::derive::gen_stub_pymethods]
27impl ImportableExecAlgorithmConfig {
28 #[new]
30 #[allow(clippy::needless_pass_by_value)]
31 fn py_new(
32 exec_algorithm_path: String,
33 config_path: String,
34 config: Py<PyDict>,
35 ) -> PyResult<Self> {
36 let json_config = Python::attach(|py| -> PyResult<HashMap<String, serde_json::Value>> {
37 let kwargs = PyDict::new(py);
38 kwargs.set_item("default", py.eval(pyo3::ffi::c_str!("str"), None, None)?)?;
39 let json_str: String = PyModule::import(py, "json")?
40 .call_method("dumps", (config.bind(py),), Some(&kwargs))?
41 .extract()?;
42
43 let json_value: serde_json::Value =
44 serde_json::from_str(&json_str).map_err(to_pyvalue_err)?;
45
46 if let serde_json::Value::Object(map) = json_value {
47 Ok(map.into_iter().collect())
48 } else {
49 Err(to_pyvalue_err("Config must be a dictionary"))
50 }
51 })?;
52
53 Ok(Self {
54 exec_algorithm_path,
55 config_path,
56 config: json_config,
57 })
58 }
59
60 #[getter]
61 fn exec_algorithm_path(&self) -> &String {
62 &self.exec_algorithm_path
63 }
64
65 #[getter]
66 fn config_path(&self) -> &String {
67 &self.config_path
68 }
69
70 #[getter]
71 fn config(&self, py: Python<'_>) -> PyResult<Py<PyDict>> {
72 let py_dict = PyDict::new(py);
73 for (key, value) in &self.config {
74 let json_str = serde_json::to_string(value).map_err(to_pyvalue_err)?;
75 let py_value = PyModule::import(py, "json")?.call_method("loads", (json_str,), None)?;
76 py_dict.set_item(key, py_value)?;
77 }
78 Ok(py_dict.unbind())
79 }
80}