Skip to main content

nautilus_blockchain/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](https://pyo3.rs).
17
18pub mod config;
19
20#[cfg(feature = "hypersync")]
21pub mod cache;
22
23#[cfg(feature = "hypersync")]
24pub mod factories;
25
26#[cfg(feature = "hypersync")]
27use nautilus_common::factories::{ClientConfig, DataClientFactory};
28#[cfg(feature = "hypersync")]
29use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
30#[cfg(feature = "hypersync")]
31use nautilus_system::get_global_pyo3_registry;
32use pyo3::prelude::*;
33
34#[cfg(feature = "hypersync")]
35use crate::constants::BLOCKCHAIN;
36
37/// Extractor function for `BlockchainDataClientFactory`.
38#[cfg(feature = "hypersync")]
39#[expect(clippy::needless_pass_by_value)] // Must match FactoryExtractor function pointer signature
40fn extract_blockchain_factory(
41    py: Python<'_>,
42    factory: Py<PyAny>,
43) -> PyResult<Box<dyn DataClientFactory>> {
44    match factory.extract::<crate::factories::BlockchainDataClientFactory>(py) {
45        Ok(concrete_factory) => Ok(Box::new(concrete_factory)),
46        Err(e) => Err(to_pyvalue_err(format!(
47            "Failed to extract BlockchainDataClientFactory: {e}"
48        ))),
49    }
50}
51
52/// Extractor function for `BlockchainDataClientConfig`.
53#[cfg(feature = "hypersync")]
54#[expect(clippy::needless_pass_by_value)] // Must match ConfigExtractor function pointer signature
55fn extract_blockchain_config(py: Python<'_>, config: Py<PyAny>) -> PyResult<Box<dyn ClientConfig>> {
56    match config.extract::<crate::config::BlockchainDataClientConfig>(py) {
57        Ok(concrete_config) => Ok(Box::new(concrete_config)),
58        Err(e) => Err(to_pyvalue_err(format!(
59            "Failed to extract BlockchainDataClientConfig: {e}"
60        ))),
61    }
62}
63
64/// Loaded as `nautilus_pyo3.blockchain`.
65///
66/// # Errors
67///
68/// Returns a `PyErr` if registering any module components fails.
69#[pymodule]
70pub fn blockchain(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
71    m.add_class::<crate::config::BlockchainDataClientConfig>()?;
72    m.add_class::<crate::config::DexPoolFilters>()?;
73    #[cfg(feature = "hypersync")]
74    m.add_class::<crate::factories::BlockchainDataClientFactory>()?;
75    #[cfg(feature = "hypersync")]
76    m.add_function(wrap_pyfunction!(
77        crate::python::cache::py_load_pool_snapshot,
78        m
79    )?)?;
80
81    // Register extractors with the global registry
82    #[cfg(feature = "hypersync")]
83    {
84        let registry = get_global_pyo3_registry();
85
86        if let Err(e) =
87            registry.register_factory_extractor(BLOCKCHAIN.to_string(), extract_blockchain_factory)
88        {
89            return Err(to_pyruntime_err(format!(
90                "Failed to register blockchain factory extractor: {e}"
91            )));
92        }
93
94        if let Err(e) = registry.register_config_extractor(
95            "BlockchainDataClientConfig".to_string(),
96            extract_blockchain_config,
97        ) {
98            return Err(to_pyruntime_err(format!(
99                "Failed to register blockchain config extractor: {e}"
100            )));
101        }
102    }
103
104    Ok(())
105}