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, KRAKEN_CLIENT_ID, KRAKEN_VENUE},
31 enums::{KrakenEnvironment, KrakenProductType},
32 },
33 config::{KrakenDataClientConfig, KrakenExecutionClientConfig},
34 factories::{KrakenDataClientFactory, KrakenExecutionClientFactory},
35 http::{KrakenFuturesHttpClient, KrakenSpotHttpClient},
36};
37
38pub mod config;
39pub mod enums;
40pub mod factories;
41pub mod http_futures;
42pub mod http_spot;
43
44#[pyfunction]
54#[pyo3_stub_gen::derive::gen_stub_pyfunction(module = "nautilus_trader.adapters.kraken")]
55#[pyo3(name = "kraken_product_type_from_symbol")]
56fn py_kraken_product_type_from_symbol(symbol: &str) -> KrakenProductType {
57 crate::common::enums::product_type_from_symbol(symbol)
58}
59
60#[expect(clippy::needless_pass_by_value)]
61fn extract_kraken_data_factory(
62 py: Python<'_>,
63 factory: Py<PyAny>,
64) -> PyResult<Box<dyn DataClientFactory>> {
65 match factory.extract::<KrakenDataClientFactory>(py) {
66 Ok(f) => Ok(Box::new(f)),
67 Err(e) => Err(to_pyvalue_err(format!(
68 "Failed to extract KrakenDataClientFactory: {e}"
69 ))),
70 }
71}
72
73#[expect(clippy::needless_pass_by_value)]
74fn extract_kraken_exec_factory(
75 py: Python<'_>,
76 factory: Py<PyAny>,
77) -> PyResult<Box<dyn ExecutionClientFactory>> {
78 match factory.extract::<KrakenExecutionClientFactory>(py) {
79 Ok(f) => Ok(Box::new(f)),
80 Err(e) => Err(to_pyvalue_err(format!(
81 "Failed to extract KrakenExecutionClientFactory: {e}"
82 ))),
83 }
84}
85
86#[expect(clippy::needless_pass_by_value)]
87fn extract_kraken_data_config(
88 py: Python<'_>,
89 config: Py<PyAny>,
90) -> PyResult<Box<dyn ClientConfig>> {
91 match config.extract::<KrakenDataClientConfig>(py) {
92 Ok(c) => Ok(Box::new(c)),
93 Err(e) => Err(to_pyvalue_err(format!(
94 "Failed to extract KrakenDataClientConfig: {e}"
95 ))),
96 }
97}
98
99#[expect(clippy::needless_pass_by_value)]
100fn extract_kraken_exec_config(
101 py: Python<'_>,
102 config: Py<PyAny>,
103) -> PyResult<Box<dyn ClientConfig>> {
104 match config.extract::<KrakenExecutionClientConfig>(py) {
105 Ok(c) => Ok(Box::new(c)),
106 Err(e) => Err(to_pyvalue_err(format!(
107 "Failed to extract KrakenExecutionClientConfig: {e}"
108 ))),
109 }
110}
111
112#[pymodule]
113pub fn kraken(m: &Bound<'_, PyModule>) -> PyResult<()> {
114 m.add(stringify!(KRAKEN), KRAKEN)?;
115 m.add(stringify!(KRAKEN_CLIENT_ID), *KRAKEN_CLIENT_ID)?;
116 m.add(stringify!(KRAKEN_VENUE), *KRAKEN_VENUE)?;
117 m.add_class::<KrakenEnvironment>()?;
118 m.add_class::<KrakenProductType>()?;
119 m.add_class::<KrakenSpotHttpClient>()?;
120 m.add_class::<KrakenFuturesHttpClient>()?;
121 m.add_class::<KrakenDataClientConfig>()?;
122 m.add_class::<KrakenDataClientFactory>()?;
123 m.add_class::<KrakenExecutionClientConfig>()?;
124 m.add_class::<KrakenExecutionClientFactory>()?;
125 m.add_function(wrap_pyfunction!(py_kraken_product_type_from_symbol, m)?)?;
126
127 let registry = get_global_pyo3_registry();
128
129 if let Err(e) =
130 registry.register_factory_extractor(KRAKEN.to_string(), extract_kraken_data_factory)
131 {
132 return Err(to_pyruntime_err(format!(
133 "Failed to register Kraken data factory extractor: {e}"
134 )));
135 }
136
137 if let Err(e) =
138 registry.register_exec_factory_extractor(KRAKEN.to_string(), extract_kraken_exec_factory)
139 {
140 return Err(to_pyruntime_err(format!(
141 "Failed to register Kraken exec factory extractor: {e}"
142 )));
143 }
144
145 if let Err(e) = registry.register_config_extractor(
146 "KrakenDataClientConfig".to_string(),
147 extract_kraken_data_config,
148 ) {
149 return Err(to_pyruntime_err(format!(
150 "Failed to register Kraken data config extractor: {e}"
151 )));
152 }
153
154 if let Err(e) = registry.register_config_extractor(
155 "KrakenExecutionClientConfig".to_string(),
156 extract_kraken_exec_config,
157 ) {
158 return Err(to_pyruntime_err(format!(
159 "Failed to register Kraken exec config extractor: {e}"
160 )));
161 }
162
163 Ok(())
164}