nautilus_derive/python/
mod.rs1pub mod config;
19pub mod factories;
20
21use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
22use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
23use nautilus_system::get_global_pyo3_registry;
24use pyo3::prelude::*;
25
26use crate::{
27 common::{
28 consts::{DERIVE, DERIVE_CLIENT_ID, DERIVE_VENUE},
29 enums::DeriveEnvironment,
30 },
31 config::{DeriveDataClientConfig, DeriveExecutionClientConfig},
32 factories::{DeriveDataClientFactory, DeriveExecutionClientFactory},
33};
34
35#[expect(clippy::needless_pass_by_value)]
36fn extract_derive_data_factory(
37 py: Python<'_>,
38 factory: Py<PyAny>,
39) -> PyResult<Box<dyn DataClientFactory>> {
40 match factory.extract::<DeriveDataClientFactory>(py) {
41 Ok(f) => Ok(Box::new(f)),
42 Err(e) => Err(to_pyvalue_err(format!(
43 "Failed to extract DeriveDataClientFactory: {e}"
44 ))),
45 }
46}
47
48#[expect(clippy::needless_pass_by_value)]
49fn extract_derive_exec_factory(
50 py: Python<'_>,
51 factory: Py<PyAny>,
52) -> PyResult<Box<dyn ExecutionClientFactory>> {
53 match factory.extract::<DeriveExecutionClientFactory>(py) {
54 Ok(f) => Ok(Box::new(f)),
55 Err(e) => Err(to_pyvalue_err(format!(
56 "Failed to extract DeriveExecutionClientFactory: {e}"
57 ))),
58 }
59}
60
61#[expect(clippy::needless_pass_by_value)]
62fn extract_derive_data_config(
63 py: Python<'_>,
64 config: Py<PyAny>,
65) -> PyResult<Box<dyn ClientConfig>> {
66 match config.extract::<DeriveDataClientConfig>(py) {
67 Ok(c) => Ok(Box::new(c)),
68 Err(e) => Err(to_pyvalue_err(format!(
69 "Failed to extract DeriveDataClientConfig: {e}"
70 ))),
71 }
72}
73
74#[expect(clippy::needless_pass_by_value)]
75fn extract_derive_exec_config(
76 py: Python<'_>,
77 config: Py<PyAny>,
78) -> PyResult<Box<dyn ClientConfig>> {
79 match config.extract::<DeriveExecutionClientConfig>(py) {
80 Ok(c) => Ok(Box::new(c)),
81 Err(e) => Err(to_pyvalue_err(format!(
82 "Failed to extract DeriveExecutionClientConfig: {e}"
83 ))),
84 }
85}
86
87#[pymodule]
93pub fn derive(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
94 m.add(stringify!(DERIVE), DERIVE)?;
95 m.add(stringify!(DERIVE_CLIENT_ID), *DERIVE_CLIENT_ID)?;
96 m.add(stringify!(DERIVE_VENUE), *DERIVE_VENUE)?;
97 m.add_class::<DeriveEnvironment>()?;
98 m.add_class::<DeriveDataClientConfig>()?;
99 m.add_class::<DeriveDataClientFactory>()?;
100 m.add_class::<DeriveExecutionClientConfig>()?;
101 m.add_class::<DeriveExecutionClientFactory>()?;
102
103 let registry = get_global_pyo3_registry();
104
105 if let Err(e) =
106 registry.register_factory_extractor(DERIVE.to_string(), extract_derive_data_factory)
107 {
108 return Err(to_pyruntime_err(format!(
109 "Failed to register Derive data factory extractor: {e}"
110 )));
111 }
112
113 if let Err(e) =
114 registry.register_exec_factory_extractor(DERIVE.to_string(), extract_derive_exec_factory)
115 {
116 return Err(to_pyruntime_err(format!(
117 "Failed to register Derive exec factory extractor: {e}"
118 )));
119 }
120
121 if let Err(e) = registry.register_config_extractor(
122 "DeriveDataClientConfig".to_string(),
123 extract_derive_data_config,
124 ) {
125 return Err(to_pyruntime_err(format!(
126 "Failed to register Derive data config extractor: {e}"
127 )));
128 }
129
130 if let Err(e) = registry.register_config_extractor(
131 "DeriveExecutionClientConfig".to_string(),
132 extract_derive_exec_config,
133 ) {
134 return Err(to_pyruntime_err(format!(
135 "Failed to register Derive exec config extractor: {e}"
136 )));
137 }
138
139 Ok(())
140}