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}