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    ///
22    /// struct MyRequest {
23    ///     id: String,
24    ///     limit: Option<u32>,
25    /// }
26    ///
27    /// impl Get for MyRequest {
28    ///     fn build_url(&self, base_url: &str) -> String {
29    ///         let mut url = format!("{}/{}", base_url, self.id);
30    ///         if let Some(limit) = self.limit {
31    ///             url.push_str(&format!("?limit={}", limit));
32    ///         }
33    ///         url
34    ///     }
35    /// }
36    /// ```
37    fn build_url(&self, base_url: &str) -> String;
38}
39
40/// Trait for non-streaming GET requests
41pub trait GetNoStream: Get + Sync + Send {
42    type Response: DeserializeOwned + FromStr<Err = OapiError> + Send + Sync;
43
44    /// Sends a GET request to the specified URL with the provided api-key.
45    fn get_response_string(
46        &self,
47        base_url: &str,
48        key: &str,
49    ) -> impl Future<Output = Result<String, OapiError>> + Send + Sync {
50        async move {
51            let url = self.build_url(base_url);
52            let client = reqwest::Client::new();
53            let response = client
54                .get(&url)
55                .headers({
56                    let mut headers = reqwest::header::HeaderMap::new();
57                    headers.insert("Accept", "application/json".parse().unwrap());
58                    headers
59                })
60                .bearer_auth(key)
61                .send()
62                .await
63                .map_err(|e| {
64                    OapiError::SendError(format!("Failed to send GET request: {:#?}", e))
65                })?;
66
67            if response.status() != reqwest::StatusCode::OK {
68                return Err(
69                    crate::errors::OapiError::ResponseStatus(response.status().as_u16()).into(),
70                );
71            }
72
73            let text = response.text().await.map_err(|e| {
74                OapiError::ResponseError(format!("Failed to get response text: {:#?}", e))
75            })?;
76
77            Ok(text)
78        }
79    }
80
81    /// Sends a GET request and deserializes the response
82    fn get_response(
83        &self,
84        base_url: &str,
85        key: &str,
86    ) -> impl Future<Output = Result<Self::Response, OapiError>> + Send + Sync {
87        async move {
88            let text = self.get_response_string(base_url, key).await?;
89            let result = Self::Response::from_str(&text)?;
90            Ok(result)
91        }
92    }
93}