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