Skip to main content

nautilus_polymarket/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
18#![expect(
19    clippy::missing_errors_doc,
20    reason = "errors documented on underlying Rust methods"
21)]
22
23pub mod config;
24pub mod factories;
25
26use nautilus_common::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
27use nautilus_core::python::{to_pyruntime_err, to_pyvalue_err};
28use nautilus_system::get_global_pyo3_registry;
29use pyo3::prelude::*;
30
31use crate::{
32    config::{PolymarketDataClientConfig, PolymarketExecClientConfig},
33    factories::{PolymarketDataClientFactory, PolymarketExecutionClientFactory},
34};
35
36#[expect(clippy::needless_pass_by_value)]
37fn extract_polymarket_data_factory(
38    py: Python<'_>,
39    factory: Py<PyAny>,
40) -> PyResult<Box<dyn DataClientFactory>> {
41    match factory.extract::<PolymarketDataClientFactory>(py) {
42        Ok(f) => Ok(Box::new(f)),
43        Err(e) => Err(to_pyvalue_err(format!(
44            "Failed to extract PolymarketDataClientFactory: {e}"
45        ))),
46    }
47}
48
49#[expect(clippy::needless_pass_by_value)]
50fn extract_polymarket_exec_factory(
51    py: Python<'_>,
52    factory: Py<PyAny>,
53) -> PyResult<Box<dyn ExecutionClientFactory>> {
54    match factory.extract::<PolymarketExecutionClientFactory>(py) {
55        Ok(f) => Ok(Box::new(f)),
56        Err(e) => Err(to_pyvalue_err(format!(
57            "Failed to extract PolymarketExecutionClientFactory: {e}"
58        ))),
59    }
60}
61
62#[expect(clippy::needless_pass_by_value)]
63fn extract_polymarket_data_config(
64    py: Python<'_>,
65    config: Py<PyAny>,
66) -> PyResult<Box<dyn ClientConfig>> {
67    match config.extract::<PolymarketDataClientConfig>(py) {
68        Ok(c) => Ok(Box::new(c)),
69        Err(e) => Err(to_pyvalue_err(format!(
70            "Failed to extract PolymarketDataClientConfig: {e}"
71        ))),
72    }
73}
74
75#[expect(clippy::needless_pass_by_value)]
76fn extract_polymarket_exec_config(
77    py: Python<'_>,
78    config: Py<PyAny>,
79) -> PyResult<Box<dyn ClientConfig>> {
80    match config.extract::<PolymarketExecClientConfig>(py) {
81        Ok(c) => Ok(Box::new(c)),
82        Err(e) => Err(to_pyvalue_err(format!(
83            "Failed to extract PolymarketExecClientConfig: {e}"
84        ))),
85    }
86}
87
88/// Loaded as `nautilus_pyo3.polymarket`.
89#[pymodule]
90pub fn polymarket(_: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
91    m.add_class::<crate::common::enums::SignatureType>()?;
92    m.add_class::<PolymarketDataClientConfig>()?;
93    m.add_class::<PolymarketExecClientConfig>()?;
94    m.add_class::<PolymarketDataClientFactory>()?;
95    m.add_class::<PolymarketExecutionClientFactory>()?;
96
97    let registry = get_global_pyo3_registry();
98
99    if let Err(e) = registry
100        .register_factory_extractor("POLYMARKET".to_string(), extract_polymarket_data_factory)
101    {
102        return Err(to_pyruntime_err(format!(
103            "Failed to register Polymarket data factory extractor: {e}"
104        )));
105    }
106
107    if let Err(e) = registry
108        .register_exec_factory_extractor("POLYMARKET".to_string(), extract_polymarket_exec_factory)
109    {
110        return Err(to_pyruntime_err(format!(
111            "Failed to register Polymarket exec factory extractor: {e}"
112        )));
113    }
114
115    if let Err(e) = registry.register_config_extractor(
116        "PolymarketDataClientConfig".to_string(),
117        extract_polymarket_data_config,
118    ) {
119        return Err(to_pyruntime_err(format!(
120            "Failed to register Polymarket data config extractor: {e}"
121        )));
122    }
123
124    if let Err(e) = registry.register_config_extractor(
125        "PolymarketExecClientConfig".to_string(),
126        extract_polymarket_exec_config,
127    ) {
128        return Err(to_pyruntime_err(format!(
129            "Failed to register Polymarket exec config extractor: {e}"
130        )));
131    }
132
133    Ok(())
134}