Skip to main content

nautilus_architect_ax/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 for the Ax adapter.
17
18pub mod http;
19pub mod websocket;
20
21use std::str::FromStr;
22
23use nautilus_core::python::to_pyvalue_err;
24use pyo3::{prelude::*, types::PyType};
25
26use crate::{
27    common::enums::{AxEnvironment, AxMarketDataLevel},
28    http::client::AxHttpClient,
29    websocket::{data::AxMdWebSocketClient, orders::AxOrdersWebSocketClient},
30};
31
32#[pymethods]
33impl AxEnvironment {
34    fn __repr__(&self) -> String {
35        format!(
36            "<{}.{}: '{}'>",
37            stringify!(AxEnvironment),
38            self.name(),
39            self.value(),
40        )
41    }
42
43    fn __str__(&self) -> String {
44        self.to_string()
45    }
46
47    #[getter]
48    #[must_use]
49    pub fn name(&self) -> String {
50        self.to_string()
51    }
52
53    #[getter]
54    #[must_use]
55    pub fn value(&self) -> u8 {
56        *self as u8
57    }
58
59    #[classmethod]
60    #[pyo3(name = "from_str")]
61    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
62        let data_str: &str = data.extract()?;
63        let tokenized = data_str.to_uppercase();
64        Self::from_str(&tokenized).map_err(to_pyvalue_err)
65    }
66
67    #[classattr]
68    #[pyo3(name = "SANDBOX")]
69    const fn py_sandbox() -> Self {
70        Self::Sandbox
71    }
72
73    #[classattr]
74    #[pyo3(name = "PRODUCTION")]
75    const fn py_production() -> Self {
76        Self::Production
77    }
78}
79
80#[pymethods]
81impl AxMarketDataLevel {
82    fn __repr__(&self) -> String {
83        format!(
84            "<{}.{}: '{}'>",
85            stringify!(AxMarketDataLevel),
86            self.name(),
87            self.value(),
88        )
89    }
90
91    fn __str__(&self) -> String {
92        self.to_string()
93    }
94
95    #[getter]
96    #[must_use]
97    pub fn name(&self) -> String {
98        self.to_string()
99    }
100
101    #[getter]
102    #[must_use]
103    pub fn value(&self) -> u8 {
104        *self as u8
105    }
106
107    #[classmethod]
108    #[pyo3(name = "from_str")]
109    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
110        let data_str: &str = data.extract()?;
111        let tokenized = data_str.to_uppercase();
112        Self::from_str(&tokenized).map_err(to_pyvalue_err)
113    }
114
115    #[classattr]
116    #[pyo3(name = "LEVEL_1")]
117    const fn py_level1() -> Self {
118        Self::Level1
119    }
120
121    #[classattr]
122    #[pyo3(name = "LEVEL_2")]
123    const fn py_level2() -> Self {
124        Self::Level2
125    }
126
127    #[classattr]
128    #[pyo3(name = "LEVEL_3")]
129    const fn py_level3() -> Self {
130        Self::Level3
131    }
132}
133
134/// Loaded as `nautilus_pyo3.architect`.
135///
136/// # Errors
137///
138/// Returns a `PyErr` if registering any module components fails.
139#[pymodule]
140pub fn architect(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
141    m.add_class::<AxEnvironment>()?;
142    m.add_class::<AxMarketDataLevel>()?;
143    m.add_class::<AxHttpClient>()?;
144    m.add_class::<AxMdWebSocketClient>()?;
145    m.add_class::<AxOrdersWebSocketClient>()?;
146
147    Ok(())
148}