Skip to main content

nautilus_deribit/python/
mod.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Python bindings from `pyo3`.
17
18pub mod config;
19pub mod enums;
20pub mod factories;
21pub mod http;
22pub mod urls;
23pub mod websocket;
24
25use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
26use nautilus_system::{
27    factories::{ClientConfig, DataClientFactory, ExecutionClientFactory},
28    get_global_pyo3_registry,
29};
30use pyo3::prelude::*;
31
32use crate::{
33    config::{DeribitDataClientConfig, DeribitExecClientConfig},
34    factories::{DeribitDataClientFactory, DeribitExecutionClientFactory},
35};
36
37fn extract_deribit_data_factory(
38    py: Python<'_>,
39    factory: Py<PyAny>,
40) -> PyResult<Box<dyn DataClientFactory>> {
41    match factory.extract::<DeribitDataClientFactory>(py) {
42        Ok(f) => Ok(Box::new(f)),
43        Err(e) => Err(to_pyvalue_err(format!(
44            "Failed to extract DeribitDataClientFactory: {e}"
45        ))),
46    }
47}
48
49fn extract_deribit_exec_factory(
50    py: Python<'_>,
51    factory: Py<PyAny>,
52) -> PyResult<Box<dyn ExecutionClientFactory>> {
53    match factory.extract::<DeribitExecutionClientFactory>(py) {
54        Ok(f) => Ok(Box::new(f)),
55        Err(e) => Err(to_pyvalue_err(format!(
56            "Failed to extract DeribitExecutionClientFactory: {e}"
57        ))),
58    }
59}
60
61fn extract_deribit_data_config(
62    py: Python<'_>,
63    config: Py<PyAny>,
64) -> PyResult<Box<dyn ClientConfig>> {
65    match config.extract::<DeribitDataClientConfig>(py) {
66        Ok(c) => Ok(Box::new(c)),
67        Err(e) => Err(to_pyvalue_err(format!(
68            "Failed to extract DeribitDataClientConfig: {e}"
69        ))),
70    }
71}
72
73fn extract_deribit_exec_config(
74    py: Python<'_>,
75    config: Py<PyAny>,
76) -> PyResult<Box<dyn ClientConfig>> {
77    match config.extract::<DeribitExecClientConfig>(py) {
78        Ok(c) => Ok(Box::new(c)),
79        Err(e) => Err(to_pyvalue_err(format!(
80            "Failed to extract DeribitExecClientConfig: {e}"
81        ))),
82    }
83}
84
85/// Loaded as `nautilus_pyo3.deribit`.
86///
87/// # Errors
88///
89/// Returns an error if any bindings fail to register with the Python module.
90#[pymodule]
91pub fn deribit(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
92    m.add_class::<super::http::client::DeribitHttpClient>()?;
93    m.add_class::<super::websocket::client::DeribitWebSocketClient>()?;
94    m.add_class::<crate::common::enums::DeribitCurrency>()?;
95    m.add_class::<crate::common::enums::DeribitProductType>()?;
96    m.add_class::<crate::websocket::enums::DeribitUpdateInterval>()?;
97    m.add_class::<DeribitDataClientConfig>()?;
98    m.add_class::<DeribitExecClientConfig>()?;
99    m.add_class::<DeribitDataClientFactory>()?;
100    m.add_class::<DeribitExecutionClientFactory>()?;
101    m.add_function(wrap_pyfunction!(urls::py_get_deribit_http_base_url, m)?)?;
102    m.add_function(wrap_pyfunction!(urls::py_get_deribit_ws_url, m)?)?;
103
104    let registry = get_global_pyo3_registry();
105
106    if let Err(e) =
107        registry.register_factory_extractor("DERIBIT".to_string(), extract_deribit_data_factory)
108    {
109        return Err(to_pyruntime_err(format!(
110            "Failed to register Deribit data factory extractor: {e}"
111        )));
112    }
113
114    if let Err(e) = registry
115        .register_exec_factory_extractor("DERIBIT".to_string(), extract_deribit_exec_factory)
116    {
117        return Err(to_pyruntime_err(format!(
118            "Failed to register Deribit exec factory extractor: {e}"
119        )));
120    }
121
122    if let Err(e) = registry.register_config_extractor(
123        "DeribitDataClientConfig".to_string(),
124        extract_deribit_data_config,
125    ) {
126        return Err(to_pyruntime_err(format!(
127            "Failed to register Deribit data config extractor: {e}"
128        )));
129    }
130
131    if let Err(e) = registry.register_config_extractor(
132        "DeribitExecClientConfig".to_string(),
133        extract_deribit_exec_config,
134    ) {
135        return Err(to_pyruntime_err(format!(
136            "Failed to register Deribit exec config extractor: {e}"
137        )));
138    }
139
140    Ok(())
141}