bezant/lib.rs
1//! # bezant
2//!
3//! Ergonomic async client for the IBKR Client Portal Web API.
4//!
5//! Bezant wraps the auto-generated [`bezant-api`] crate with the sugar you
6//! actually need to build an automated trading bot:
7//!
8//! - [`Client`] — a thin wrapper around the Gateway with saner TLS defaults
9//! (self-signed certs, timeout, user-agent, session cookies).
10//! - [`Client::spawn_keepalive`] — a drop-to-stop background task that
11//! tickles `/tickle` so the 5-minute CPAPI session never expires.
12//! - [`Client::health`] — one call that returns [`Error::NotAuthenticated`]
13//! or [`Error::NoSession`] instead of an opaque HTTP status.
14//!
15//! For raw access to every one of the ~154 CPAPI endpoints, use the
16//! underlying [`bezant-api`] crate directly. The two are fully interoperable
17//! — [`Client::api`] hands you the generated client.
18//!
19//! ## Quickstart
20//!
21//! ```no_run
22//! # async fn run() -> bezant::Result<()> {
23//! use std::time::Duration;
24//!
25//! let client = bezant::Client::new("https://localhost:5000/v1/api")?;
26//! let _keepalive = client.spawn_keepalive(Duration::from_secs(60));
27//! client.health().await?; // errors early if the user hasn't logged in
28//!
29//! // drop into the generated client for real work:
30//! let _ = client
31//! .api()
32//! .get_all_accounts(bezant::api::GetAllAccountsRequest::default())
33//! .await?;
34//! # Ok(())
35//! # }
36//! ```
37//!
38//! [`bezant-api`]: https://docs.rs/bezant-api
39
40#![deny(missing_docs)]
41#![warn(clippy::all)]
42#![allow(clippy::module_name_repetitions)]
43
44mod auth;
45mod client;
46mod error;
47mod helpers;
48mod jar;
49pub mod ws;
50
51pub use auth::{AuthStatus, KeepaliveHandle, TickleResponse};
52pub use client::{Client, ClientBuilder, DEFAULT_BASE_URL};
53pub use error::{Error, Result};
54pub use helpers::{
55 ContractSummary, Position, SymbolCache, MAX_POSITION_PAGES, POSITIONS_PAGE_SIZE,
56};
57pub use jar::NameKeyedJar;
58pub use ws::{MarketDataFields, Subscription, WsClient, WsMessage, WsRecv, WsSink};
59
60/// Re-export of the auto-generated API crate for callers that want raw access.
61pub use bezant_api as api;
62
63/// Re-export of [`url::Url`] so callers can name the return type of
64/// [`Client::base_url`] without adding `url` to their own `Cargo.toml`.
65pub use url::Url;
66
67/// Re-export of [`reqwest::StatusCode`] — callers using
68/// [`Client::http`] frequently need it and otherwise have to add
69/// `reqwest` to their own `Cargo.toml` just to spell the type.
70pub use reqwest::StatusCode;
71
72/// Glob-importable prelude for the typical bot use case:
73/// `Client`, `ClientBuilder`, `Result`, `Error`, `SymbolCache`,
74/// `KeepaliveHandle`. Optimised for `use bezant::prelude::*;`.
75///
76/// ```no_run
77/// use bezant::prelude::*;
78///
79/// # async fn run() -> Result<()> {
80/// let client = Client::new("https://localhost:5000/v1/api")?;
81/// let cache = SymbolCache::new(client);
82/// let aapl = cache.conid_for("AAPL").await?;
83/// println!("AAPL = {aapl}");
84/// # Ok(())
85/// # }
86/// ```
87pub mod prelude {
88 pub use crate::{
89 AuthStatus, Client, ClientBuilder, Error, KeepaliveHandle, Position, Result, SymbolCache,
90 TickleResponse,
91 };
92}