nautilus_architect_ax/python/
config.rs1use nautilus_core::string::secret::SecretString;
17use nautilus_model::identifiers::AccountId;
18use nautilus_network::websocket::TransportBackend;
19use pyo3::pymethods;
20
21use crate::{
22 common::enums::AxEnvironment,
23 config::{AxDataClientConfig, AxExecutionClientConfig},
24};
25
26#[pymethods]
27#[pyo3_stub_gen::derive::gen_stub_pymethods]
28impl AxDataClientConfig {
29 #[new]
31 #[expect(clippy::too_many_arguments)]
32 #[pyo3(signature = (api_key=None, api_secret=None, environment=None, base_url_http=None, base_url_ws_public=None, base_url_ws_private=None, proxy_url=None, http_timeout_secs=None, max_retries=None, retry_delay_initial_ms=None, retry_delay_max_ms=None, heartbeat_interval_secs=None, recv_window_ms=None, update_instruments_interval_mins=None, funding_rate_poll_interval_mins=None, transport_backend=None, book_snapshot_timeout_secs=None))]
33 fn py_new(
34 api_key: Option<String>,
35 api_secret: Option<String>,
36 environment: Option<AxEnvironment>,
37 base_url_http: Option<String>,
38 base_url_ws_public: Option<String>,
39 base_url_ws_private: Option<String>,
40 proxy_url: Option<String>,
41 http_timeout_secs: Option<u64>,
42 max_retries: Option<u32>,
43 retry_delay_initial_ms: Option<u64>,
44 retry_delay_max_ms: Option<u64>,
45 heartbeat_interval_secs: Option<u64>,
46 recv_window_ms: Option<u64>,
47 update_instruments_interval_mins: Option<u64>,
48 funding_rate_poll_interval_mins: Option<u64>,
49 transport_backend: Option<TransportBackend>,
50 book_snapshot_timeout_secs: Option<u64>,
51 ) -> Self {
52 let default = Self::default();
53 Self {
54 api_key: api_key.map(SecretString::from),
55 api_secret: api_secret.map(SecretString::from),
56 environment: environment.unwrap_or(default.environment),
57 base_url_http,
58 base_url_ws_public,
59 base_url_ws_private,
60 proxy_url: proxy_url.map(SecretString::from),
61 http_timeout_secs: http_timeout_secs.unwrap_or(default.http_timeout_secs),
62 max_retries: max_retries.unwrap_or(default.max_retries),
63 retry_delay_initial_ms: retry_delay_initial_ms
64 .unwrap_or(default.retry_delay_initial_ms),
65 retry_delay_max_ms: retry_delay_max_ms.unwrap_or(default.retry_delay_max_ms),
66 heartbeat_interval_secs: heartbeat_interval_secs
67 .unwrap_or(default.heartbeat_interval_secs),
68 recv_window_ms: recv_window_ms.unwrap_or(default.recv_window_ms),
69 update_instruments_interval_mins: update_instruments_interval_mins
70 .unwrap_or(default.update_instruments_interval_mins),
71 funding_rate_poll_interval_mins: funding_rate_poll_interval_mins
72 .unwrap_or(default.funding_rate_poll_interval_mins),
73 book_snapshot_timeout_secs: book_snapshot_timeout_secs
74 .unwrap_or(default.book_snapshot_timeout_secs),
75 transport_backend: transport_backend.unwrap_or(default.transport_backend),
76 }
77 }
78
79 #[getter]
80 const fn has_proxy_url(&self) -> bool {
81 self.proxy_url.is_some()
82 }
83
84 fn __repr__(&self) -> String {
85 stringify!(AxDataClientConfig).to_string()
86 }
87
88 fn __str__(&self) -> String {
89 stringify!(AxDataClientConfig).to_string()
90 }
91}
92
93#[pymethods]
94#[pyo3_stub_gen::derive::gen_stub_pymethods]
95impl AxExecutionClientConfig {
96 #[new]
98 #[expect(clippy::too_many_arguments)]
99 #[pyo3(signature = (account_id=None, api_key=None, api_secret=None, environment=None, base_url_http=None, base_url_orders=None, base_url_ws_private=None, proxy_url=None, http_timeout_secs=None, max_retries=None, retry_delay_initial_ms=None, retry_delay_max_ms=None, heartbeat_interval_secs=None, recv_window_ms=None, cancel_on_disconnect=None, transport_backend=None))]
100 fn py_new(
101 account_id: Option<AccountId>,
102 api_key: Option<String>,
103 api_secret: Option<String>,
104 environment: Option<AxEnvironment>,
105 base_url_http: Option<String>,
106 base_url_orders: Option<String>,
107 base_url_ws_private: Option<String>,
108 proxy_url: Option<String>,
109 http_timeout_secs: Option<u64>,
110 max_retries: Option<u32>,
111 retry_delay_initial_ms: Option<u64>,
112 retry_delay_max_ms: Option<u64>,
113 heartbeat_interval_secs: Option<u64>,
114 recv_window_ms: Option<u64>,
115 cancel_on_disconnect: Option<bool>,
116 transport_backend: Option<TransportBackend>,
117 ) -> Self {
118 let default = Self::default();
119 Self {
120 account_id: account_id.unwrap_or(default.account_id),
121 api_key: api_key.map(SecretString::from),
122 api_secret: api_secret.map(SecretString::from),
123 environment: environment.unwrap_or(default.environment),
124 base_url_http,
125 base_url_orders,
126 base_url_ws_private,
127 proxy_url: proxy_url.map(SecretString::from),
128 http_timeout_secs: http_timeout_secs.unwrap_or(default.http_timeout_secs),
129 max_retries: max_retries.unwrap_or(default.max_retries),
130 retry_delay_initial_ms: retry_delay_initial_ms
131 .unwrap_or(default.retry_delay_initial_ms),
132 retry_delay_max_ms: retry_delay_max_ms.unwrap_or(default.retry_delay_max_ms),
133 heartbeat_interval_secs: heartbeat_interval_secs
134 .unwrap_or(default.heartbeat_interval_secs),
135 recv_window_ms: recv_window_ms.unwrap_or(default.recv_window_ms),
136 cancel_on_disconnect: cancel_on_disconnect.unwrap_or(default.cancel_on_disconnect),
137 transport_backend: transport_backend.unwrap_or(default.transport_backend),
138 }
139 }
140
141 #[getter]
142 const fn has_proxy_url(&self) -> bool {
143 self.proxy_url.is_some()
144 }
145
146 fn __repr__(&self) -> String {
147 stringify!(AxExecutionClientConfig).to_string()
148 }
149
150 fn __str__(&self) -> String {
151 stringify!(AxExecutionClientConfig).to_string()
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use rstest::rstest;
158
159 use super::*;
160
161 #[rstest]
162 #[case::default(None, 10)]
163 #[case::override_value(Some(42), 42)]
164 fn test_data_config_py_new_book_snapshot_timeout(
165 #[case] book_snapshot_timeout_secs: Option<u64>,
166 #[case] expected: u64,
167 ) {
168 let config = AxDataClientConfig::py_new(
169 None,
170 None,
171 None,
172 None,
173 None,
174 None,
175 None,
176 None,
177 None,
178 None,
179 None,
180 None,
181 None,
182 None,
183 Some(7),
184 None,
185 book_snapshot_timeout_secs,
186 );
187
188 assert_eq!(config.funding_rate_poll_interval_mins, 7);
189 assert_eq!(config.book_snapshot_timeout_secs, expected);
190 }
191}