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
18#![expect(
19    clippy::missing_errors_doc,
20    reason = "errors documented on underlying Rust methods"
21)]
22
23pub mod config;
24pub mod http;
25pub mod websocket;
26
27use std::str::FromStr;
28
29use nautilus_core::python::to_pyvalue_err;
30use pyo3::{prelude::*, types::PyType};
31
32use crate::{
33    common::enums::{AxEnvironment, AxMarketDataLevel},
34    http::client::AxHttpClient,
35    python::websocket::{PyAxMdWebSocketClient, PyAxOrdersWebSocketClient},
36};
37
38#[pymethods]
39#[pyo3_stub_gen::derive::gen_stub_pymethods]
40impl AxEnvironment {
41    fn __repr__(&self) -> String {
42        format!(
43            "<{}.{}: '{}'>",
44            stringify!(AxEnvironment),
45            self.name(),
46            self.value(),
47        )
48    }
49
50    fn __str__(&self) -> String {
51        self.to_string()
52    }
53
54    #[getter]
55    #[must_use]
56    pub fn name(&self) -> String {
57        self.to_string()
58    }
59
60    #[getter]
61    #[must_use]
62    pub fn value(&self) -> u8 {
63        *self as u8
64    }
65
66    #[classmethod]
67    #[pyo3(name = "from_str")]
68    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
69        let data_str: &str = data.extract()?;
70        let tokenized = data_str.to_uppercase();
71        Self::from_str(&tokenized).map_err(to_pyvalue_err)
72    }
73}
74
75#[pymethods]
76#[pyo3_stub_gen::derive::gen_stub_pymethods]
77impl AxMarketDataLevel {
78    fn __repr__(&self) -> String {
79        format!(
80            "<{}.{}: '{}'>",
81            stringify!(AxMarketDataLevel),
82            self.name(),
83            self.value(),
84        )
85    }
86
87    fn __str__(&self) -> String {
88        self.to_string()
89    }
90
91    #[getter]
92    #[must_use]
93    pub fn name(&self) -> String {
94        self.to_string()
95    }
96
97    #[getter]
98    #[must_use]
99    pub fn value(&self) -> u8 {
100        *self as u8
101    }
102
103    #[classmethod]
104    #[pyo3(name = "from_str")]
105    fn py_from_str(_: &Bound<'_, PyType>, data: &Bound<'_, PyAny>) -> PyResult<Self> {
106        let data_str: &str = data.extract()?;
107        let tokenized = data_str.to_uppercase();
108        Self::from_str(&tokenized).map_err(to_pyvalue_err)
109    }
110}
111
112/// Loaded as `nautilus_pyo3.architect`.
113///
114/// # Errors
115///
116/// Returns a `PyErr` if registering any module components fails.
117#[pymodule]
118pub fn architect(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
119    m.add_class::<AxEnvironment>()?;
120    m.add_class::<AxMarketDataLevel>()?;
121    m.add_class::<crate::config::AxDataClientConfig>()?;
122    m.add_class::<crate::config::AxExecClientConfig>()?;
123    m.add_class::<AxHttpClient>()?;
124    m.add_class::<PyAxMdWebSocketClient>()?;
125    m.add_class::<PyAxOrdersWebSocketClient>()?;
126
127    Ok(())
128}