use derive_more::*;
use crate::{Chat, ChatResponse, Completion, CompletionResponse};
#[derive(Debug, Clone, From, Into, FromStr, Display)]
pub struct ApiKey(String);
#[derive(Debug, Clone)]
pub struct Client {
base_url: String,
client: reqwest::Client,
}
impl Client {
pub fn new(api_key: ApiKey) -> Self {
Self {
base_url: "https://api.openai.com/v1".into(),
client: reqwest::Client::builder()
.default_headers(
[
(
reqwest::header::AUTHORIZATION,
reqwest::header::HeaderValue::from_str(
&format!("Bearer {}", api_key)[..],
)
.unwrap(),
),
(
reqwest::header::CONTENT_TYPE,
reqwest::header::HeaderValue::from_static("application/json"),
),
]
.into_iter()
.collect(),
)
.build()
.unwrap(),
}
}
pub async fn do_completion(
&self,
completion: &Completion,
) -> anyhow::Result<CompletionResponse> {
debug!(
"Sending completion request: {}",
serde_json::to_string_pretty(completion)?
);
let body = self
.client
.post(format!("{}/completions", self.base_url))
.json(completion)
.send()
.await?
.text()
.await?;
debug!("Received: {}", body);
Ok(serde_json::from_str(&body)?)
}
pub async fn do_chat(&self, chat: &Chat) -> anyhow::Result<ChatResponse> {
debug!(
"Sending chat request: {}",
serde_json::to_string_pretty(chat)?
);
let body = self
.client
.post(format!("{}/chat/completions", self.base_url))
.json(chat)
.send()
.await?
.text()
.await?;
debug!("Received: {}", body);
Ok(serde_json::from_str(&body)?)
}
}