1#![warn(rustc::all)]
46#![deny(unsafe_code)]
47#![deny(nonstandard_style)]
48#![deny(missing_debug_implementations)]
49#![deny(clippy::missing_errors_doc)]
50#![deny(clippy::missing_panics_doc)]
51#![deny(rustdoc::broken_intra_doc_links)]
52
53use std::path::Path;
54
55use pyo3::prelude::*;
56
57#[pymodule] #[cfg_attr(feature = "cython-compat", pyo3(name = "nautilus_pyo3"))]
64fn _libnautilus(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
65 let sys = PyModule::import(py, "sys")?;
66 let modules = sys.getattr("modules")?;
67 let sys_modules: &Bound<'_, PyAny> = modules.downcast()?;
68
69 #[cfg(feature = "cython-compat")]
70 let module_name = "nautilus_trader.core.nautilus_pyo3";
71
72 #[cfg(not(feature = "cython-compat"))]
73 let module_name = "nautilus_trader._libnautilus";
74
75 sys_modules.set_item(module_name, m)?;
77
78 let n = "analysis";
79 let submodule = pyo3::wrap_pymodule!(nautilus_analysis::python::analysis);
80 m.add_wrapped(submodule)?;
81 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
82 #[cfg(feature = "cython-compat")]
83 re_export_module_attributes(m, n)?;
84
85 let n = "core";
86 let submodule = pyo3::wrap_pymodule!(nautilus_core::python::core);
87 m.add_wrapped(submodule)?;
88 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
89 #[cfg(feature = "cython-compat")]
90 re_export_module_attributes(m, n)?;
91
92 let n = "common";
93 let submodule = pyo3::wrap_pymodule!(nautilus_common::python::common);
94 m.add_wrapped(submodule)?;
95 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
96 #[cfg(feature = "cython-compat")]
97 re_export_module_attributes(m, n)?;
98
99 let n = "cryptography";
100 let submodule = pyo3::wrap_pymodule!(nautilus_cryptography::python::cryptography);
101 m.add_wrapped(submodule)?;
102 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
103 #[cfg(feature = "cython-compat")]
104 re_export_module_attributes(m, n)?;
105
106 let n = "indicators";
107 let submodule = pyo3::wrap_pymodule!(nautilus_indicators::python::indicators);
108 m.add_wrapped(submodule)?;
109 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
110 #[cfg(feature = "cython-compat")]
111 re_export_module_attributes(m, n)?;
112
113 let n = "infrastructure";
114 let submodule = pyo3::wrap_pymodule!(nautilus_infrastructure::python::infrastructure);
115 m.add_wrapped(submodule)?;
116 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
117 #[cfg(feature = "cython-compat")]
118 re_export_module_attributes(m, n)?;
119
120 let n = "live";
121 let submodule = pyo3::wrap_pymodule!(nautilus_live::python::live);
122 m.add_wrapped(submodule)?;
123 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
124 #[cfg(feature = "cython-compat")]
125 re_export_module_attributes(m, n)?;
126
127 let n = "model";
128 let submodule = pyo3::wrap_pymodule!(nautilus_model::python::model);
129 m.add_wrapped(submodule)?;
130 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
131 #[cfg(feature = "cython-compat")]
132 re_export_module_attributes(m, n)?;
133
134 let n = "network";
135 let submodule = pyo3::wrap_pymodule!(nautilus_network::python::network);
136 m.add_wrapped(submodule)?;
137 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
138 #[cfg(feature = "cython-compat")]
139 re_export_module_attributes(m, n)?;
140
141 let n = "persistence";
142 let submodule = pyo3::wrap_pymodule!(nautilus_persistence::python::persistence);
143 m.add_wrapped(submodule)?;
144 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
145 #[cfg(feature = "cython-compat")]
146 re_export_module_attributes(m, n)?;
147
148 let n = "serialization";
149 let submodule = pyo3::wrap_pymodule!(nautilus_serialization::python::serialization);
150 m.add_wrapped(submodule)?;
151 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
152 #[cfg(feature = "cython-compat")]
153 re_export_module_attributes(m, n)?;
154
155 let n = "testkit";
156 let submodule = pyo3::wrap_pymodule!(nautilus_testkit::python::testkit);
157 m.add_wrapped(submodule)?;
158 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
159 #[cfg(feature = "cython-compat")]
160 re_export_module_attributes(m, n)?;
161
162 let n = "trading";
163 let submodule = pyo3::wrap_pymodule!(nautilus_trading::python::trading);
164 m.add_wrapped(submodule)?;
165 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
166 #[cfg(feature = "cython-compat")]
167 re_export_module_attributes(m, n)?;
168
169 let n = "bitmex";
174 let submodule = pyo3::wrap_pymodule!(nautilus_bitmex::python::bitmex);
175 m.add_wrapped(submodule)?;
176 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
177 #[cfg(feature = "cython-compat")]
178 re_export_module_attributes(m, n)?;
179
180 let n = "bybit";
181 let submodule = pyo3::wrap_pymodule!(nautilus_bybit::python::bybit);
182 m.add_wrapped(submodule)?;
183 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
184 #[cfg(feature = "cython-compat")]
185 re_export_module_attributes(m, n)?;
186
187 let n = "coinbase_intx";
188 let submodule = pyo3::wrap_pymodule!(nautilus_coinbase_intx::python::coinbase_intx);
189 m.add_wrapped(submodule)?;
190 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
191 #[cfg(feature = "cython-compat")]
192 re_export_module_attributes(m, n)?;
193
194 let n = "databento";
195 let submodule = pyo3::wrap_pymodule!(nautilus_databento::python::databento);
196 m.add_wrapped(submodule)?;
197 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
198 #[cfg(feature = "cython-compat")]
199 re_export_module_attributes(m, n)?;
200
201 let n = "hyperliquid";
202 let submodule = pyo3::wrap_pymodule!(nautilus_hyperliquid::python::hyperliquid);
203 m.add_wrapped(submodule)?;
204 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
205 #[cfg(feature = "cython-compat")]
206 re_export_module_attributes(m, n)?;
207
208 let n = "okx";
209 let submodule = pyo3::wrap_pymodule!(nautilus_okx::python::okx);
210 m.add_wrapped(submodule)?;
211 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
212 #[cfg(feature = "cython-compat")]
213 re_export_module_attributes(m, n)?;
214
215 let n = "tardis";
216 let submodule = pyo3::wrap_pymodule!(nautilus_tardis::python::tardis);
217 m.add_wrapped(submodule)?;
218 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
219 #[cfg(feature = "cython-compat")]
220 re_export_module_attributes(m, n)?;
221
222 #[cfg(feature = "defi")]
223 {
224 let n = "blockchain";
225 let submodule = pyo3::wrap_pymodule!(nautilus_blockchain::python::blockchain);
226 m.add_wrapped(submodule)?;
227 sys_modules.set_item(format!("{module_name}.{n}"), m.getattr(n)?)?;
228 #[cfg(feature = "cython-compat")]
229 re_export_module_attributes(m, n)?;
230 }
231
232 Ok(())
233}
234
235#[cfg(feature = "cython-compat")]
236fn re_export_module_attributes(
237 parent_module: &Bound<'_, PyModule>,
238 submodule_name: &str,
239) -> PyResult<()> {
240 let submodule = parent_module.getattr(submodule_name)?;
241 for item_name in submodule.dir()? {
242 let item_name_str: &str = item_name.extract()?;
243 if let Ok(attr) = submodule.getattr(item_name_str) {
244 parent_module.add(item_name_str, attr)?;
245 }
246 }
247
248 Ok(())
249}
250
251pub fn stub_info() -> pyo3_stub_gen::Result<pyo3_stub_gen::StubInfo> {
269 let workspace_root = Path::new(env!("CARGO_MANIFEST_DIR"))
270 .parent()
271 .unwrap()
272 .parent()
273 .unwrap();
274 let pyproject_path = workspace_root.join("python").join("pyproject.toml");
275
276 pyo3_stub_gen::StubInfo::from_pyproject_toml(&pyproject_path)
277}