openai_interface/rest/get.rs
1//! GET request functionality for OpenAI interface
2//!
3//! This module provides HTTP GET request functionality for making requests to OpenAI-compatible APIs.
4//! Unlike POST requests, GET requests typically don't require serialization of request bodies,
5//! but may include query parameters.
6
7use std::{future::Future, str::FromStr};
8
9use serde::de::DeserializeOwned;
10
11use crate::errors::OapiError;
12
13/// Base trait for GET requests
14pub trait Get {
15 /// Returns the URL with query parameters if needed
16 ///
17 /// # Example
18 ///
19 /// ```rust
20 /// use openai_interface::rest::get::Get;
21 /// use openai_interface::errors::OapiError;
22 ///
23 /// struct MyRequest {
24 /// id: String,
25 /// limit: Option<u32>,
26 /// }
27 ///
28 /// impl Get for MyRequest {
29 /// fn build_url(&self, base_url: &str) -> Result<String, OapiError> {
30 /// let mut url = format!("{}/{}", base_url, self.id);
31 /// if let Some(limit) = self.limit {
32 /// url.push_str(&format!("?limit={}", limit));
33 /// }
34 /// Ok(url)
35 /// }
36 /// }
37 /// ```
38 fn build_url(&self, base_url: &str) -> Result<String, OapiError>;
39}
40
41/// Trait for non-streaming GET requests
42pub trait GetNoStream: Get + Sync + Send {
43 type Response: DeserializeOwned + FromStr<Err = OapiError> + Send + Sync;
44
45 /// Sends a GET request to the specified URL with the provided api-key.
46 fn get_response_string(
47 &self,
48 base_url: &str,
49 key: &str,
50 ) -> impl Future<Output = Result<String, OapiError>> + Send + Sync {
51 async move {
52 let url = self.build_url(base_url)?;
53 let client = reqwest::Client::new();
54 let response = client
55 .get(&url)
56 .headers({
57 let mut headers = reqwest::header::HeaderMap::new();
58 headers.insert("Accept", "application/json".parse().unwrap());
59 headers
60 })
61 .bearer_auth(key)
62 .send()
63 .await
64 .map_err(|e| {
65 OapiError::SendError(format!("Failed to send GET request: {:#?}", e))
66 })?;
67
68 if response.status() != reqwest::StatusCode::OK {
69 return Err(
70 crate::errors::OapiError::ResponseStatus(response.status().as_u16()).into(),
71 );
72 }
73
74 let text = response.text().await.map_err(|e| {
75 OapiError::ResponseError(format!("Failed to get response text: {:#?}", e))
76 })?;
77
78 Ok(text)
79 }
80 }
81
82 /// Sends a GET request and deserializes the response
83 fn get_response(
84 &self,
85 base_url: &str,
86 key: &str,
87 ) -> impl Future<Output = Result<Self::Response, OapiError>> + Send + Sync {
88 async move {
89 let text = self.get_response_string(base_url, key).await?;
90 let result = Self::Response::from_str(&text)?;
91 Ok(result)
92 }
93 }
94}