pulse_client/lib.rs
1//! Official Rust client for [StreamFlow Pulse](https://github.com/olsisoft/streamflow)
2//! — the AI Agent Platform.
3//!
4//! # Quick start
5//!
6//! ```no_run
7//! use pulse_client::PulseClient;
8//!
9//! #[tokio::main]
10//! async fn main() -> Result<(), pulse_client::PulseError> {
11//! let client = PulseClient::builder()
12//! .base_url("http://localhost:9090")
13//! .build()?;
14//!
15//! client.auth().login("alice", "secret").await?;
16//!
17//! for pipeline in client.pipelines().list().await? {
18//! println!("{}", pipeline["name"]);
19//! }
20//! Ok(())
21//! }
22//! ```
23//!
24//! # Surface
25//!
26//! Mirrors the Python (`pulse-py`), JavaScript (`@olsisoft/pulse-client`),
27//! Java (`com.streamflow:pulse-client`) and Go (`github.com/olsisoft/pulse-go`)
28//! SDKs 1:1:
29//!
30//! - [`auth()`](PulseClient::auth) — login, refresh, organisations, switch org
31//! - [`pipelines()`](PulseClient::pipelines) — list, get, create, delete
32//! - [`agents()`](PulseClient::agents) — list, get
33//! - [`templates()`](PulseClient::templates) — list
34//! - [`users()`](PulseClient::users) — list (admin only)
35//! - [`events()`](PulseClient::events) — Server-Sent Events stream
36//! - [`iq()`](PulseClient::iq) — B-106 Interactive Queries on agent state
37//! - [`streams()`](PulseClient::streams) — B-107 Kafka-Streams-like DSL
38//! - [`version()`](PulseClient::version) — public, no JWT required
39//!
40//! # Wire format
41//!
42//! Every method corresponds 1:1 to an endpoint in the Pulse OpenAPI 3.1 spec
43//! (`streamflow-pulse/src/main/resources/openapi/openapi.yaml`). Drift caught
44//! at PR time by the in-tree spec invariant tests (B-103).
45
46#![doc(html_root_url = "https://docs.rs/pulse-client/2.6.0")]
47#![warn(missing_debug_implementations)]
48#![warn(rust_2018_idioms)]
49
50mod client;
51mod error;
52mod events;
53mod iq;
54mod resources;
55mod streams;
56
57pub use client::{PulseClient, PulseClientBuilder};
58pub use error::PulseError;
59pub use events::{EventsResource, EventsStream};
60pub use iq::{iq_and, iq_leaf, iq_not, iq_or, IQQueryOptions, IQResource, IQScanOptions};
61pub use resources::{
62 AgentsResource, AuthResource, PipelinesResource, TemplatesResource, UsersResource,
63};
64pub use streams::{
65 aggs, windows, BranchSpec, BroadcastJoinOptions, CdcJoinOptions, CepOptions,
66 EnrichAsyncOptions, MapOptions, StreamBuilder, StreamsResource, WindowOptions, WindowSpec,
67};
68
69// Re-export serde_json::Value so callers don't need to add serde_json to
70// their direct dependencies just to inspect responses.
71pub use serde_json::Value;
72
73/// Current SDK version (matches `Cargo.toml` and the Pulse server it targets).
74pub const VERSION: &str = "2.6.0";
75
76impl std::fmt::Debug for PulseClient {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 f.debug_struct("PulseClient")
79 .field("base_url", &self.inner.base_url)
80 .field("token", &self.token().map(|_| "<set>"))
81 .finish()
82 }
83}
84
85impl<'c> std::fmt::Debug for AuthResource<'c> {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 f.debug_struct("AuthResource").finish()
88 }
89}
90
91impl<'c> std::fmt::Debug for PipelinesResource<'c> {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 f.debug_struct("PipelinesResource").finish()
94 }
95}
96
97impl<'c> std::fmt::Debug for AgentsResource<'c> {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 f.debug_struct("AgentsResource").finish()
100 }
101}
102
103impl<'c> std::fmt::Debug for TemplatesResource<'c> {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.debug_struct("TemplatesResource").finish()
106 }
107}
108
109impl<'c> std::fmt::Debug for UsersResource<'c> {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 f.debug_struct("UsersResource").finish()
112 }
113}