use futures_core::Stream;
use reqwest::RequestBuilder;
use crate::messages::{
MessageChunk, MessagesError, MessagesRequestBody, MessagesResponseBody,
StreamError,
};
use crate::{ApiKey, Beta, Version};
#[derive(Clone)]
pub struct Client {
api_key: ApiKey,
version: Version,
client: reqwest::Client,
beta: Option<Beta>,
}
impl Client {
pub fn from_env() -> Result<Self, std::env::VarError> {
let api_key = ApiKey::from_env()?;
let version = Version::default();
let client = reqwest::Client::new();
Ok(Self {
api_key,
version,
client,
beta: None,
})
}
pub fn from_api_key(api_key: ApiKey) -> Self {
let version = Version::default();
let client = reqwest::Client::new();
Self {
api_key,
version,
client,
beta: None,
}
}
pub(crate) fn post(
&self,
endpoint: &str,
) -> RequestBuilder {
let mut builder = self
.client
.post(endpoint)
.header("x-api-key", self.api_key.value())
.header(
"anthropic-version",
self.version.to_string(),
);
if let Some(beta) = self.beta {
builder = builder.header("anthropic-beta", beta.to_string());
}
builder
}
}
impl Client {
pub async fn create_a_message(
&self,
request_body: MessagesRequestBody,
) -> Result<MessagesResponseBody, MessagesError> {
crate::messages::api::create_a_message(self, request_body).await
}
pub async fn create_a_message_stream(
&self,
request_body: MessagesRequestBody,
) -> Result<
impl Stream<Item = Result<MessageChunk, StreamError>>,
MessagesError,
> {
crate::messages::api::create_a_message_stream(self, request_body).await
}
}
#[derive(Clone)]
pub struct ClientBuilder {
api_key: ApiKey,
version: Option<Version>,
client: Option<reqwest::Client>,
beta: Option<Beta>,
}
impl ClientBuilder {
pub fn new(api_key: ApiKey) -> Self {
Self {
api_key,
version: None,
client: None,
beta: None,
}
}
pub fn from_env() -> Result<Self, std::env::VarError> {
let api_key = ApiKey::from_env()?;
Ok(Self::new(api_key))
}
pub fn version(
mut self,
version: Version,
) -> Self {
self.version = Some(version);
self
}
pub fn client(
mut self,
client: reqwest::Client,
) -> Self {
self.client = Some(client);
self
}
pub fn beta(
mut self,
beta: Beta,
) -> Self {
self.beta = Some(beta);
self
}
pub fn build(self) -> Client {
let version = self
.version
.unwrap_or_default();
let client = self
.client
.unwrap_or_default();
Client {
api_key: self.api_key,
version,
client,
beta: self.beta,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builder() {
let client = ClientBuilder::new(ApiKey::new("api-key")).build();
assert_eq!(client.api_key.value(), "api-key");
assert_eq!(client.version, Version::default());
let client = ClientBuilder::new(ApiKey::new("api-key"))
.version(Version::V2023_01_01)
.build();
assert_eq!(client.api_key.value(), "api-key");
assert_eq!(client.version, Version::V2023_01_01);
let client = ClientBuilder::new(ApiKey::new("api-key"))
.client(
reqwest::ClientBuilder::new()
.timeout(std::time::Duration::from_secs(10))
.build()
.unwrap(),
)
.build();
assert_eq!(client.api_key.value(), "api-key");
assert_eq!(client.version, Version::default());
let client = ClientBuilder::new(ApiKey::new("api-key"))
.beta(Beta::Tools2024_04_04)
.build();
assert_eq!(client.api_key.value(), "api-key");
assert_eq!(client.beta, Some(Beta::Tools2024_04_04));
}
}