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}