nautilus_kraken/python/
mod.rs1#![expect(
19 clippy::missing_errors_doc,
20 reason = "errors documented on underlying Rust methods"
21)]
22
23use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
24use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
25use nautilus_system::get_global_pyo3_registry;
26use pyo3::prelude::*;
27
28use crate::{
29 common::{
30 consts::KRAKEN,
31 enums::{KrakenEnvironment, KrakenProductType},
32 },
33 config::{KrakenDataClientConfig, KrakenExecClientConfig},
34 factories::{KrakenDataClientFactory, KrakenExecutionClientFactory},
35 http::{KrakenFuturesHttpClient, KrakenSpotHttpClient},
36 websocket::{
37 futures::client::KrakenFuturesWebSocketClient, spot_v2::client::KrakenSpotWebSocketClient,
38 },
39};
40
41pub mod config;
42pub mod enums;
43pub mod factories;
44pub mod http_futures;
45pub mod http_spot;
46pub mod websocket_futures;
47pub mod websocket_spot;
48
49#[pyfunction]
59#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.kraken")]
60#[pyo3(name = "kraken_product_type_from_symbol")]
61fn py_kraken_product_type_from_symbol(symbol: &str) -> KrakenProductType {
62 crate::common::enums::product_type_from_symbol(symbol)
63}
64
65#[expect(clippy::needless_pass_by_value)]
66fn extract_kraken_data_factory(
67 py: Python<'_>,
68 factory: Py<PyAny>,
69) -> PyResult<Box<dyn DataClientFactory>> {
70 match factory.extract::<KrakenDataClientFactory>(py) {
71 Ok(f) => Ok(Box::new(f)),
72 Err(e) => Err(to_pyvalue_err(format!(
73 "Failed to extract KrakenDataClientFactory: {e}"
74 ))),
75 }
76}
77
78#[expect(clippy::needless_pass_by_value)]
79fn extract_kraken_exec_factory(
80 py: Python<'_>,
81 factory: Py<PyAny>,
82) -> PyResult<Box<dyn ExecutionClientFactory>> {
83 match factory.extract::<KrakenExecutionClientFactory>(py) {
84 Ok(f) => Ok(Box::new(f)),
85 Err(e) => Err(to_pyvalue_err(format!(
86 "Failed to extract KrakenExecutionClientFactory: {e}"
87 ))),
88 }
89}
90
91#[expect(clippy::needless_pass_by_value)]
92fn extract_kraken_data_config(
93 py: Python<'_>,
94 config: Py<PyAny>,
95) -> PyResult<Box<dyn ClientConfig>> {
96 match config.extract::<KrakenDataClientConfig>(py) {
97 Ok(c) => Ok(Box::new(c)),
98 Err(e) => Err(to_pyvalue_err(format!(
99 "Failed to extract KrakenDataClientConfig: {e}"
100 ))),
101 }
102}
103
104#[expect(clippy::needless_pass_by_value)]
105fn extract_kraken_exec_config(
106 py: Python<'_>,
107 config: Py<PyAny>,
108) -> PyResult<Box<dyn ClientConfig>> {
109 match config.extract::<KrakenExecClientConfig>(py) {
110 Ok(c) => Ok(Box::new(c)),
111 Err(e) => Err(to_pyvalue_err(format!(
112 "Failed to extract KrakenExecClientConfig: {e}"
113 ))),
114 }
115}
116
117#[pymodule]
118pub fn kraken(m: &Bound<'_, PyModule>) -> PyResult<()> {
119 m.add_class::<KrakenEnvironment>()?;
120 m.add_class::<KrakenProductType>()?;
121 m.add_class::<KrakenSpotHttpClient>()?;
122 m.add_class::<KrakenFuturesHttpClient>()?;
123 m.add_class::<KrakenSpotWebSocketClient>()?;
124 m.add_class::<KrakenFuturesWebSocketClient>()?;
125 m.add_class::<KrakenDataClientConfig>()?;
126 m.add_class::<KrakenExecClientConfig>()?;
127 m.add_class::<KrakenDataClientFactory>()?;
128 m.add_class::<KrakenExecutionClientFactory>()?;
129 m.add_function(wrap_pyfunction!(py_kraken_product_type_from_symbol, m)?)?;
130
131 let registry = get_global_pyo3_registry();
132
133 if let Err(e) =
134 registry.register_factory_extractor(KRAKEN.to_string(), extract_kraken_data_factory)
135 {
136 return Err(to_pyruntime_err(format!(
137 "Failed to register Kraken data factory extractor: {e}"
138 )));
139 }
140
141 if let Err(e) =
142 registry.register_exec_factory_extractor(KRAKEN.to_string(), extract_kraken_exec_factory)
143 {
144 return Err(to_pyruntime_err(format!(
145 "Failed to register Kraken exec factory extractor: {e}"
146 )));
147 }
148
149 if let Err(e) = registry.register_config_extractor(
150 "KrakenDataClientConfig".to_string(),
151 extract_kraken_data_config,
152 ) {
153 return Err(to_pyruntime_err(format!(
154 "Failed to register Kraken data config extractor: {e}"
155 )));
156 }
157
158 if let Err(e) = registry.register_config_extractor(
159 "KrakenExecClientConfig".to_string(),
160 extract_kraken_exec_config,
161 ) {
162 return Err(to_pyruntime_err(format!(
163 "Failed to register Kraken exec config extractor: {e}"
164 )));
165 }
166
167 Ok(())
168}